Created
April 6, 2012 16:00
-
-
Save yyuu/2321002 to your computer and use it in GitHub Desktop.
mon monitor plugin to test http service
This file contains hidden or 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 | |
| # | |
| # pyhttp.monitor - mon monitor plugin to test http service | |
| # | |
| from __future__ import with_statement | |
| import inspect | |
| import logging | |
| import optparse | |
| import os | |
| import re | |
| import sys | |
| import urllib2 | |
| import urlparse | |
| class InvalidResponseError(Exception): | |
| pass | |
| def urlopen(url, data=None, timeout=None): | |
| argspec = inspect.getargspec(urllib2.urlopen) | |
| if len(argspec[0]) == 2: # urllib2 prior than py2.5 doesn't have urllib2.urlopen/3 | |
| return urllib2.urlopen(url, data) | |
| else: | |
| return urllib2.urlopen(url, data, timeout) | |
| def main(args): | |
| parser = optparse.OptionParser("usage %prog [OPTIONS]", add_help_option=False) | |
| parser.add_option('-a', '--user-agent', default='mon.d/pyhttp.monitor', dest='user_agent', help='User-Agent, default to "mon.d/pyhttp.monitor"') | |
| parser.add_option('-H', '--header-expects', default=[], action='append', dest='header_expects', help='match regex in response header') | |
| parser.add_option('--help', action='help', help='show this message and exit.') | |
| parser.add_option('-m', '--expects', default=[], action='append', dest='expects', help='match regex in response body') | |
| parser.add_option('-p', '--port', type='int', default=[], action='append', dest='ports', help='TCP port to connect to (default to 80)') | |
| parser.add_option('--proto', default=[], action='append', dest='protos', help='application layer protocol to use') | |
| parser.add_option('-t', '--timeout', type='int', default=None, dest='timeout', help='timeout') | |
| parser.add_option('-u', '--url', default='/', dest='path', help='path to get, default to "/"') | |
| parser.add_option('-v', '--verbose', default=False, action='store_true', dest='verbose', help='show verbose message.') | |
| (options, args) = parser.parse_args(args) | |
| if options.verbose: | |
| logging.basicConfig(level=logging.DEBUG) | |
| protos = [ proto.lower() for proto in options.protos ] if 0 < len(options.protos) else [ 'http' ] | |
| if 0 < len(options.ports): | |
| ports = options.ports | |
| else: | |
| ports = [] | |
| if 'http' in protos: | |
| ports.append(80) | |
| if 'https' in protos: | |
| ports.append(443) | |
| f = 0 | |
| for scheme, host, port in [ (s, h, p) for s in protos for h in args[1:] for p in ports ]: | |
| url = urlparse.urlunparse((scheme, "%s:%d" % (host, port), options.path, '', '', '')) | |
| client = None | |
| try: | |
| client = urlopen(url, None, options.timeout) | |
| got = client.read() | |
| logging.debug("%s: got response body (%d bytes)" % (url, len(got))) | |
| for expects in options.expects: | |
| if re.search(expects, got, re.IGNORECASE | re.MULTILINE): | |
| logging.debug("%s: response body (%d bytes) matched to %s." % (url, len(got), repr(expects))) | |
| else: | |
| raise(InvalidResponseError("%s: response body (%d bytes) not matched to %s" % (url, len(got), repr(expects)))) | |
| for header_expects in options.header_expects: | |
| if header_expects.find('=') < 0: | |
| expected_key, expected_value = header_expects, None | |
| else: | |
| expected_key, expected_value = header_expects.split('=', 2) | |
| got_value = client.headers.getheader(expected_key, None) | |
| if got_value: | |
| logging.debug("%s: response header %s exists." % (url, repr(expected_key))) | |
| if expected_value and re.search(expected_value, got_value, re.IGNORECASE | re.MULTILINE): | |
| logging.debug("%s: response header %s (%d bytes) matched to %s." % (url, repr(expected_key), len(got_value), repr(expected_value))) | |
| else: | |
| raise(InvalidResponseError("%s: response header %s (%d bytes) not matched to %s" % (url, repr(expected_key), len(got_value), repr(expected_value)))) | |
| else: | |
| raise(InvalidResponseError("%s: response header %s does not exist" % (url, repr(expected_key)))) | |
| except (InvalidResponseError, urllib2.URLError), error: | |
| logging.error("%s: got an error: %s" % (url, error)) | |
| f += 1 | |
| finally: | |
| if client: | |
| client.close() | |
| sys.exit(0 if f == 0 else 1) | |
| if __name__ == "__main__": | |
| main(sys.argv) | |
| # vim:set ft=python : |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment