forked from pistolero/zbxsend
-
Notifications
You must be signed in to change notification settings - Fork 0
/
zbxsend.py
89 lines (77 loc) · 2.81 KB
/
zbxsend.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
import struct
import time
import socket
import logging
try:
import json
except:
import simplejson as json
class Metric(object):
def __init__(self, host, key, value, clock=None):
self.host = host
self.key = key
self.value = value
self.clock = clock
def __repr__(self):
if self.clock is None:
return 'Metric(%r, %r, %r)' % (self.host, self.key, self.value)
return 'Metric(%r, %r, %r, %r)' % (self.host, self.key, self.value, self.clock)
def send_to_zabbix(metrics, zabbix_host='127.0.0.1', zabbix_port=10051, timeout=15):
"""Send set of metrics to Zabbix server."""
j = json.dumps
# Zabbix has very fragile JSON parser, and we cannot use json to dump whole packet
metrics_data = []
for m in metrics:
clock = m.clock or time.time()
metrics_data.append(('\t\t{\n'
'\t\t\t"host":%s,\n'
'\t\t\t"key":%s,\n'
'\t\t\t"value":%s,\n'
'\t\t\t"clock":%s}') % (j(m.host), j(m.key), j(m.value), clock))
json_data = ('{\n'
'\t"request":"sender data",\n'
'\t"data":[\n%s]\n'
'}') % (',\n'.join(metrics_data))
data_len = struct.pack('<Q', len(json_data))
packet = 'ZBXD\1' + data_len + json_data
try:
zabbix = socket.socket()
zabbix.connect((zabbix_host, zabbix_port))
zabbix.settimeout(timeout)
# send metrics to zabbix
zabbix.sendall(packet)
# get response header from zabbix
resp_hdr = _recv_all(zabbix, 13)
if not resp_hdr.startswith('ZBXD\1') or len(resp_hdr) != 13:
logger.error('Wrong zabbix response')
return False
resp_body_len = struct.unpack('<Q', resp_hdr[5:])[0]
# get response body from zabbix
resp_body = zabbix.recv(resp_body_len)
resp = json.loads(resp_body)
logger.debug('Got response from Zabbix: %s' % resp)
logger.info(resp.get('info'))
if resp.get('response') != 'success':
logger.error('Got error from Zabbix: %s', resp)
return False
return True
except socket.timeout as e:
logger.error("zabbix timeout: " + str(e))
return False
except Exception as e:
logger.exception('Error while sending data to Zabbix: ' + str(e))
return False
finally:
zabbix.close()
logger = logging.getLogger('zbxsender')
def _recv_all(sock, count):
buf = ''
while len(buf)<count:
chunk = sock.recv(count-len(buf))
if not chunk:
return buf
buf += chunk
return buf
if __name__ == '__main__':
logging.basicConfig(level=logging.DEBUG)
send_to_zabbix([Metric('localhost', 'bucks_earned', 99999)], 'localhost', 10051)