Created
June 11, 2014 09:24
-
-
Save jupemara/396baac4a83b53c24fc5 to your computer and use it in GitHub Desktop.
Send nginx stub_status to zabbix server by using zabbix_sender protocol. This scripts is compatible with Python2.6.x.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python | |
# -*- coding: utf-8 -*- | |
""" | |
Fetch nginx stub status. | |
""" | |
import optparse | |
import subprocess | |
import urllib2 | |
import zabbix_sender | |
# default variables | |
DEFAULT = { | |
'nginx_schema': 'http', | |
'nginx_host': '127.0.0.1', | |
'nginx_port': 80, | |
'nginx_stub_uri': 'nginx_status', | |
'nginx_binary_path': '/usr/sbin/nginx', | |
'zabbix_server_host': '127.0.0.1', | |
'zabbix_server_port': 10051, | |
'zabbix_hostname': None | |
} | |
def get_args(): | |
""" | |
parse arguments | |
""" | |
usage = 'Send nginx stub_status to zabbix server.' | |
parser = optparse.OptionParser(usage=usage) | |
parser.add_option( | |
'--nginx-host', '-N', | |
type='string', | |
default=DEFAULT['nginx_host'], | |
help='Nginx host.', | |
dest='nginx_host' | |
) | |
parser.add_option( | |
'--nginx-port', '-P', | |
type='int', | |
default=DEFAULT['nginx_port'], | |
help='Nginx port number.', | |
dest='nginx_port' | |
) | |
parser.add_option( | |
'--nginx-schema', '-S', | |
type='string', | |
default=DEFAULT['nginx_schema'], | |
help='Nginx stub_status schema. e.g: https, http.', | |
dest='nginx_schema' | |
) | |
parser.add_option( | |
'--nginx-stub-uri', '-U', | |
type='string', | |
default=DEFAULT['nginx_stub_uri'], | |
help='Nginx stub status uri.', | |
dest='nginx_stub_uri' | |
) | |
parser.add_option( | |
'--nginx-binary-path', '-B', | |
type='string', | |
default=DEFAULT['nginx_binary_path'], | |
help='Nginx binary absolute path.', | |
dest='nginx_binary_path' | |
) | |
parser.add_option( | |
'--zabbix-server-host', '-Z', | |
type='string', | |
default=DEFAULT['zabbix_server_host'], | |
help='Zabbix server host.', | |
dest='zabbix_server_host' | |
) | |
parser.add_option( | |
'--zabbix-server-port', '-p', | |
type='int', | |
default=DEFAULT['zabbix_server_port'], | |
help='Zabbix server port number.', | |
dest='zabbix_server_port' | |
) | |
parser.add_option( | |
'--zabbix-hostname', '-z', | |
type='string', | |
default=DEFAULT['zabbix_hostname'], | |
help='Zabbix host item name.', | |
dest='zabbix_hostname' | |
) | |
return parser.parse_args()[0] | |
def fetch_stub_status(host, stub_status_uri, schema='http', port=80): | |
""" | |
`stub_status` is below format. | |
Active connections : N | |
server accepts handled requests | |
N N N | |
Reading: N Writing: N Waiting: N | |
This scripts returns Json Object. | |
{ | |
"nginx.KEYNAME": VALUE | |
} | |
Notes: `cps` is `connection per seconds`. | |
""" | |
results = dict() | |
stub_url = ( | |
'{schema}://{host}:{port}/{uri}' | |
''.format( | |
schema=schema, | |
host=host, | |
port=port, | |
uri=stub_status_uri | |
) | |
) | |
request = urllib2.Request(stub_url) | |
raw_response = urllib2.urlopen(request) | |
response = raw_response.readlines() | |
# Active connections | |
active_connections = response[0].split(':')[1].strip() | |
results['nginx.stat[active_connections]'] = active_connections | |
# server accespts handled requests | |
keys = response[1].split()[1:] | |
values = response[2].split() | |
for key, value in zip(keys, values): | |
results['nginx.stat[{0}]'.format(key)] = value | |
results['nginx.stat[{0}.cps]'.format(key)] = value | |
# Reading: N Writing: N Waiting: N | |
keys = response[3].split()[0::2] | |
keys = [entry.strip(':').lower() for entry in keys] | |
values = response[3].split()[1::2] | |
for key, value in zip(keys, values): | |
results['nginx.stat[{0}]'.format(key)] = value | |
return results | |
def get_version(path='nginx'): | |
""" | |
Get nginx version | |
""" | |
try: | |
raw_result = subprocess.Popen( | |
[path, '-v'], | |
stderr=subprocess.PIPE | |
).communicate()[1] | |
return raw_result.split('/')[1] | |
except: | |
return None | |
if __name__ == '__main__': | |
OPTIONS = get_args() | |
if OPTIONS.zabbix_hostname is None: | |
raise ValueError( | |
'You must set "--zabbix-hostname" option.' | |
) | |
STUB_STATUS = fetch_stub_status( | |
host=OPTIONS.nginx_host, | |
stub_status_uri=OPTIONS.nginx_stub_uri | |
) | |
ZABBIX = zabbix_sender.ZabbixSender( | |
server_address=OPTIONS.zabbix_server_host, | |
server_port=OPTIONS.zabbix_server_port | |
) | |
for key, value in STUB_STATUS.items(): | |
ZABBIX.add(key=key, value=value, hostname=OPTIONS.zabbix_hostname) | |
ZABBIX.send() | |
NGINX_VERSION = get_version(OPTIONS.nginx_binary_path) | |
if NGINX_VERSION is not None: | |
print(NGINX_VERSION) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python | |
# -*- coding: utf-8 -*- | |
import datetime | |
import json | |
import socket | |
import struct | |
import time | |
class ZabbixSender(object): | |
def __init__(self, server_address, server_port=10051): | |
self.server_address = socket.gethostbyname(server_address) | |
self.server_port = server_port | |
self.hostname = None | |
self.body = dict() | |
self.body['request'] = 'sender data' | |
self.body['data'] = list() | |
unix_timestamp = time.mktime(datetime.datetime.now().utctimetuple()) | |
self.timestamp = int(unix_timestamp) | |
self.result = None | |
def set_hostname(self, hostname): | |
self.hostname = hostname | |
def add(self, key, value, hostname=None, timestamp=None): | |
item = dict() | |
item['key'] = key | |
item['value'] = value | |
if hostname is not None: | |
item['host'] = hostname | |
elif self.hostname is not None: | |
item['host'] = self.hostname | |
else: | |
raise ValueError('"hostname" has not been set nor supplied.') | |
if timestamp is not None: | |
item['clock'] = timestamp | |
else: | |
item['clock'] = self.timestamp | |
self.body['data'].append(item) | |
def send(self): | |
request = json.dumps(self.body, ensure_ascii=False).encode('utf-8') | |
fmt = '<4sBQ' + str(len(request)) + 's' | |
data = struct.pack(fmt, 'ZBXD', 1, len(request), request) | |
sock = socket.create_connection( | |
(self.server_address, self.server_port) | |
) | |
writer = sock.makefile('wb') | |
writer.write(data) | |
writer.close() | |
reader = sock.makefile('rb') | |
response = reader.read() | |
reader.close() | |
sock.close() | |
fmt = '<4sBQ' + str(len(response) - struct.calcsize('<4sBQ')) + 's' | |
self.result = struct.unpack(fmt, response) | |
def get_result(self): | |
return json.loads(self.result[3]) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment