#!/usr/bin/python # -*- coding:utf-8 -*- ############################################################################### # filename : check_wowza_edge.py # contact : emrah.com@gmail.com # # This is a Nagios plugin. It checks the Wowza edge server status via the Wowza # load balancer server. # # Dependencies: # python-lxml python-ipaddr # # Usage: # check_wowza_edge.py -h # # Nagios usage: # command_line /path/to/check_wowza_edge.py -H '$HOSTADDRESS$' -e '$ARG1$' # -w '$ARG2$' -c '$ARG3$' ############################################################################### import sys import urllib2 import ipaddr import argparse from lxml import etree # Load balancer's XML info page. STATUS_PAGE = '/loadbalancer?serverInfoXML' # Debug mode. DEBUG = False #------------------------------------------------------------------------------ def argument_parser(): '''Parse the parameters.''' try: # Parse parameters. parser = argparse.ArgumentParser() parser.add_argument('-H', '--hostname', required=True, help='Load balancer\'s host name or IP Address') parser.add_argument('-p', '--port', type=int, default=1935, help='Load balancer\'s port number (default: 1935)') parser.add_argument('-e', '--edge', required=True, help='Edge\'s host name or IP Address') parser.add_argument('-w', '--warning', type=int, default=500, help='The connection count in warning status (default: 500)') parser.add_argument('-c', '--critical', type=int, default=750, help='The connection count in critical status (default: 750)') parser.add_argument('-t', '--timeout', type=int, default=10, help='The connection timeout (default: 10)') result = parser.parse_args() except Exception: if DEBUG: raise result = None return result #------------------------------------------------------------------------------ def argument_validator(args): '''Validate the parameters.''' try: # Validate parameters. if (not ipaddr.IPAddress(args.hostname)): raise NameError('Invalid IP address for the load balancer') elif (not ipaddr.IPAddress(args.edge)): raise NameError('Invalid IP address for the edge') elif (not args.port > 0 or not args.port < 65536): raise NameError('Invalid port number for the load balancer') elif (not args.warning > 0): raise NameError('Invalid connection count for the warning status') elif (not args.critical > 0): raise NameError('Invalid connection count for the critical status') elif (not (args.warning < args.critical)): raise NameError('The connection count for the warning status ' + 'must be smaller than the connection count for ' + 'the critical status') elif (not args.timeout > 0): raise NameError('Invalid connection timeout') result = args except Exception: if DEBUG: raise result = None return result # ----------------------------------------------------------------------------- def get_edge_info(loadbalancer_ip, loadbalancer_port, edge_ip, timeout): ''' Get the Wowza edge server info via the Wowza load balancer. ''' try: # Get XML info page's content. url = 'http://%s:%s/%s' % (loadbalancer_ip, loadbalancer_port, STATUS_PAGE) req = urllib2.urlopen(url, timeout=timeout) res = etree.parse(req) req.close() # Find node for the given edge server. for app in res.xpath('LoadBalancerServer'): if (app.findtext('redirect') != edge_ip): continue # Get the info for the given edge server. edge = {} edge['status'] = app.findtext('status') edge['connect_count'] = long(app.findtext('connectCount')) edge['last_message'] = app.findtext('lastMessage') edge['server_id'] = app.findtext('serverId') edge['redirect'] = app.findtext('redirect') edge['redirect_count'] = long(app.findtext('redirectCount')) break result = edge except Exception: if DEBUG: raise result = None return result # ----------------------------------------------------------------------------- def get_nagios_status(args, edge): ''' Get the Nagios plugin's return variables. It returns (code, message) pair. ''' try: if edge['status'] == 'RUNNING': if (edge['connect_count'] > args.critical): code = 2 status = 'CRITICAL' elif (edge['connect_count'] > args.warning): code = 1 status = 'WARNING' else: code = 0 status = 'OK' else: code = 2 status = 'CRITICAL' message = '%s - %s, %s connections, %s redirects, %s ago.\n' \ % (status, edge['status'], edge['connect_count'], edge['redirect_count'], edge['last_message']) result = {'code' : code, 'message' : message} except Exception: if DEBUG: raise result = None return result # ----------------------------------------------------------------------------- # Program main. # ----------------------------------------------------------------------------- if __name__ == '__main__': try: # Get parameters. args = argument_parser() if args is None: raise NameError('Invalid parameters') # Validate parameters. args = argument_validator(args) if args is None: raise NameError('Could not validate the parameters') # Get the edge server info. edge = get_edge_info(args.hostname, args.port, args.edge, args.timeout) if edge is None: raise NameError('Could not get the edge server info') # Get the Nagios plugin's status for this edge server. nagios = get_nagios_status(args, edge) if nagios is None: raise NameError('Could not get the Nagios plugin\'s status') except Exception, err: if DEBUG: raise nagios = {'code' : 3, 'message' : 'UNKNOWN - %s\n' % (str(err))} sys.stdout.write(nagios.get('message', 'UNKNOWN')) sys.exit(nagios.get('code', 3))