munin-contrib/plugins/nginx/nginx-cache-multi_

164 lines
5.1 KiB
Python
Executable File

#!/usr/bin/env python
# -*- coding: utf-8 -*-
# vim: set fileencoding=utf-8
#
# Munin plugin to monitor nginx cache statuses.
#
# Copyright Igor Borodikhin
#
# License : GPLv3
#
# This plugin generates two graphs - with number of requests and with percents.
# Create these symlinks:
# ln -s /usr/share/munin/plugins/nginx-cache-multi_ /etc/munin/plugins/nginx-cache-multi_number
# ln -s /usr/share/munin/plugins/nginx-cache-multi_ /etc/munin/plugins/nginx-cache-multi_percent
#
# You can override the log file location.
#
# [nginx-cache-multi]
# env.logfile /var/log/nginx/cache-access.log
#
# Nginx must be configured to include "cs=$upstream_cache_status" in the
# log file. Example format:
#
# log_format cache '$remote_addr - $host [$time_local] "$request" $status '
# '$body_bytes_sent "$http_referer" '
# 'rt=$request_time ut="$upstream_response_time" '
# 'cs=$upstream_cache_status';
#%# capabilities=autoconf
#%# family=contrib
import os, sys, re
# How we've been called
prog_name = sys.argv[0]
prog_name = prog_name[prog_name.rfind("/")+1:]
# What is graph type?
graph_type = prog_name[prog_name.rfind("_")+1:]
# Where to store plugin state
if "MUNIN_PLUGSTATE" in os.environ:
state_dir = os.environ["MUNIN_PLUGSTATE"]
else:
state_dir = None
# Log path
if "logfile" in os.environ:
log_file = os.environ["logfile"]
else:
log_file = "/var/log/nginx/access.log"
cache_status_list = { "MISS" : 0, "EXPIRED" : 0, "UPDATING" : 0, "STALE" : 0, "HIT" : 0, "NONE" : 0, "TOTAL" : 0 }
if len(sys.argv) == 2 and sys.argv[1] == "autoconf":
print "yes"
elif len(sys.argv) == 2 and sys.argv[1] == "config":
graph_args = ""
if graph_type == "number":
vlabel = "requests"
else:
vlabel = "%"
graph_args = "graph_args -l 0"
# Parent graph declaration
print "multigraph nginx_cache_multi_%s" % graph_type
print "graph_title Nginx cache status (%s)" % graph_type
print "graph_category webserver"
print "graph_vlabel %s" % vlabel
if graph_args:
print(graph_args)
for key in cache_status_list.keys():
if key != "TOTAL":
print "%s.label %s" % (key.lower(), key.capitalize())
print "%s.draw AREASTACK" % key.lower()
print "%s.min 0" % key.lower()
print ""
for key in cache_status_list.keys():
# Other graphs declaration
if key != "TOTAL":
print "multigraph nginx_cache_multi_%s.%s" % (graph_type, key.lower())
print "graph_title Nginx cache status (%s) - %s" % (graph_type, key.capitalize())
print "graph_category webserver"
print "graph_vlabel %s" % vlabel
print "%s.label %s" % (key.lower(), key.capitalize())
print "%s.draw LINE1" % key.lower()
print "%s.min 0" % key.lower()
print ""
else:
last_byte_file = "%s/%s_state" % (state_dir, prog_name)
last_byte_handle = None
# Load last position in log file
try:
last_byte_handle = open(last_byte_file, "r")
last_byte = int(last_byte_handle.read())
except Exception:
last_byte = 0
if last_byte_handle != None:
last_byte_handle.close()
# Open log file for reading
try:
log_handle = open(log_file, "r")
except Exception:
print "Log file %s not readable" % log_file
sys.exit(1)
# Find out log size and set proper position depending on log size
try:
log_size = int(os.path.getsize(log_file))
except ValueError:
log_size = 0
if log_size < last_byte:
last_byte = 0
# Set position on file
log_handle.seek(last_byte)
reg_exp = re.compile(r"cs=([^\s]+)")
for line in log_handle:
match = reg_exp.search(line)
cache_status = match.group(1)
if cache_status == "-":
cache_status = "NONE"
cache_status_list[cache_status] += 1
cache_status_list["TOTAL"] += 1
try:
last_byte_handle = open(last_byte_file, "w")
last_byte_handle.write(str(log_handle.tell()))
last_byte_handle.close()
except Exception:
sys.exit(1)
log_handle.close()
# Handle graph type (_num for absolute numbers and anything else for percents)
if graph_type != "number":
for key in cache_status_list.keys():
if key != "TOTAL":
cache_status_list[key] = cache_status_list[key] * 100 / cache_status_list["TOTAL"]
cache_status_list["TOTAL"] = 100
# Parent graph declaration
print "multigraph nginx_cache_multi_%s" % graph_type
#print "total.value %s" % cache_status_list["TOTAL"]
for key in cache_status_list.keys():
if key != "TOTAL":
print "%s.value %s" % (key.lower(), cache_status_list[key])
print ""
for key in cache_status_list.keys():
# Other graphs declaration
if key != "TOTAL":
print "multigraph nginx_cache_multi_%s.%s" % (graph_type, key.lower())
print "total.value %s" % cache_status_list["TOTAL"]
print "%s.value %s" % (key.lower(), cache_status_list[key])
print ""