从 Zabbix agent 收集数据

概述

zabbix_utils 允许您从 Zabbix agent 收集数据(类似于 Zabbix get)。

可以使用同步或异步模式收集数据:

  • 在同步模式下,您的 Python 脚本会先请求并等待数据返回,然后再继续执行,这适用于简单、顺序性强且可预测的操作。
  • 在异步模式下,脚本发出数据请求后不会等待每个响应返回,从而允许其他操作并行进行;对于响应较慢的请求或大批量数据,这种方式效率更高。

本页中的示例主要侧重于同步模式,不过异步模式也遵循类似的模式。 更多示例可在 GitHub 仓库中的 zabbix_utils 中找到。

导入

要使用 zabbix_utils 收集监控项值,请在您的 Python 脚本中导入 Getter 类:

from zabbix_utils import Getter

请求数据

要请求监控项值:

  1. 创建一个 Getter 实例,并指定您的 Zabbix agent 的 IP 地址和端口。
  2. Getter 实例上调用 get() 方法,并指定您要获取的监控项键。

例如,要请求 system.uname 监控项的数据:

agent = Getter(host='192.0.2.0', port=10050)
response = agent.get('system.uname')
使用非默认 IP

如果运行脚本的服务器有多个 IP 地址,您可以为 Getter 指定一个 source_ip,以便其在连接到 Zabbix agent 时使用:

agent = Getter(
    host='192.0.2.0',
    port=10050,
    source_ip='10.10.7.1'
)
使用超时

您可以为 Getter 设置响应 timeout,以控制脚本在放弃之前应等待 Zabbix agent 响应多长时间:

agent = Getter(
    host='192.0.2.0',
    port=10050,
    timeout=30
)
使用加密

Getter 不包含内置加密支持,但您可以通过使用第三方库创建包装器来提供此功能:

def psk_wrapper(sock, tls):
    # ...
    # 套接字的 TLS PSK 包装器实现
    # ...

agent = Getter(
    host='192.0.2.0',
    port=10050,
    socket_wrapper=psk_wrapper
)
响应

来自 Zabbix agent 的响应由库处理,并作为 AgentResponse 对象返回:

print(response)
# {
#     "error": null,
#     "raw": "Linux zabbix_server 5.15.0-3.60.5.1.el9uek.x86_64",
#     "value": "Linux zabbix_server 5.15.0-3.60.5.1.el9uek.x86_64"
# }

print(response.value)
# Linux zabbix_server 5.15.0-3.60.5.1.el9uek.x86_64

print(response.error)
# None
异步模式

异步模式允许您的脚本在不等待每个值逐个返回的情况下收集值。
当脚本需要收集大量值,或者某些值的收集耗时较长时,这可以让脚本更高效。

使用异步模式时,与同步模式相比有一些重要区别:

  • 导入 Python 的 asyncio 模块(您必须先安装所需的依赖项)。
  • 导入 AsyncGetter,而不是 Getter
  • async 函数中编写代码。
  • 调用 get() 方法时使用 await

例如,使用异步模式收集单个值:

# 1. 为异步模式导入 asyncio,以及从 zabbix_utils 导入 AsyncGetter:
import asyncio
from zabbix_utils import AsyncGetter

# 2. 定义主 async 函数,所有数据请求都将在其中执行:
async def main():
    agent = AsyncGetter(host='192.0.2.0', port=10050)

    # 3. 从 Zabbix agent 获取 system.uname 的值(必须使用 await):
    response = await agent.get('system.uname')

    # 4. 打印 Zabbix agent 返回的值:
    print(response.value)

# 5. 使用 asyncio 的事件循环运行 async main() 函数:
asyncio.run(main())