root / plugins / nginx / nginx-cache-multi_ @ 430d68ff
Historique | Voir | Annoter | Télécharger (4,97 ko)
| 1 |
#!/usr/bin/env python |
|---|---|
| 2 |
# -*- coding: utf-8 -*- |
| 3 |
# vim: set fileencoding=utf-8 |
| 4 |
# |
| 5 |
# Munin plugin to monitor nginx cache statuses. |
| 6 |
# |
| 7 |
# Copyright Igor Borodikhin |
| 8 |
# |
| 9 |
# License : GPLv3 |
| 10 |
# |
| 11 |
# This plugin generates two graphs - with number of requests and with percents. |
| 12 |
# Create these symlinks: |
| 13 |
# ln -s /usr/share/munin/plugins/nginx-cache-multi_ /etc/munin/plugins/nginx-cache-multi_number |
| 14 |
# ls -s /usr/share/munin/plugins/nginx-cache-multi_ /etc/munin/plugins/nginx-cache-multi_percent |
| 15 |
# |
| 16 |
# You can override the log file location. |
| 17 |
# |
| 18 |
# [nginx-cache-multi] |
| 19 |
# env.logfile /var/log/nginx/cache-access.log |
| 20 |
# |
| 21 |
# Nginx must be configured to include "cs=$upstream_cache_status" in the |
| 22 |
# log file. Example format: |
| 23 |
# |
| 24 |
# log_format cache '$remote_addr - $host [$time_local] "$request" $status ' |
| 25 |
# '$body_bytes_sent "$http_referer" ' |
| 26 |
# 'rt=$request_time ut="$upstream_response_time" ' |
| 27 |
# 'cs=$upstream_cache_status'; |
| 28 |
#%# capabilities=autoconf |
| 29 |
#%# family=contrib |
| 30 |
|
| 31 |
import os, sys, re |
| 32 |
|
| 33 |
# How we've been called |
| 34 |
prog_name = sys.argv[0] |
| 35 |
prog_name = prog_name[prog_name.rfind("/")+1:]
|
| 36 |
|
| 37 |
# What is graph type? |
| 38 |
graph_type = prog_name[prog_name.rfind("_")+1:]
|
| 39 |
|
| 40 |
# Where to store plugin state |
| 41 |
if "MUNIN_PLUGSTATE" in os.environ: |
| 42 |
state_dir = os.environ["MUNIN_PLUGSTATE"] |
| 43 |
else: |
| 44 |
state_dir = None |
| 45 |
|
| 46 |
# Log path |
| 47 |
if "logfile" in os.environ: |
| 48 |
log_file = os.environ["logfile"] |
| 49 |
else: |
| 50 |
log_file = "/var/log/nginx/access.log" |
| 51 |
|
| 52 |
cache_status_list = { "MISS" : 0, "EXPIRED" : 0, "UPDATING" : 0, "STALE" : 0, "HIT" : 0, "NONE" : 0, "TOTAL" : 0 }
|
| 53 |
|
| 54 |
if len(sys.argv) == 2 and sys.argv[1] == "autoconf": |
| 55 |
print "yes" |
| 56 |
elif len(sys.argv) == 2 and sys.argv[1] == "config": |
| 57 |
if graph_type == "number": |
| 58 |
vlabel = "requests" |
| 59 |
else: |
| 60 |
vlabel = "%" |
| 61 |
|
| 62 |
# Parent graph declaration |
| 63 |
print "multigraph nginx_cache_multi_%s" % graph_type |
| 64 |
print "graph_title Nginx cache status (%s)" % graph_type |
| 65 |
print "graph_category nginx" |
| 66 |
print "graph_vlabel %s" % vlabel |
| 67 |
for key in cache_status_list.keys(): |
| 68 |
if key != "TOTAL": |
| 69 |
print "%s.label %s" % (key.lower(), key.capitalize()) |
| 70 |
print "%s.draw AREASTACK" % key.lower() |
| 71 |
print "%s.min 0" % key.lower() |
| 72 |
print "" |
| 73 |
|
| 74 |
for key in cache_status_list.keys(): |
| 75 |
# Other graphs declaration |
| 76 |
if key != "TOTAL": |
| 77 |
print "multigraph nginx_cache_multi_%s.%s" % (graph_type, key.lower()) |
| 78 |
print "graph_title Nginx cache status (%s) - %s" % (graph_type, key.capitalize()) |
| 79 |
print "graph_category nginx" |
| 80 |
print "graph_vlabel %s" % vlabel |
| 81 |
print "%s.label %s" % (key.lower(), key.capitalize()) |
| 82 |
print "%s.draw LINE1" % key.lower() |
| 83 |
print "%s.min 0" % key.lower() |
| 84 |
print "" |
| 85 |
else: |
| 86 |
last_byte_file = "%s/%s_state" % (state_dir, prog_name) |
| 87 |
last_byte_handle = None |
| 88 |
|
| 89 |
# Load last position in log file |
| 90 |
try: |
| 91 |
last_byte_handle = open(last_byte_file, "r") |
| 92 |
last_byte = int(last_byte_handle.read()) |
| 93 |
except Exception: |
| 94 |
last_byte = 0 |
| 95 |
|
| 96 |
if last_byte_handle != None: |
| 97 |
last_byte_handle.close() |
| 98 |
|
| 99 |
# Open log file for reading |
| 100 |
try: |
| 101 |
log_handle = open(log_file, "r") |
| 102 |
except Exception: |
| 103 |
print "Log file %s not readable" % log_file |
| 104 |
sys.exit(1) |
| 105 |
|
| 106 |
# Find out log size and set proper position depending on log size |
| 107 |
try: |
| 108 |
log_size = int(os.path.getsize(log_file)) |
| 109 |
except ValueError: |
| 110 |
log_size = 0 |
| 111 |
|
| 112 |
if log_size < last_byte: |
| 113 |
last_byte = 0 |
| 114 |
|
| 115 |
# Set position on file |
| 116 |
log_handle.seek(last_byte) |
| 117 |
|
| 118 |
reg_exp = re.compile(r"cs=([^\s]+)") |
| 119 |
|
| 120 |
for line in log_handle: |
| 121 |
match = reg_exp.search(line) |
| 122 |
cache_status = match.group(1) |
| 123 |
if cache_status == "-": |
| 124 |
cache_status = "NONE" |
| 125 |
cache_status_list[cache_status] += 1 |
| 126 |
cache_status_list["TOTAL"] += 1 |
| 127 |
|
| 128 |
try: |
| 129 |
last_byte_handle = open(last_byte_file, "w") |
| 130 |
last_byte_handle.write(str(log_handle.tell())) |
| 131 |
last_byte_handle.close() |
| 132 |
except Exception: |
| 133 |
sys.exit(1) |
| 134 |
|
| 135 |
log_handle.close() |
| 136 |
|
| 137 |
# Handle graph type (_num for absolute numbers and anything alse for percents) |
| 138 |
if graph_type != "number": |
| 139 |
for key in cache_status_list.keys(): |
| 140 |
if key != "TOTAL": |
| 141 |
cache_status_list[key] = cache_status_list[key] * 100 / cache_status_list["TOTAL"] |
| 142 |
cache_status_list["TOTAL"] = 100 |
| 143 |
|
| 144 |
|
| 145 |
# Parent graph declaration |
| 146 |
print "multigraph nginx_cache_multi_%s" % graph_type |
| 147 |
#print "total.value %s" % cache_status_list["TOTAL"] |
| 148 |
for key in cache_status_list.keys(): |
| 149 |
if key != "TOTAL": |
| 150 |
print "%s.value %s" % (key.lower(), cache_status_list[key]) |
| 151 |
print "" |
| 152 |
|
| 153 |
for key in cache_status_list.keys(): |
| 154 |
# Other graphs declaration |
| 155 |
if key != "TOTAL": |
| 156 |
print "multigraph nginx_cache_multi_%s.%s" % (graph_type, key.lower()) |
| 157 |
print "total.value %s" % cache_status_list["TOTAL"] |
| 158 |
print "%s.value %s" % (key.lower(), cache_status_list[key]) |
| 159 |
print "" |
