root / plugins / nginx / nginx-cache-multi_ @ d5fc30a9
Historique | Voir | Annoter | Télécharger (5,09 ko)
| 1 | f6276fc9 | iborodikhin | #!/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 | c2513bd2 | poiuty | # ln -s /usr/share/munin/plugins/nginx-cache-multi_ /etc/munin/plugins/nginx-cache-multi_percent |
| 15 | f6276fc9 | iborodikhin | # |
| 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 | 40532b68 | Johann Schmitz | graph_args = "" |
| 58 | f6276fc9 | iborodikhin | if graph_type == "number": |
| 59 | vlabel = "requests" |
||
| 60 | else: |
||
| 61 | vlabel = "%" |
||
| 62 | 40532b68 | Johann Schmitz | graph_args = "graph_args -l 0" |
| 63 | f6276fc9 | iborodikhin | |
| 64 | # Parent graph declaration |
||
| 65 | print "multigraph nginx_cache_multi_%s" % graph_type |
||
| 66 | print "graph_title Nginx cache status (%s)" % graph_type |
||
| 67 | 3c98d069 | dipohl | print "graph_category webserver" |
| 68 | f6276fc9 | iborodikhin | print "graph_vlabel %s" % vlabel |
| 69 | 40532b68 | Johann Schmitz | if graph_args: |
| 70 | print(graph_args) |
||
| 71 | f6276fc9 | iborodikhin | for key in cache_status_list.keys(): |
| 72 | if key != "TOTAL": |
||
| 73 | print "%s.label %s" % (key.lower(), key.capitalize()) |
||
| 74 | print "%s.draw AREASTACK" % key.lower() |
||
| 75 | print "%s.min 0" % key.lower() |
||
| 76 | print "" |
||
| 77 | |||
| 78 | for key in cache_status_list.keys(): |
||
| 79 | # Other graphs declaration |
||
| 80 | if key != "TOTAL": |
||
| 81 | print "multigraph nginx_cache_multi_%s.%s" % (graph_type, key.lower()) |
||
| 82 | print "graph_title Nginx cache status (%s) - %s" % (graph_type, key.capitalize()) |
||
| 83 | 3c98d069 | dipohl | print "graph_category webserver" |
| 84 | f6276fc9 | iborodikhin | print "graph_vlabel %s" % vlabel |
| 85 | print "%s.label %s" % (key.lower(), key.capitalize()) |
||
| 86 | 80cb77cb | iborodikhin | print "%s.draw LINE1" % key.lower() |
| 87 | f6276fc9 | iborodikhin | print "%s.min 0" % key.lower() |
| 88 | print "" |
||
| 89 | else: |
||
| 90 | last_byte_file = "%s/%s_state" % (state_dir, prog_name) |
||
| 91 | last_byte_handle = None |
||
| 92 | |||
| 93 | # Load last position in log file |
||
| 94 | try: |
||
| 95 | last_byte_handle = open(last_byte_file, "r") |
||
| 96 | last_byte = int(last_byte_handle.read()) |
||
| 97 | except Exception: |
||
| 98 | last_byte = 0 |
||
| 99 | |||
| 100 | if last_byte_handle != None: |
||
| 101 | last_byte_handle.close() |
||
| 102 | |||
| 103 | # Open log file for reading |
||
| 104 | try: |
||
| 105 | log_handle = open(log_file, "r") |
||
| 106 | except Exception: |
||
| 107 | print "Log file %s not readable" % log_file |
||
| 108 | sys.exit(1) |
||
| 109 | |||
| 110 | # Find out log size and set proper position depending on log size |
||
| 111 | try: |
||
| 112 | log_size = int(os.path.getsize(log_file)) |
||
| 113 | except ValueError: |
||
| 114 | log_size = 0 |
||
| 115 | |||
| 116 | if log_size < last_byte: |
||
| 117 | last_byte = 0 |
||
| 118 | |||
| 119 | # Set position on file |
||
| 120 | log_handle.seek(last_byte) |
||
| 121 | |||
| 122 | reg_exp = re.compile(r"cs=([^\s]+)") |
||
| 123 | |||
| 124 | for line in log_handle: |
||
| 125 | match = reg_exp.search(line) |
||
| 126 | cache_status = match.group(1) |
||
| 127 | if cache_status == "-": |
||
| 128 | cache_status = "NONE" |
||
| 129 | cache_status_list[cache_status] += 1 |
||
| 130 | cache_status_list["TOTAL"] += 1 |
||
| 131 | |||
| 132 | try: |
||
| 133 | last_byte_handle = open(last_byte_file, "w") |
||
| 134 | last_byte_handle.write(str(log_handle.tell())) |
||
| 135 | last_byte_handle.close() |
||
| 136 | except Exception: |
||
| 137 | sys.exit(1) |
||
| 138 | |||
| 139 | log_handle.close() |
||
| 140 | |||
| 141 | fba800ae | Veres Lajos | # Handle graph type (_num for absolute numbers and anything else for percents) |
| 142 | f6276fc9 | iborodikhin | if graph_type != "number": |
| 143 | for key in cache_status_list.keys(): |
||
| 144 | if key != "TOTAL": |
||
| 145 | cache_status_list[key] = cache_status_list[key] * 100 / cache_status_list["TOTAL"] |
||
| 146 | cache_status_list["TOTAL"] = 100 |
||
| 147 | |||
| 148 | |||
| 149 | # Parent graph declaration |
||
| 150 | print "multigraph nginx_cache_multi_%s" % graph_type |
||
| 151 | #print "total.value %s" % cache_status_list["TOTAL"] |
||
| 152 | for key in cache_status_list.keys(): |
||
| 153 | if key != "TOTAL": |
||
| 154 | print "%s.value %s" % (key.lower(), cache_status_list[key]) |
||
| 155 | print "" |
||
| 156 | |||
| 157 | for key in cache_status_list.keys(): |
||
| 158 | # Other graphs declaration |
||
| 159 | if key != "TOTAL": |
||
| 160 | print "multigraph nginx_cache_multi_%s.%s" % (graph_type, key.lower()) |
||
| 161 | print "total.value %s" % cache_status_list["TOTAL"] |
||
| 162 | print "%s.value %s" % (key.lower(), cache_status_list[key]) |
||
| 163 | 40532b68 | Johann Schmitz | print "" |
