Zabbix协议分析

概述

Zabbix使用一种自定义的基于TCP的协议与客户端进行通信

Zabbix <- TCP -> Zabbix agent

协议内容

<HEADER> - "ZBXD\x01" (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>\n

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 = 'ZBXD\x01' + 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

posted @ 2016-11-25 01:09  metasequoia  阅读(2634)  评论(0编辑  收藏  举报