Enviar dades al servidor o proxy Zabbix

zabbix_utils us permet enviar valors d'elements a un element trapper al servidor o proxy Zabbix (de manera similar a Zabbix sender).

Podeu enviar un sol valor, diversos valors o fins i tot dirigir-vos a diversos clústers Zabbix.

Les dades es poden enviar en mode síncron o asíncron:

  • En mode síncron, el vostre script de Python envia valors i espera una resposta abans de continuar; això és adequat per a operacions senzilles, seqüencials i predictibles.

  • En mode asíncron, el script envia valors sense esperar cada resposta, permetent que altres operacions continuïn en paral·lel; això és més eficient per a peticions lentes o grans lots de dades.

Els exemples d'aquesta pàgina se centren en el mode síncron, tot i que mode asíncron segueix patrons similars. Hi ha exemples addicionals disponibles al repositori de GitHub zabbix_utils.

Importar

Per utilitzar zabbix_utils per enviar valors d'element, importa la classe Sender de l'script:

from zabbix_utils import Sender

Per a l'enviament de diversos valors, també podeu importar la classe ItemValue:

from zabbix_utils import Sender, ItemValue

Enviar un únic valor

Per enviar un valor d'element:

  1. Creeu una instància Remitent, especificant l'adreça IP i el port del vostre servidor o proxy de Zabbix.
  2. Crideu el mètode send_value() a la instància Sender utilitzant el següent format:
sender_instance.send_value('host', 'item.key', 'value', optional_timestamp, opcional_nanoseconds)

Per exemple, per enviar 1 a l'element service.status trapper a l'equip Servidor Linux:

sender = Sender(server='127.0.0.1', port=10051)
response = sender.send_value('Linux server', 'service.status', 1)
Emprant adreces IP que no són per defecte IP

Si el servidor que executa l'script té diverses adreces IP, podeu especificar un source_ip perquè el remetent s'empri en enviar valors al servidor o proxy de Zabbix:

sender = Sender(
    server='127.0.0.1',
    port=10051,
    source_ip='10.10.7.1'
)
Ús de temps d'espera

Podeu establir una resposta temps d'espera per al Remitent per controlar quant de temps ha d'esperar el vostre script per a una resposta del servidor o proxy de Zabbix abans de renunciar:

sender = Sender(
    server='127.0.0.1',
    port=10051,
    timeout=30
)
Ús del fitxer de configuració de l'agent

Podeu deixar que zabbix_utils llegeixi els paràmetres Server o [ServerActive]/manual/appendix/config/zabbix_agentd#serveractive) des d'un fitxer de configuració local de Zabbix o agent 2. En aquests casos, no cal especificar els paràmetres de connexió quan creeu una instància Remitent:

sender= Sender(
    use_config=True,
    config_path='/etc/zabbix/zabbix_agent2.conf'
)

::: nota important Si ServerActive conté un o més clústers de Zabbix amb múltiples instàncies de servidor, Sender envia dades al primer servidor disponible a cada clúster. Si ServerActive no és pas establert, s'empra l'adreça de Server amb el port per defecte (10051). ::

Ús del xifrat

El Sender no inclou compatibilitat amb el xifrat integrat, però podeu proporcionar-la creant un contenidor utilitzant biblioteques de tercers:

Implementació del contenidor TLS PSK per al sòcol

def psk_wrapper(sock, tls):
    # ...
    # Implementació del contenidor TLS PSK per al socket
    # ...

sender= Sender(
    server='127.0.0.1',
    port=10051,
    socket_wrapper=psk_wrapper
)
Resposta per a un valor únic

La resposta retornada pel servidor o proxy de Zabbix és processada per la biblioteca i retornada com a objecte TrapperResponse:

print(response)
# {"processat": 1, "fallit": 0, "total": 1, "temps": "0.000123", "chunk": 1}

print(response.processed)
# 1

print(response.failed)
# 0

print(response.total)
# 1
Mode asíncron

El mode asíncron permet que el vostre script Python enviï valors sense esperar una resposta del servidor o del proxy de Zabbix. Això pot fer que el vostre script sigui més eficient quan necessita enviar molts valors o quan alguns valors triguen molt a enviar-los.

Quan s'empra el mode asíncron, hi ha algunes diferències importants en comparació amb el mode síncron:

  • Importar el mòdul asyncio de Python (primer heu de instal·lar les dependències requerides).
  • Importació AsyncSender en lloc de Sender.
  • Escriu el teu codi dins d'una funció async.
  • Utilitzeu await quan crideu el mètode send_value().

Per exemple, per enviar un únic valor utilitzant el mode asíncron:

# 1. Importa asyncio per al mode asíncron, i AsyncSender de zabbix_utils:
import asyncio
de zabbix_utils importació AsyncSender

# 2. Definir la funció principal async on s'executaran totes les operacions d'enviament de dades (s'ha d'esperar):
async def main():
    sender = AsyncSender(server='127.0.0.1', port=10051)
    response = espera el servidor sender.send_value('Linux', 'service.status', 1)

    # 3. Imprimeix la resposta retornada pel servidor Zabbix o proxy:
    print(response)

# 4. Executeu la funció async main() utilitzant el bucle d'esdeveniments d'asyncio:
asyncio.run(main()))
Envia diversos valors

Per enviar diversos valors:

  1. Prepareu una matriu d'objectes ItemValue, cadascun utilitzant el mateix format que el mètode send_value().
  2. Creeu una instància Remitent, especificant l'adreça IP i el port del vostre servidor o proxy de Zabbix.
  3. Crida el mètode send() (en lloc de send_value()) a la instància Sender, especificant l'array d'objectes amb valors a enviar.

Per exemple, per enviar cinc valors a diferents equips:

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(servidor='127.0.0.1', port=10051)
response = sender.send(elements)
Ús de la mida del tros personalitzat

Si necessiteu enviar més valors que un element de caçador pot acceptar en una sola petició, podeu dividir-los en trossos.

Per defecte, la mida del tros és de 250 valors. Podeu canviar-lo establint el paràmetre chunk_size quan creeu una instància Sender.

Per exemple, per enviar cinc valors en tres trossos (2-2-1), establiu el paràmetre chunk_size a 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(servidor='127.0.0.1', port=10051, chunk_size=2)
response = sender.send(elements)
Envia valors a múltiples clústers de Zabbix

Per enviar valors a diversos clústers de Zabbix:

  1. Prepareu una sèrie de clústers de Zabbix. Si un clúster té múltiples nodes, el valor s'enviarà al primer node disponible de cada clúster.
  2. Creeu un 'Sender', especificant la vostra matriu de clústers de Zabbix.
  3. Crida el mètode send_value() a la instància Sender utilitzant el mateix format que el mètode send_value().

Per exemple, per enviar un valor al primer node disponible en cada clúster:

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)
Resposta per a múltiples valors

Per defecte, Sender retorna un resultat agregat de l'enviament de valors a tots els equips o clústers:

print(response)
# {"processed": 2, "failed": 0, "total": 2, "time": "0.000108", "chunk": 2}

Si necessiteu informació més detallada, podeu inspeccionar els resultats de cada clúster i de cada tros amb l'atribut response.details:

print(response)
# {"processat": 2, "fallit": 0, "total": 2, "temps": "0.000108", "chunk": 2}

if response.failed == 0:
    print(f"Valor enviat correctament en {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"Processed {resp.processed} of {resp.total} at {node.address}:{node.port}")
            # Processed 1 of 1 at 127.0.0.1:10051
            # Processed 1 of 1 at zabbix.example.local:10051