Skip to content

Instantly share code, notes, and snippets.

@andreisavu
Created June 12, 2009 08:36
Show Gist options
  • Save andreisavu/128524 to your computer and use it in GitHub Desktop.
Save andreisavu/128524 to your computer and use it in GitHub Desktop.
Nagios plugin for measuring the peak and average number of requests a server receives.
#! /usr/bin/python
"""
Measure the number of request per seconds the
server has received in the last n requests (peak and average)
You can use it to analyze log files from apache and nginx
or any other server that uses the same log format as apache.
This script is designed to be used as a nagios plug-in.
"""
__author__ = 'Andrei Savu <contact@andreisavu.ro>'
__version__ = (0,0,1)
import sys, os, getopt,re
def apache_tail(n, file):
" Run tail on the log file and parse each line "
logre = '(?P<ip>[.\d]+) - - \[(?P<time>.*?)\] "GET (?P<uri>.*?) HTTP/1.\d" (?P<status_code>\d+) \d+ "(?P<referral>.*?)" "(?P<agent>.*?)"'
parse = re.compile(logre).search
def make_assoc(l):
if not l: return None
return {'ip': l.group('ip'),
'time': l.group('time'),
'uri': l.group('uri'),
'status_code': l.group('status_code'),
'referral': l.group('referral'),
'agent': l.group('agent')
}
p = os.popen('/usr/bin/tail -n %d %s' % (n, file))
for l in p.xreadlines():
yield make_assoc(parse(l))
p.close()
def apache_peak(n, file):
" Get apache peak number of requests per second and the average value "
db = {}
for l in apache_tail(n, file):
if not l: continue
if l['time'] in db:
db[l['time']] += 1
else:
db[l['time']] = 1
max, avg = 0, 0
for k,v in db.items():
if v > max: max = v
avg += v
avg = avg / len(db)
return max, avg
def get_args():
" Get command line arguments and validate them "
opt, args = getopt.getopt(sys.argv[1:], 'w:c:n:')
w = c = None
n = 5000
for o, v in opt:
if o == '-w':
w = int(v)
elif o == '-c':
c = int(v)
elif o == '-n':
n = int(v)
elif o == '-h':
usage()
else:
raise Exception('Unknown flag.')
if not w or not c:
raise Exception('Specify warning and critical limits.')
if not n or n <= 0:
raise Exception('n should be a positive integer')
if len(args) == 0:
raise Exception('Please specify the log file.')
return w, c, n, args[0]
def usage():
print 'Usage: ./check_rps.py -w WARNING -c CRITICAL -n LINES FILE'
print ' -w warning level. mandatory'
print ' -c critical level. mandatory'
print ' -n the number of rows to analyze. by default 5000'
print ' FILE - apache log file path. mandatory'
sys.exit(3)
def main():
if len(sys.argv) != 6 and len(sys.argv) != 8:
usage()
try:
w, c, n, f = get_args()
peak, avg = apache_peak(n, f)
check_status = 0
result = 'Ok'
if peak > w:
check_status = 1
result = 'Warning'
if peak > c:
check_status = 2
result = 'Critical'
print "%s! Peak: %d req/s Average: %d req/s|peak=%d;%d;%d average=%d" % (result, peak, avg, peak, w, c, avg)
sys.exit(check_status)
except Exception, e:
print e.message
usage()
if __name__ == '__main__':
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment