diff --git a/plugins/memcached/memcached_servers_ b/plugins/memcached/memcached_servers_ new file mode 100644 index 00000000..f1262035 --- /dev/null +++ b/plugins/memcached/memcached_servers_ @@ -0,0 +1,201 @@ +#!/usr/bin/env perl +=head1 NAME + +memcached_servers_ - Munin multigraph plugin to monitor multiple memcache servers + +=head1 CONFIGURATION + +You need to configure the to-be-used servers and the corresponding labels separated +by spaace in your environment. Example: + +[memcached_servers_*] + env.addresses cache1.server.com:11211 cache2.server.com:11211 + env.labels master slave + +Please note that the number of labels and addresses must be equal. + + +=head1 MULTIGRAPH + +With munin multigraph capabilities, you can generate different graphs. Available +graphs include: + +=over + +=item bytes: memcached bytes usage + +=item hits: get and set hits + +=item items: number of stored items + +=item requests: number of requests + +=item traffic: traffic + +=back + +Link the plugin to get the desirec output, for example: memcached_multi_bytes + + +=head1 DEPENDENCIES + +=over + +=item Cache::Memcached + +=back + + +=head1 ACKNOWLEDGEMENTS + +This plugin is based on the available memcached plugins at +L + +=head1 AUTHORS + +Jonas Kaufmann + +=cut + +use strict; +use warnings; +use Cache::Memcached; +use File::Basename; + +#Configuration of used servers in environment +my @addresses = split(/ /, $ENV{addresses}); +my @labels = split(/ /, $ENV{labels}); + +if ($#addresses < 0 || $#labels < 0) { + print "Error: you need to configure addresses and labels in your environment.\n"; + exit 1; +} + +if ($#addresses != $#labels) { + print "Error: number of adresses and labels must be equal.\n"; + exit 1; +} + +# Configuration of modes for multigraph +my @modes = qw(bytes hits items requests traffic); + +my $mode = substr(basename($0), length('memcached_servers_')); +if (($mode eq '') || ! grep($_ eq $mode, @modes)) { + $mode = $modes[0]; +} + + +# Output for munin config +my $cmd = shift || ''; +if ($cmd eq 'config') { + # Labels and basic graph information + if ($mode eq 'bytes') { + print "graph_title Memcached bytes used\n"; + print "graph_args --base 1024 -l 0\n"; + print "graph_vlabel bytes\n"; + print "graph_category memcached\n"; + print "graph_info This graph monitors the size of the memcached cache.\n"; + } elsif ($mode eq 'hits') { + print "graph_title Memcached cache hits and misses\n"; + print "graph_args --base 1000 -l 0\n"; + print "graph_vlabel requests\n"; + print "graph_category memcached\n"; + print "graph_info This graph monitors the number of cache hits and misses.\n"; + } elsif ($mode eq 'items') { + print "graph_title Memcached cached items\n"; + print "graph_args --base 1000 -l 0\n"; + print "graph_vlabel items\n"; + print "graph_category memcached\n"; + print "graph_info This graph monitors the number of items stored by the memcached server.\n"; + } elsif ($mode eq 'requests') { + print "graph_title Memcached requests\n"; + print "graph_args --base 1000 -l 0\n"; + print "graph_vlabel requests\n"; + print "graph_category memcached\n"; + print "graph_info This graph monitors the number of get and set requests.\n"; + } elsif ($mode eq 'traffic') { + print "graph_title Memcached network traffic\n"; + print "graph_args --base 1000 -l 0\n"; + print "graph_vlabel bits per \${graph_period}\n"; + print "graph_category memcached\n"; + print "graph_info This graph monitors the network traffic of the memcached server.\n"; + } + + + # Graph configuration + for (my $i = 0; $i < @labels; $i++) { + if ($mode eq 'bytes') { + print "bytes_" . $labels[$i] . ".label bytes used (" . $labels[$i] . ")\n"; + print "bytes_" . $labels[$i] . ".info Number of bytes currently used (" . $labels[$i] . ")\n"; + print "bytes_" . $labels[$i] . ".min 0\n"; + print "maxbytes_" . $labels[$i] . ".label maximum available (" . $labels[$i] . ")\n"; + print "maxbytes_" . $labels[$i] . ".info The configured cache size (" . $labels[$i] . ")\n"; + print "maxbytes_" . $labels[$i] . ".min 0\n"; + } elsif ($mode eq 'hits') { + print "hits_" . $labels[$i] . ".label hits (" . $labels[$i] . ")\n"; + print "hits_" . $labels[$i] . ".info Number of cache hits (" . $labels[$i] . ")\n"; + print "hits_" . $labels[$i] . ".min 0\n"; + print "hits_" . $labels[$i] . ".type DERIVE\n"; + print "misses_" . $labels[$i] . ".label misses (" . $labels[$i] . ")\n"; + print "misses_" . $labels[$i] . ".info Number of cache misses (" . $labels[$i] . ")\n"; + print "misses_" . $labels[$i] . ".min 0\n"; + print "misses_" . $labels[$i] . ".type DERIVE\n"; + } elsif ($mode eq 'items') { + print "items_" . $labels[$i] . ".label items (" . $labels[$i] . ")\n"; + print "items_" . $labels[$i] . ".info Number of cached items (" . $labels[$i] . ")\n"; + print "items_" . $labels[$i] . ".min 0\n"; + } elsif ($mode eq 'requests') { + print "gets_" . $labels[$i] . ".label gets (" . $labels[$i] . ")\n"; + print "gets_" . $labels[$i] . ".info Number of get requests (" . $labels[$i] . ")\n"; + print "gets_" . $labels[$i] . ".min 0\n"; + print "gets_" . $labels[$i] . ".type DERIVE\n"; + print "sets_" . $labels[$i] . ".label sets (" . $labels[$i] . ")\n"; + print "sets_" . $labels[$i] . ".info Number of set requests (" . $labels[$i] . ")\n"; + print "sets_" . $labels[$i] . ".min 0\n"; + print "sets_" . $labels[$i] . ".type DERIVE\n"; + } elsif ($mode eq 'traffic') { + print "up_" . $labels[$i] . ".label bits in (" . $labels[$i] . ")\n"; + print "up_" . $labels[$i] . ".info Traffic received by memcached (" . $labels[$i] . ")\n"; + print "up_" . $labels[$i] . ".min 0\n"; + print "up_" . $labels[$i] . ".cdef up_" . $labels[$i] . ",8,*\n"; + print "up_" . $labels[$i] . ".type COUNTER\n"; + print "down_" . $labels[$i] . ".label bits out (" . $labels[$i] . ")\n"; + print "down_" . $labels[$i] . ".info Traffic sent by memcached (" . $labels[$i] . ")\n"; + print "down_" . $labels[$i] . ".min 0\n"; + print "down_" . $labels[$i] . ".cdef down_" . $labels[$i] . ",8,*\n"; + print "down_" . $labels[$i] . ".type COUNTER\n"; + } + } + exit 0; +} + + + +# Output for data queries +for (my $i = 0; $i < @addresses; $i++) { + my $memd = new Cache::Memcached { 'servers' => [$addresses[$i]] }; + my $memstats = $memd->stats(['misc']); + + if ($mode eq 'bytes') { + print "bytes_" . $labels[$i] . ".value " . + $memstats->{hosts}->{$addresses[$i]}->{misc}->{bytes} . "\n"; + print "maxbytes_" . $labels[$i] . ".value " . + $memstats->{hosts}->{$addresses[$i]}->{misc}->{limit_maxbytes} . "\n"; + } elsif ($mode eq 'hits') { + print "hits_" . $labels[$i] . ".value " . + $memstats->{hosts}->{$addresses[$i]}->{misc}->{get_hits} . "\n"; + print "misses_" . $labels[$i] . ".value " . + $memstats->{hosts}->{$addresses[$i]}->{misc}->{get_misses} . "\n"; + } elsif ($mode eq 'items') { + print "items_" . $labels[$i] . ".value " . + $memstats->{hosts}->{$addresses[$i]}->{misc}->{curr_items} . "\n"; + } elsif ($mode eq 'requests') { + print "gets_" . $labels[$i] . ".value " . $memstats->{hosts}->{$addresses[$i]}->{misc}->{cmd_get} . "\n"; + print "sets_" . $labels[$i] . ".value " . $memstats->{hosts}->{$addresses[$i]}->{misc}->{cmd_set} . "\n"; + } elsif ($mode eq 'traffic') { + print "up_" . $labels[$i] . ".value " . $memstats->{hosts}->{$addresses[$i]}->{misc}->{bytes_read} . "\n"; + print "down_" . $labels[$i] . ".value " . $memstats->{hosts}->{$addresses[$i]}->{misc}->{bytes_written} . "\n"; + } + +} +