Skip to content

Instantly share code, notes, and snippets.

@Lusitaniae
Forked from bactisme/nginx_status_codes.py
Last active May 23, 2017 14:47
Show Gist options
  • Save Lusitaniae/fb8532294b1cfba7aceffa1e2dd2a264 to your computer and use it in GitHub Desktop.
Save Lusitaniae/fb8532294b1cfba7aceffa1e2dd2a264 to your computer and use it in GitHub Desktop.
Very simple munin plugin to graph nginx HTTP error codes
#!/usr/bin/python3
'''
Monitors error rates based on the Nginx access log.
By default triggers an warn alert at 2 req/s and critical for 4 req/s for each status code.
Some of the less common status codes have been commented out. Customize accordingly for yourself.
ALL FAME GOES HERE : https://gist.github.com/mipearson/1146151
Install:
wget https://gist.github.com/Lusitaniae/fb8532294b1cfba7aceffa1e2dd2a264 -O /usr/share/munin/plugins/nginx_error_rate;
ln -s /usr/share/munin/plugins/nginx_error_rate /etc/munin/plugins/;
chmod +x /etc/munin/plugins/nginx_error_rate;
Test:
munin-run nginx_error_rate;
munin-run nginx_error_rate config;
Munin conf (optional):
[nginx*]
user root
env.access_log /var/log/nginx/blogs.access.log
'user root' might be necessary if you have permission errors.
'''
import re, sys, os
CODES = {
'400': 'Bad Request',
'401': 'Unauthorized',
'403': 'Forbidden',
'404': 'Not Found',
# '405': 'Method Not Allowed',
# '406': 'Not Acceptable',
# '408': 'Request Timeout',
# '499': 'Client Connection Terminated',
'500': 'Internal Server Error',
'502': 'Bad Gateway',
'503': 'Service Unavailable',
'504': 'Gateway timeout',
# 'Other': 'Other responses'
}
ACCESS_LOG = "/var/log/nginx/access.log"
if 'access_log' in os.environ:
ACCESS_LOG = os.environ.get('access_log')
if len(sys.argv) > 1 and sys.argv[1] == 'config':
print ("graph_title nginx Error Codes")
print ("graph_vlabel responses per minute")
print ("graph_category nginx")
print ("graph_period minute")
print ("graph_info Non-200 response codes per minute")
for code in CODES:
print ("stat%s.label %s %s" % (code, code, CODES[code]))
print ("stat%s.type DERIVE" % (code))
print ("stat%s.min 0" % (code))
print("stat%s.warning 2" % code)
print("stat%s.critical 4" % code)
else:
results = {k:0 for k in CODES}
with open(ACCESS_LOG, 'r') as f:
for line in f.readlines():
code = re.search(" (\d\d\d) ", line)
if code:
code = code.group(0).strip()
if code in CODES:
results[code] += 1
# elif int(code) >= 400:
# results['Other'] += 1
for k in results:
print("stat%s.value %s" % (k, results[k]))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment