Skip to content

Commit

Permalink
Added plugin to monitor multiple memcached servers
Browse files Browse the repository at this point in the history
This plugins allows to monitor multiple memcached servers. The server names can be given in the environment. Graphs include memcached bytes usage, get and set hits, number of stored items, number of requests and traffic. These graphs contain values for each server.
  • Loading branch information
j0nes2k committed Oct 10, 2014
1 parent b098ec4 commit e10ae8e
Showing 1 changed file with 201 additions and 0 deletions.
201 changes: 201 additions & 0 deletions 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<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) {
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";
}

}

0 comments on commit e10ae8e

Please sign in to comment.