Inviare dati al server o al proxy Zabbix
zabbix_utils consente di inviare valori di item a un item trapper sul server o proxy Zabbix (in modo simile a Zabbix sender).
È possibile inviare un singolo valore, più valori o persino indirizzare più cluster Zabbix.
I dati possono essere inviati in modalità sincrona o asincrona:
- In modalità sincrona, lo script Python invia i valori e attende una risposta prima di continuare; questa modalità è adatta per operazioni semplici, sequenziali e prevedibili.
- In modalità asincrona, lo script invia i valori senza attendere ogni risposta, consentendo ad altre operazioni di procedere in parallelo; questa modalità è più efficiente per richieste lente o grandi quantità di dati.
Gli esempi in questa pagina si concentrano sulla modalità sincrona, sebbene la modalità asincrona segua schemi simili. Ulteriori esempi sono disponibili nel repository GitHub zabbix_utils.
Importazione
Per utilizzare zabbix_utils per l'invio dei valori degli item, importa la classe Sender nel tuo script:
from zabbix_utils import Sender
Per inviare più valori, puoi anche importare la classe ItemValue:
from zabbix_utils import Sender, ItemValue
Inviare un singolo valore
Per inviare un valore di un item:
- Creare un'istanza di
Sender, specificando l'indirizzo IP e la porta del server o proxy Zabbix. - Chiamare il metodo
send_value()sull'istanzaSenderutilizzando il seguente formato:
sender_instance.send_value('host', 'item.key', 'value', optional_timestamp, optional_nanoseconds)
Ad esempio, per inviare 1 al trapper item service.status del host Linux server:
sender = Sender(server='127.0.0.1', port=10051)
response = sender.send_value('Linux server', 'service.status', 1)
Utilizzo di un IP non predefinito
Se il server che esegue lo script dispone di più indirizzi IP, è possibile specificare un source_ip che Sender utilizzerà durante l'invio dei valori al server o al proxy Zabbix:
sender = Sender(
server='127.0.0.1',
port=10051,
source_ip='10.10.7.1'
)
Uso del timeout
Puoi impostare un timeout di risposta per Sender per controllare per quanto tempo il tuo script deve attendere una risposta dal server o dal proxy Zabbix prima di interrompere il tentativo:
sender = Sender(
server='127.0.0.1',
port=10051,
timeout=30
)
Utilizzo del file di configurazione dell'agent
Puoi fare in modo che zabbix_utils legga i parametri Server o ServerActive da un file di configurazione locale di Zabbix agent o agent 2.
In questi casi, non è necessario specificare i parametri di connessione quando si crea un'istanza di Sender:
sender = Sender(
use_config=True,
config_path='/etc/zabbix/zabbix_agent2.conf'
)
Se ServerActive contiene uno o più cluster Zabbix con più istanze server, Sender invia i dati al primo server disponibile in ciascun cluster.
Se ServerActive non è impostato, viene utilizzato l'indirizzo di Server con la porta predefinita (10051).
Utilizzo della crittografia
Sender non include il supporto integrato per la crittografia, ma è possibile fornirlo creando un wrapper tramite librerie di terze parti:
def psk_wrapper(sock, tls):
# ...
# Implementazione del wrapper TLS PSK per il socket
# ...
sender = Sender(
server='127.0.0.1',
port=10051,
socket_wrapper=psk_wrapper
)
Risposta per valore singolo
La risposta restituita da Zabbix server o proxy viene elaborata dalla libreria e restituita come oggetto TrapperResponse:
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
Modalità asincrona
La modalità asincrona consente al tuo script Python di inviare valori senza attendere una risposta dal server o dal proxy Zabbix. Questo può rendere lo script più efficiente quando deve inviare molti valori o quando alcuni valori richiedono molto tempo per essere inviati.
Quando si utilizza la modalità asincrona, ci sono alcune differenze importanti rispetto alla modalità sincrona:
- Importa il modulo
asynciodi Python (devi prima installare le dipendenze richieste). - Importa
AsyncSenderinvece diSender. - Scrivi il codice all'interno di una funzione
async. - Usa
awaitquando chiami il metodosend_value().
Ad esempio, per inviare un singolo valore utilizzando la modalità asincrona:
# 1. Importa asyncio per la modalità asincrona e AsyncSender da zabbix_utils:
import asyncio
from zabbix_utils import AsyncSender
# 2. Definisci la funzione async principale in cui verranno eseguite tutte le operazioni di invio dei dati (è necessario usare await):
async def main():
sender = AsyncSender(server='127.0.0.1', port=10051)
response = await sender.send_value('Linux server', 'service.status', 1)
# 3. Stampa la risposta restituita dal server o dal proxy Zabbix:
print(response)
# 4. Esegui la funzione async main() utilizzando il ciclo di eventi di asyncio:
asyncio.run(main())
Inviare più valori
Per inviare più valori:
- Preparare un array di oggetti
ItemValue, ciascuno utilizzando lo stesso formato del metodosend_value(). - Creare un'istanza di
Sender, specificando l'indirizzo IP e la porta del proprio server o proxy Zabbix. - Chiamare il metodo
send()(invece disend_value()) sull'istanzaSender, specificando l'array di oggetti con i valori da inviare.
Ad esempio, per inviare cinque valori a host diversi:
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)
Utilizzo di una dimensione personalizzata dei blocchi
Se devi inviare più valori di quanti un item trapper possa accettare in una singola richiesta, puoi suddividerli in blocchi.
Per impostazione predefinita, la dimensione del blocco è di 250 valori.
Puoi modificarla impostando il parametro chunk_size durante la creazione di un'istanza di Sender.
Ad esempio, per inviare cinque valori in tre blocchi (2-2-1), imposta il parametro chunk_size su 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)
Inviare valori a più cluster Zabbix
Per inviare valori a più cluster Zabbix:
- Preparare un array di cluster Zabbix. Se un cluster ha più nodi, il valore verrà inviato al primo nodo disponibile di ciascun cluster.
- Creare un
Sender, specificando il proprio array di cluster Zabbix. - Chiamare il metodo
send_value()sull'istanzaSenderutilizzando lo stesso formato del metodosend_value().
Ad esempio, per inviare un valore al primo nodo disponibile in ciascun cluster:
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)
Risposta per più valori
Per impostazione predefinita, Sender restituisce un risultato aggregato dell'invio dei valori tra tutti gli host o cluster:
print(response)
# {"processed": 2, "failed": 0, "total": 2, "time": "0.000108", "chunk": 2}
Se hai bisogno di informazioni più dettagliate, puoi esaminare i risultati per ciascun cluster e ciascun chunk utilizzando l'attributo response.details:
print(response)
# {"processed": 2, "failed": 0, "total": 2, "time": "0.000108", "chunk": 2}
if response.failed == 0:
print(f"Valore inviato con successo in {response.time}")
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"Elaborati {resp.processed} di {resp.total} su {node.address}:{node.port}")
# Elaborati 1 di 1 su 127.0.0.1:10051
# Elaborati 1 di 1 su zabbix.example.local:10051