2014-10-10 17:34:41 +02:00
|
|
|
#!/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<https://github.com/munin-monitoring/contrib/tree/master/plugins/memcached>
|
|
|
|
|
|
|
|
=head1 AUTHORS
|
|
|
|
|
|
|
|
Jonas Kaufmann <jonas@windfinder.com>
|
|
|
|
|
|
|
|
=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) {
|
2017-04-17 22:43:38 +02:00
|
|
|
print "Error: number of addresses and labels must be equal.\n";
|
2014-10-10 17:34:41 +02:00
|
|
|
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";
|
2017-02-27 00:25:28 +01:00
|
|
|
print "graph_category memory\n";
|
2014-10-10 17:34:41 +02:00
|
|
|
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";
|
2017-02-27 00:25:28 +01:00
|
|
|
print "graph_category memory\n";
|
2014-10-10 17:34:41 +02:00
|
|
|
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";
|
2017-02-27 00:25:28 +01:00
|
|
|
print "graph_category memory\n";
|
2014-10-10 17:34:41 +02:00
|
|
|
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";
|
2017-02-27 00:25:28 +01:00
|
|
|
print "graph_category memory\n";
|
2014-10-10 17:34:41 +02:00
|
|
|
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";
|
2017-02-27 00:25:28 +01:00
|
|
|
print "graph_category memory\n";
|
2014-10-10 17:34:41 +02:00
|
|
|
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";
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|