概述
Zabbix使用一种自定义的基于TCP的协议与客户端进行通信
Zabbix <- TCP -> Zabbix agent
协议内容
<HEADER> - "ZBXDx01" (5 bytes) <DATALEN> - data length (8 bytes). 1 will be formatted as 01/00/00/00/00/00/00/00 (eight bytes in HEX, 64 bit number)
<DATA>
<DATA>: json格式,内容又分为主动检查和被动检查
为了避免Zabbix内存耗尽,Zabbix限制每个连接最多使用128M内存
被动检查
Server request
<item key>
Agent response
<HEADER><DATALEN><DATA>[0<ERROR>]
[]是可选的仅在不支持的items时发送
主动检查
(1)获取相关items的列表
Agent request
<HEADER><DATALEN>{ "request":"active checks", "host":"<hostname>" }
Server response
<HEADER><DATALEN>{ "response":"success", "data":[ { "key":"agent.version", "delay":600, "lastlogsize":0, "mtime":0 }, { "key":"vfs.fs.size[/nono]", "delay":600, "lastlogsize":0, "mtime":0 } ] }
(2)发送收集的数据
Agent send
<HEADER><DATALEN>{ "request":"agent data", "data":[ { "host":"<hostname>", "key":"agent.version", "value":"2.4.0", "clock":1400675595, "ns":76808644 }, { "host":"<hostname>", "key":"vfs.fs.size[/nono]", "state":1, "value":"Cannot obtain filesystem information: [2] No such file or directory", "clock":1400675595, "ns":78154128 } ], "clock": 1400675595, "ns": 78211329 }
Server response
<HEADER><DATALEN>{ "response":"success", "info":"processed: 2; failed: 0; total: 2; seconds spent: 0.003534" }
Zabbix Trapper发生在主动检查的第二个步骤,Agent发送数据到Server(zabbix_sender),Trapper items必须事先定义好
python模拟的zabbix_sender
#!/usr/bin/python #-*- coding:utf8 -*- __author__ = 'pdd' __date__ = '2016/11/28' ''' script simulate zabbix_sender ''' import sys import json import time import struct import socket import argparse parser = argparse.ArgumentParser(description='script simulate zabbix_sender') parser.add_argument('-z','--server',dest='server',action='store',help='Zabbix server ip') parser.add_argument('-p','--port',dest='port',action='store',help='Zabbix server port',default=10051,type=int) parser.add_argument('-s','--host',dest='host',action='store') parser.add_argument('-k','--key',dest='key',action='store',help='item key') parser.add_argument('-o','--value',dest='value',action='store',help='item value') args = parser.parse_args() class Metric(object): def __init__(self, host, key, value): self.host = host self.key = key self.value = value def __repr__(self): result = 'Metric(%r, %r, %r)' % (self.host, self.key, self.value) return result def send_to_zabbix(): j = json.dumps m = Metric(args.host, args.key, args.value) clock = ('%d' % time.time()) metrics = '{"host":%s,"key":%s,"value":%s,"clock":%s}' % (j(m.host), j(m.key), j(m.value), j(clock)) json_data = '{"request":"sender data","data":[%s]}' % metrics data_len = struct.pack('<Q', len(json_data)) packet = 'ZBXDx01' + data_len + json_data try: zabbix = socket.socket() zabbix.connect((args.server, args.port)) zabbix.sendall(packet) resp_hdr = zabbix.recv(13) resp_body_len = struct.unpack('<Q', resp_hdr[5:])[0] resp_body = zabbix.recv(resp_body_len) zabbix.close() resp = json.loads(resp_body) print(resp) except: print('Error while sending data to Zabbix') if __name__=='__main__': send_to_zabbix()
运行
参考:
https://www.zabbix.com/documentation/3.0/manual/appendix/items/activepassive
https://www.zabbix.org/wiki/Docs/protocols/zabbix_sender/2.0