zabbix_utils lets you send item values to a trapper item on Zabbix server or proxy (similarly to Zabbix sender).
You can send a single value, multiple values, or even target multiple Zabbix clusters.
Data can be sent in synchronous or asynchronous mode:
The examples on this page focus on synchronous mode, though asynchronous mode follows similar patterns. Additional examples are available in the zabbix_utils GitHub repository.
To use zabbix_utils for sending item values, import the Sender class in your script:
For sending multiple values, you may also import the ItemValue class:
To send an item value:
Sender instance, specifying the IP address and port of your Zabbix server or proxy.send_value() method on the Sender instance using the following format:For example, to send 1 to the service.status trapper item on the Linux server host:
sender = Sender(server='127.0.0.1', port=10051)
response = sender.send_value('Linux server', 'service.status', 1)If the server running your script has multiple IP addresses, you can specify a source_ip for the Sender to use when sending values to Zabbix server or proxy:
You can set a response timeout for the Sender to control how long your script should wait for a response from Zabbix server or proxy before giving up:
You can let zabbix_utils read the Server or ServerActive parameters from a local Zabbix agent or agent 2 configuration file. In such cases, you don't need to specify connection parameters when creating a Sender instance:
If ServerActive contains one or more Zabbix clusters with multiple server instances, Sender sends data to the first available server in each cluster. If ServerActive is not set, the address from Server with the default port (10051) is used.
The Sender does not include built-in encryption support, but you can provide it by creating a wrapper using third-party libraries:
def psk_wrapper(sock, tls):
# ...
# Implementation of TLS PSK wrapper for the socket
# ...
sender = Sender(
server='127.0.0.1',
port=10051,
socket_wrapper=psk_wrapper
)The response returned by Zabbix server or proxy is processed by the library and returned as a TrapperResponse object:
print(response)
# {"processed": 1, "failed": 0, "total": 1, "time": "0.000123", "chunk": 1}
print(response.processed)
# 1
print(response.failed)
# 0
print(response.total)
# 1Asynchronous mode lets your Python script send values without waiting for a response from Zabbix server or proxy. This can make your script more efficient when it needs to send many values or when some values take a long time send.
When using asynchronous mode, there are a few important differences compared to synchronous mode:
asyncio module (you must first install the required dependencies).AsyncSender instead of Sender.async function.await when calling the send_value() method.For example, to send a single value using asynchronous mode:
# 1. Import asyncio for asynchronous mode, and AsyncSender from zabbix_utils:
import asyncio
from zabbix_utils import AsyncSender
# 2. Define the main async function where all data sending operations (must await) will be executed:
async def main():
sender = AsyncSender(server='127.0.0.1', port=10051)
response = await sender.send_value('Linux server', 'service.status', 1)
# 3. Print the response returned by Zabbix server or proxy:
print(response)
# 4. Run the async main() function using asyncio's event loop:
asyncio.run(main())To send multiple values:
ItemValue objects, each using the same format as the send_value() method.Sender instance, specifying the IP address and port of your Zabbix server or proxy.send() method (instead of send_value()) on the Sender instance, specifying the array of objects with values to send.For example, to send five values to different hosts:
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)If you need to send more values than a trapper item can accept in a single request, you can split them into chunks.
By default, the chunk size is 250 values. You can change it by setting the chunk_size parameter when creating a Sender instance.
For example, to send five values in three chunks (2-2-1), set the chunk_size parameter to 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)To send values to multiple Zabbix clusters:
Sender, specifying your array of Zabbix clusters.send_value() method on the Sender instance using the same format as the send_value() method.For example, to send send a value to the first available node in each 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)By default, Sender returns an aggregated result of sending values across all hosts or clusters:
If you need more detailed information, you can inspect the results for each cluster and each chunk using the response.details attribute:
print(response)
# {"processed": 2, "failed": 0, "total": 2, "time": "0.000108", "chunk": 2}
if response.failed == 0:
print(f"Value sent successfully 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"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