Skip to content

Instantly share code, notes, and snippets.

@jupemara
Created June 11, 2014 09:24
Show Gist options
  • Save jupemara/396baac4a83b53c24fc5 to your computer and use it in GitHub Desktop.
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.
#!/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)
#!/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