Daten an Zabbix-Server oder -Proxy senden
Mit zabbix_utils können Sie Datenpunkt-Werte an einen Trapper-Datenpunkt auf dem Zabbix-Server oder -Proxy senden (ähnlich wie mit Zabbix sender).
Sie können einen einzelnen Wert, mehrere Werte oder sogar mehrere Zabbix-Cluster als Ziel angeben.
Daten können im synchronen oder asynchronen Modus gesendet werden:
- Im synchronen Modus sendet Ihr Python-Skript Werte und wartet auf eine Antwort, bevor es fortfährt; dies eignet sich für einfache, sequenzielle und vorhersehbare Vorgänge.
- Im asynchronen Modus sendet das Skript Werte, ohne auf jede Antwort zu warten, sodass andere Vorgänge parallel fortgesetzt werden können; dies ist bei langsamen Anfragen oder großen Datenmengen effizienter.
Die Beispiele auf dieser Seite konzentrieren sich auf den synchronen Modus, obwohl der asynchrone Modus einem ähnlichen Muster folgt. Zusätzliche Beispiele sind im GitHub-Repository zabbix_utils verfügbar.
Import
Um zabbix_utils zum Senden von Datenpunkt-Werten zu verwenden, importieren Sie die Klasse Sender in Ihr Skript:
from zabbix_utils import Sender
Zum Senden mehrerer Werte können Sie auch die Klasse ItemValue importieren:
from zabbix_utils import Sender, ItemValue
Einzelnen Wert senden
So senden Sie einen Datenpunktwert:
- Erstellen Sie eine
Sender-Instanz und geben Sie dabei die IP-Adresse und den Port Ihres Zabbix-Servers oder -Proxys an. - Rufen Sie die Methode
send_value()derSender-Instanz im folgenden Format auf:
sender_instance.send_value('host', 'item.key', 'value', optional_timestamp, optional_nanoseconds)
Um beispielsweise 1 an den Trapper-Datenpunkt service.status auf dem Host Linux server zu senden:
sender = Sender(server='127.0.0.1', port=10051)
response = sender.send_value('Linux server', 'service.status', 1)
Verwendung einer nicht standardmäßigen IP
Wenn der Server, auf dem Ihr Skript ausgeführt wird, mehrere IP-Adressen hat, können Sie eine source_ip angeben, die der Sender beim Senden von Werten an den Zabbix Server oder Proxy verwenden soll:
sender = Sender(
server='127.0.0.1',
port=10051,
source_ip='10.10.7.1'
)
Timeout verwenden
Sie können für den Sender einen Antwort-timeout festlegen, um zu steuern, wie lange Ihr Skript auf eine Antwort vom Zabbix Server oder Proxy warten soll, bevor es aufgibt:
sender = Sender(
server='127.0.0.1',
port=10051,
timeout=30
)
Verwenden der Agent-Konfigurationsdatei
Sie können zabbix_utils die Parameter Server oder ServerActive aus einer lokalen Zabbix-Agent- oder Agent-2-Konfigurationsdatei lesen lassen.
In solchen Fällen müssen Sie beim Erstellen einer Sender-Instanz keine Verbindungsparameter angeben:
sender = Sender(
use_config=True,
config_path='/etc/zabbix/zabbix_agent2.conf'
)
Wenn ServerActive einen oder mehrere Zabbix-Cluster mit mehreren Server-Instanzen enthält, sendet Sender Daten an den ersten verfügbaren Server in jedem Cluster.
Wenn ServerActive nicht gesetzt ist, wird die Adresse aus Server mit dem Standard-Port (10051) verwendet.
Verwendung von Verschlüsselung
Der Sender enthält keine integrierte Unterstützung für Verschlüsselung, aber Sie können diese durch die Erstellung eines Wrappers mit Bibliotheken von Drittanbietern bereitstellen:
def psk_wrapper(sock, tls):
# ...
# Implementierung eines TLS-PSK-Wrappers für den Socket
# ...
sender = Sender(
server='127.0.0.1',
port=10051,
socket_wrapper=psk_wrapper
)
Antwort für einen einzelnen Wert
Die vom Zabbix Server oder Proxy zurückgegebene Antwort wird von der Bibliothek verarbeitet und als TrapperResponse-Objekt zurückgegeben:
print(response)
# {"processed": 1, "failed": 0, "total": 1, "time": "0.000123", "chunk": 1}
print(response.processed)
# 1
print(response.failed)
# 0
print(response.total)
# 1
Asynchroner Modus
Der asynchrone Modus ermöglicht es Ihrem Python-Skript, Werte zu senden, ohne auf eine Antwort vom Zabbix Server oder Proxy zu warten. Dadurch kann Ihr Skript effizienter werden, wenn es viele Werte senden muss oder wenn das Senden einiger Werte lange dauert.
Bei der Verwendung des asynchronen Modus gibt es im Vergleich zum synchronen Modus einige wichtige Unterschiede:
- Importieren Sie das Python-Modul
asyncio(Sie müssen zuerst die erforderlichen Abhängigkeiten installieren). - Importieren Sie
AsyncSenderanstelle vonSender. - Schreiben Sie Ihren Code innerhalb einer
async-Funktion. - Verwenden Sie
await, wenn Sie die Methodesend_value()aufrufen.
Zum Beispiel, um einen einzelnen Wert im asynchronen Modus zu senden:
# 1. Importieren Sie asyncio für den asynchronen Modus und AsyncSender aus zabbix_utils:
import asyncio
from zabbix_utils import AsyncSender
# 2. Definieren Sie die Hauptfunktion async, in der alle Datensendevorgänge (müssen await verwenden) ausgeführt werden:
async def main():
sender = AsyncSender(server='127.0.0.1', port=10051)
response = await sender.send_value('Linux server', 'service.status', 1)
# 3. Geben Sie die vom Zabbix Server oder Proxy zurückgegebene Antwort aus:
print(response)
# 4. Führen Sie die asynchrone Funktion main() mit der Ereignisschleife von asyncio aus:
asyncio.run(main())
Mehrere Werte senden
Um mehrere Werte zu senden:
- Bereiten Sie ein Array von
ItemValue-Objekten vor, wobei jedes dasselbe Format wie die Methodesend_value()verwendet. - Erstellen Sie eine
Sender-Instanz und geben Sie dabei die IP-Adresse und den Port Ihres Zabbix-Server oder -Proxy an. - Rufen Sie für die
Sender-Instanz die Methodesend()auf (anstelle vonsend_value()) und geben Sie dabei das Array von Objekten mit den zu sendenden Werten an.
Zum Beispiel, um fünf Werte an verschiedene Hosts zu senden:
items = [
ItemValue('server-de', 'service.status', 'up', 1770887205, 100),
ItemValue('server-fr', 'service.status', 'up', 1770887205, 100),
ItemValue('server-uk', 'service.status', 'up', 1770887205, 100),
ItemValue('server-nl', 'service.status', 'up', 1770887205, 100),
ItemValue('server-pl', 'service.status', 'up', 1770887205, 100),
]
sender = Sender(server='127.0.0.1', port=10051)
response = sender.send(items)
Benutzerdefinierte Chunk-Größe verwenden
Wenn Sie mehr Werte senden müssen, als ein Trapper-Datenpunkt in einer einzelnen Anfrage akzeptieren kann, können Sie diese in Chunks aufteilen.
Standardmäßig beträgt die Chunk-Größe 250 Werte.
Sie können sie ändern, indem Sie beim Erstellen einer Sender-Instanz den Parameter chunk_size festlegen.
Um beispielsweise fünf Werte in drei Chunks (2-2-1) zu senden, setzen Sie den Parameter chunk_size auf 2:
items = [
ItemValue('server-de', 'service.status', 'up'),
ItemValue('server-fr', 'service.status', 'up'),
ItemValue('server-uk', 'service.status', 'up'),
ItemValue('server-nl', 'service.status', 'up'),
ItemValue('server-pl', 'service.status', 'up'),
]
sender = Sender(server='127.0.0.1', port=10051, chunk_size=2)
response = sender.send(items)
Werte an mehrere Zabbix-Cluster senden
Um Werte an mehrere Zabbix-Cluster zu senden:
- Bereiten Sie ein Array von Zabbix-Clustern vor. Wenn ein Cluster mehrere Knoten hat, wird der Wert an den ersten verfügbaren Knoten jedes Clusters gesendet.
- Erstellen Sie einen
Senderund geben Sie dabei Ihr Array von Zabbix-Clustern an. - Rufen Sie die Methode
send_value()für dieSender-Instanz auf und verwenden Sie dabei dasselbe Format wie bei der Methodesend_value().
Zum Beispiel, um einen Wert an den ersten verfügbaren Knoten in jedem Cluster zu senden:
zabbix_clusters = [
['zabbix.cluster1.node1', 'zabbix.cluster1.node2:10051'],
['zabbix.cluster2.node1:10051', 'zabbix.cluster2.node2', 'zabbix.cluster2.node3']
]
sender = Sender(clusters=zabbix_clusters)
response = sender.send_value('Linux server', 'service.status', 1)
Antwort für mehrere Werte
Standardmäßig gibt Sender ein aggregiertes Ergebnis für das Senden von Werten über alle Hosts oder Cluster hinweg zurück:
print(response)
# {"processed": 2, "failed": 0, "total": 2, "time": "0.000108", "chunk": 2}
Wenn Sie detailliertere Informationen benötigen, können Sie die Ergebnisse für jeden Cluster und jeden Chunk über das Attribut response.details prüfen:
print(response)
# {"processed": 2, "failed": 0, "total": 2, "time": "0.000108", "chunk": 2}
if response.failed == 0:
print(f"Wert erfolgreich in {response.time} gesendet")
else:
print(response.details)
# {
# 127.0.0.1:10051: [
# {
# "processed": 1,
# "failed": 0,
# "total": 1,
# "time": "0.000051",
# "chunk": 1
# }
# ],
# zabbix.example.local:10051: [
# {
# "processed": 1,
# "failed": 0,
# "total": 1,
# "time": "0.000057",
# "chunk": 1
# }
# ]
# }
for node, chunks in response.details.items():
for resp in chunks:
print(f"{resp.processed} von {resp.total} verarbeitet bei {node.address}:{node.port}")
# 1 von 1 verarbeitet bei 127.0.0.1:10051
# 1 von 1 verarbeitet bei zabbix.example.local:10051