1
0
Fork 0
mirror of https://github.com/munin-monitoring/contrib.git synced 2025-07-23 06:35:42 +00:00

Updating Memcached Multigraph plugin to latest version

This commit is contained in:
Matt West 2012-02-09 10:03:20 -08:00
parent 59f28e56ed
commit 208bfbedb3

View file

@ -1,6 +1,6 @@
#!/usr/bin/perl #!/usr/bin/perl
# #
=head1 NAME =head1 MEMCACHED
Memcached - A Plugin to monitor Memcached Servers (Multigraph) Memcached - A Plugin to monitor Memcached Servers (Multigraph)
@ -36,9 +36,6 @@ items => I<MULTIGRAPH> This graphs the current items and total items in the memc
memory => I<MULTIGRAPH> This graphs the current and max memory allocation B<Multigraph breaks this down to per slab.> memory => I<MULTIGRAPH> This graphs the current and max memory allocation B<Multigraph breaks this down to per slab.>
The following example holds true for all graphing options in this plugin.
Example: ln -s /usr/share/munin/plugins/memcached_multi_ /etc/munin/plugins/memcached_multi_bytes
=head1 ADDITIONAL INFORMATION =head1 ADDITIONAL INFORMATION
You will find that some of the graphs have LEI on them. This was done in order to save room You will find that some of the graphs have LEI on them. This was done in order to save room
@ -52,13 +49,11 @@ The B<Timescale> variable formats certain graphs based on the following guidelin
=head1 ACKNOWLEDGEMENTS =head1 ACKNOWLEDGEMENTS
The core of this plugin is based on the mysql_ plugin maintained by Kjell-Magne Ãierud Thanks to dormando for putting up with me ;)
Thanks to dormando as well for putting up with me ;)
=head1 AUTHOR =head1 AUTHOR
Matt West < https://code.google.com/p/memcached-munin-plugin/ > Matt West < https://github.com/mhwest13/Memcached-Munin-Plugin >
=head1 LICENSE =head1 LICENSE
@ -72,54 +67,77 @@ GPLv2
=cut =cut
use strict; use strict;
use warnings;
use IO::Socket; use IO::Socket;
use Munin::Plugin; use Munin::Plugin;
use File::Basename;
if (basename($0) !~ /^memcached_multi_/) {
print "This script needs to be named memcached_multi_ and have symlinks which start the same.\n";
exit 1;
}
# tell munin about our multigraph capabilities
need_multigraph(); need_multigraph();
=head1 Variable Declarations
This section of code is to declare the variables used throughout the plugin
Some of them are imported as environment variables from munin plugin conf.d
file, others are hashes used for storing information that comes from the
stats commands issued to memcached.
=cut
# lets import environment variables for the plugin or use the default
my $host = $ENV{host} || "127.0.0.1"; my $host = $ENV{host} || "127.0.0.1";
my $port = $ENV{port} || 11211; my $port = $ENV{port} || 11211;
my %stats;
# This hash contains the information contained in two memcache commands
# stats and stats settings.
my %items;
# This gives us eviction rates and other hit stats per slab
# We track this so we can see if something was evicted earlier than necessary
my %chnks;
# This gives us the memory size and usage per slab
# We track this so we can see what slab is being used the most and has no free chunks
# so we can re-tune memcached to allocate more pages for the specified chunk size
my $timescale = $ENV{timescale} || 3;
# This gives us the ability to control the timescale our graphs are displaying. # This gives us the ability to control the timescale our graphs are displaying.
# The default it set to divide by hours, if you want to get seconds set it to 1. # The default it set to divide by hours, if you want to get seconds set it to 1.
# Options: 1 = seconds, 2 = minutes, 3 = hours, 4 = days # Options: 1 = seconds, 2 = minutes, 3 = hours, 4 = days
my $timescale = $ENV{timescale} || 3;
# This hash contains the information contained in two memcache commands
# stats and stats settings.
my %stats;
# This gives us eviction rates and other hit stats per slab
# We track this so we can see if something was evicted earlier than necessary
my %items;
# This gives us the memory size and usage per slab
# We track this so we can see what slab is being used the most and has no free chunks
# so we can re-tune memcached to allocate more pages for the specified chunk size
my %chnks;
=head2 Graph Declarations
This block of code builds up all of the graph info for all root / sub graphs.
%graphs: is a container for all of the graph definition information. In here is where you'll
find the configuration information for munin's graphing procedure.
Format:
$graph{graph_name} => {
config => {
You'll find the main graph config stored here
{ key => value },
{ ... },
},
datasrc => [
Name: name given to data value
Attr: Attribute and value, attribute must be valid plugin argument
{ name => 'Name', info => 'info about graph', ... },
{ ... },
],
}
=cut
# So I was trying to figure out how to build this up, and looking at some good examples
# I decided to use the format, or for the most part, the format from the mysql_ munin plugin
# for Innodb by Kjell-Magne Ãierud, it just spoke ease of flexibility especially with multigraphs
# thanks btw ;)
#
# %graphs is a container for all of the graph definition information. In here is where you'll
# find the configuration information for munin's graphing procedure.
# Format:
#
# $graph{graph_name} => {
# config => {
# # You'll find keys and values stored here for graph manipulation
# },
# datasrc => [
# # Name: name given to data value
# # Attr: Attribute for given value
# { name => 'Name', (Attr) },
# { ... },
# ],
# }
my %graphs; my %graphs;
# main graph for memcached item count
$graphs{items} = { $graphs{items} = {
config => { config => {
args => '--base 1000 --lower-limit 0', args => '--base 1000 --lower-limit 0',
@ -133,7 +151,7 @@ $graphs{items} = {
{ name => 'total_items', label => 'New Items', min => '0', type => 'DERIVE' }, { name => 'total_items', label => 'New Items', min => '0', type => 'DERIVE' },
], ],
}; };
# main graph for memcached memory usage
$graphs{memory} = { $graphs{memory} = {
config => { config => {
args => '--base 1024 --lower-limit 0', args => '--base 1024 --lower-limit 0',
@ -147,7 +165,7 @@ $graphs{memory} = {
{ name => 'bytes', draw => 'AREA', label => 'Current Bytes Used', min => '0' }, { name => 'bytes', draw => 'AREA', label => 'Current Bytes Used', min => '0' },
], ],
}; };
# main graph for memcached network usage
$graphs{bytes} = { $graphs{bytes} = {
config => { config => {
args => '--base 1000', args => '--base 1000',
@ -162,7 +180,7 @@ $graphs{bytes} = {
{ name => 'bytes_written', type => 'DERIVE', label => 'Traffic in (-) / out (+)', negative => 'bytes_read', cdef => 'bytes_written,8,*', min => '0' }, { name => 'bytes_written', type => 'DERIVE', label => 'Traffic in (-) / out (+)', negative => 'bytes_read', cdef => 'bytes_written,8,*', min => '0' },
], ],
}; };
# graph for memcached connections
$graphs{conns} = { $graphs{conns} = {
config => { config => {
args => '--base 1000 --lower-limit 0', args => '--base 1000 --lower-limit 0',
@ -178,7 +196,7 @@ $graphs{conns} = {
{ name => 'avg_conns' , label => 'Avg Connections', min => '0' }, { name => 'avg_conns' , label => 'Avg Connections', min => '0' },
], ],
}; };
# main graph for memcached commands issued
$graphs{commands} = { $graphs{commands} = {
config => { config => {
args => '--base 1000 --lower-limit 0', args => '--base 1000 --lower-limit 0',
@ -200,7 +218,7 @@ $graphs{commands} = {
{ name => 'decr_misses', type => 'DERIVE', label => 'Decrement Misses', info => 'Number of unsuccessful decrement requests', min => '0' }, { name => 'decr_misses', type => 'DERIVE', label => 'Decrement Misses', info => 'Number of unsuccessful decrement requests', min => '0' },
], ],
}; };
# main graph for memcached eviction rates
$graphs{evictions} = { $graphs{evictions} = {
config => { config => {
args => '--base 1000 --lower-limit 0', args => '--base 1000 --lower-limit 0',
@ -215,7 +233,7 @@ $graphs{evictions} = {
{ name => 'reclaimed', label => 'Reclaimed Items', info => 'Cumulative Reclaimed Item Entries Across All Slabs', type => 'DERIVE', min => '0' }, { name => 'reclaimed', label => 'Reclaimed Items', info => 'Cumulative Reclaimed Item Entries Across All Slabs', type => 'DERIVE', min => '0' },
], ],
}; };
# sub graph for breaking memory info down by slab ( sub graph of memory )
$graphs{slabchnks} = { $graphs{slabchnks} = {
config => { config => {
args => '--base 1000 --lower-limit 0', args => '--base 1000 --lower-limit 0',
@ -230,7 +248,7 @@ $graphs{slabchnks} = {
{ name => 'free_chunks', label => 'Total Chunks Not in Use (Free)', min => '0' }, { name => 'free_chunks', label => 'Total Chunks Not in Use (Free)', min => '0' },
], ],
}; };
# sub graph for breaking commands down by slab ( sub graph of commands )
$graphs{slabhits} = { $graphs{slabhits} = {
config => { config => {
args => '--base 1000 --lower-limit 0', args => '--base 1000 --lower-limit 0',
@ -247,7 +265,7 @@ $graphs{slabhits} = {
{ name => 'decr_hits', label => 'Decrement Requests', type => 'DERIVE', min => '0' }, { name => 'decr_hits', label => 'Decrement Requests', type => 'DERIVE', min => '0' },
], ],
}; };
# sub graph for breaking evictions down by slab ( sub graph of evictions )
$graphs{slabevics} = { $graphs{slabevics} = {
config => { config => {
args => '--base 1000 --lower-limit 0', args => '--base 1000 --lower-limit 0',
@ -262,7 +280,7 @@ $graphs{slabevics} = {
{ name => 'reclaimed', label => 'Reclaimed Expired Items', info => 'This is number of times items were stored in expired entry memory space', type => 'DERIVE', min => '0' }, { name => 'reclaimed', label => 'Reclaimed Expired Items', info => 'This is number of times items were stored in expired entry memory space', type => 'DERIVE', min => '0' },
], ],
}; };
# sub graph for showing the time between an item was last evicted and requested ( sub graph of evictions )
$graphs{slabevictime} = { $graphs{slabevictime} = {
config => { config => {
args => '--base 1000 --lower-limit 0', args => '--base 1000 --lower-limit 0',
@ -275,7 +293,7 @@ $graphs{slabevictime} = {
{ name => 'evicted_time', label => 'Eviction Time (LEI)', info => 'Time Since Request for Last Evicted Item', min => '0' }, { name => 'evicted_time', label => 'Eviction Time (LEI)', info => 'Time Since Request for Last Evicted Item', min => '0' },
], ],
}; };
# sub graph for breaking items down by slab ( sub graph of items )
$graphs{slabitems} = { $graphs{slabitems} = {
config => { config => {
args => '--base 1000 --lower-limit 0', args => '--base 1000 --lower-limit 0',
@ -288,7 +306,7 @@ $graphs{slabitems} = {
{ name => 'number', label => 'Items', info => 'This is the amount of items stored in this slab', min => '0' }, { name => 'number', label => 'Items', info => 'This is the amount of items stored in this slab', min => '0' },
], ],
}; };
# sub graph for showing the age of the eldest item stored in a slab ( sub graph of items )
$graphs{slabitemtime} = { $graphs{slabitemtime} = {
config => { config => {
args => '--base 1000 --lower-limit 0', args => '--base 1000 --lower-limit 0',
@ -302,37 +320,47 @@ $graphs{slabitemtime} = {
], ],
}; };
## =head1 Munin Checks
#### Config Check ####
## These checks look for config / autoconf / suggest params
=head2 Config Check
This block of code looks at the argument that is possibly supplied,
should it be config, it then checks to make sure the plugin
specified exists, assuming it does, it will run the do_config
subroutine for the plugin specified, otherwise it dies complaining
about an unknown plugin.
=cut
if (defined $ARGV[0] && $ARGV[0] eq 'config') { if (defined $ARGV[0] && $ARGV[0] eq 'config') {
# Lets get our plugin from the symlink being called up, we'll also verify its a valid
# plugin that we have graph information for
$0 =~ /memcached_multi_(.+)*/; $0 =~ /memcached_multi_(.+)*/;
my $plugin = $1; my $plugin = $1;
die 'Unknown Plugin Specified: ' . ($plugin ? $plugin : '') unless $graphs{$plugin}; die 'Unknown Plugin Specified: ' . ($plugin ? $plugin : '') unless $graphs{$plugin};
# We need to fetch the stats before we do any config, cause its needed for multigraph # We need to fetch the stats before we do any config, cause its needed for multigraph
# subgraphs which use slab information for title / info per slab
fetch_stats(); fetch_stats();
# Now lets go ahead and print out our config. # Now lets go ahead and print out our config.
do_config($plugin); do_config($plugin);
exit 0; exit 0;
} }
## =head2 Autoconf Check
#### Autoconf Check ####
## This block of code looks at the argument that is possibly supplied,
should it be autoconf, we will attempt to connect to the memcached
service specified on the host:port, upon successful connection it
prints yes, otherwise it prints no.
=cut
if (defined $ARGV[0] && $ARGV[0] eq 'autoconf') { if (defined $ARGV[0] && $ARGV[0] eq 'autoconf') {
# Lets attempt to connect to memcached
my $s = IO::Socket::INET->new( my $s = get_conn();
Proto => "tcp", # Lets verify that we did connect to memcached
PeerAddr => $host,
PeerPort => $port,
);
if (defined($s)) { if (defined($s)) {
print "yes\n"; print "yes\n";
exit 0; exit 0;
@ -342,18 +370,21 @@ if (defined $ARGV[0] && $ARGV[0] eq 'autoconf') {
} }
} }
## =head2 Suggest Check
#### Suggest Check ####
## This block of code looks at the argument that is possibly supplied,
should it be suggest, we are going to print the possible plugins
which can be specified. Note we only specify the root graphs for the
multigraphs, since the rest of the subgraphs will appear "behind" the
root graphs. It also attempts to connect to the memcached service to
verify it is infact running.
=cut
if (defined $ARGV[0] && $ARGV[0] eq 'suggest') { if (defined $ARGV[0] && $ARGV[0] eq 'suggest') {
# Lets attempt to connect to memcached
my $s = IO::Socket::INET->new( my $s = get_conn();
Proto => "tcp", # Lets check that we did connect to memcached
PeerAddr => $host,
PeerPort => $port,
);
if (defined($s)) { if (defined($s)) {
my @rootplugins = ('bytes','conns','commands','evictions','items','memory'); my @rootplugins = ('bytes','conns','commands','evictions','items','memory');
foreach my $plugin (@rootplugins) { foreach my $plugin (@rootplugins) {
@ -366,30 +397,29 @@ if (defined $ARGV[0] && $ARGV[0] eq 'suggest') {
} }
} }
## =head1 Output Subroutines
#### Well We aren't running (auto)config/suggest so lets print some stats ####
##
Output Subroutine calls to output data values
=head2 fetch_output
This subroutine is the main call for printing data for the plugin.
No parameters are taken as this is the default call if no arguments
are supplied from the command line.
=cut
# Well, no arguments were supplied that we know about, so lets print some data
fetch_output(); fetch_output();
##
#### Subroutines for printing info gathered from memcached ####
##
##
#### This subroutine performs the bulk processing for printing statistics.
##
sub fetch_output { sub fetch_output {
# Lets get our plugin from the symlink being called up, we'll also verify its a valid
# plugin that we have graph information for
$0 =~ /memcached_multi_(.+)*/; $0 =~ /memcached_multi_(.+)*/;
my $plugin = $1; my $plugin = $1;
die 'Unknown Plugin Specified: ' . ($plugin ? $plugin : '') unless $graphs{$plugin}; die 'Unknown Plugin Specified: ' . ($plugin ? $plugin : '') unless $graphs{$plugin};
# Well we need to actually fetch the stats before we do anything to them. # Well we need to actually fetch the stats before we do anything to them.
fetch_stats(); fetch_stats();
# Now lets go ahead and print out our output. # Now lets go ahead and print out our output.
my @subgraphs; my @subgraphs;
if ($plugin eq 'memory') { if ($plugin eq 'memory') {
@ -423,17 +453,24 @@ sub fetch_output {
return; return;
} }
## =head2 print_root_output
#### This subroutine is for the root non-multigraph graphs which render on the main node page ####
## This block of code prints out the return values for our root graphs. It takes
one parameter $plugin. Returns when completed, this is the non multigraph
output subroutine.
$plugin; graph we are calling up to print data values for
Example: print_root_output($plugin);
=cut
sub print_root_output { sub print_root_output {
# Lets get our plugin, set our graph reference and print out info for Munin
my ($plugin) = (@_); my ($plugin) = (@_);
my $graph = $graphs{$plugin}; my $graph = $graphs{$plugin};
print "graph memcached_$plugin\n"; print "graph memcached_$plugin\n";
# The conns plugin has some specific needs, looking for plugin type
if ($plugin ne 'conns') { if ($plugin ne 'conns') {
foreach my $dsrc (@{$graph->{datasrc}}) { foreach my $dsrc (@{$graph->{datasrc}}) {
my %datasrc = %$dsrc; my %datasrc = %$dsrc;
@ -461,26 +498,33 @@ sub print_root_output {
} }
} }
} }
return; return;
} }
## =head2 print_rootmulti_output
#### This subroutine is for the root multigraph graphs which render on the main node page ####
## This block of code prints out the return values for our root graphs. It takes
one parameter $plugin. Returns when completed, this is the multigraph
output subroutine
$plugin; main(root) graph we are calling up to print data values for
Example: print_rootmulti_output($plugin);
=cut
sub print_rootmulti_output { sub print_rootmulti_output {
# Lets get our plugin, set our graph reference and print out info for Munin
my ($plugin) = (@_); my ($plugin) = (@_);
my $graph = $graphs{$plugin}; my $graph = $graphs{$plugin};
print "multigraph memcached_$plugin\n"; print "multigraph memcached_$plugin\n";
# Lets print our data values with their appropriate name
foreach my $dsrc (@{$graph->{datasrc}}) { foreach my $dsrc (@{$graph->{datasrc}}) {
my $output = 0; my $output = 0;
my %datasrc = %$dsrc; my %datasrc = %$dsrc;
while ( my ($key, $value) = each(%datasrc)) { while ( my ($key, $value) = each(%datasrc)) {
next if ($key ne 'name'); next if ($key ne 'name');
next if (($plugin eq 'evictions') && ($value eq 'reclaimed') && ($stats{version} =~ /1\.4\.[0-2]/));
if (($plugin eq 'evictions') && ($value eq 'evicted_nonzero')) { if (($plugin eq 'evictions') && ($value eq 'evicted_nonzero')) {
foreach my $slabid (sort{$a <=> $b} keys %items) { foreach my $slabid (sort{$a <=> $b} keys %items) {
$output += $items{$slabid}->{evicted_nonzero}; $output += $items{$slabid}->{evicted_nonzero};
@ -491,24 +535,33 @@ sub print_rootmulti_output {
print "$dsrc->{name}.value $output\n"; print "$dsrc->{name}.value $output\n";
} }
} }
return; return;
} }
## =head2 print_submulti_output
#### This subroutine is for the sub multigraph graphs created via the multigraph plugin ####
## This block of code prints out the return values for our root graphs. It takes
three parameters $slabid, $plugin and @subgraphs. Returns when completed, this
is the multigraph output subroutine for our subgraphs
$slabid; slab id that we will use to grab info from and print out
$plugin; main(root) being called, used for multigraph output and slab id
@subgraphs; graphs we are actually trying to print data values for
Example: print_submulti_output($slabid,$plugin,@subgraphs);
=cut
sub print_submulti_output { sub print_submulti_output {
# Lets get our slabid, plugin, and subgraphs
my ($slabid,$plugin,@subgraphs) = (@_); my ($slabid,$plugin,@subgraphs) = (@_);
my $currslab = undef; my $currslab = undef;
# Time to loop over our subgraphs array
foreach my $sgraph (@subgraphs) { foreach my $sgraph (@subgraphs) {
# Lets set our graph reference for quick calling, and print some info for munin
my $graph = $graphs{$sgraph}; my $graph = $graphs{$sgraph};
print "multigraph memcached_$plugin.$sgraph\_$slabid\n"; print "multigraph memcached_$plugin.$sgraph\_$slabid\n";
# Lets figure out what slab info we are trying to call up
if ($plugin eq 'evictions') { if ($plugin eq 'evictions') {
$currslab = $items{$slabid}; $currslab = $items{$slabid};
} elsif ($plugin eq 'memory') { } elsif ($plugin eq 'memory') {
@ -520,11 +573,12 @@ sub print_submulti_output {
} else { } else {
return; return;
} }
# Lets print our data values with their appropriate name
foreach my $dsrc (@{$graph->{datasrc}}) { foreach my $dsrc (@{$graph->{datasrc}}) {
my %datasrc = %$dsrc; my %datasrc = %$dsrc;
while ( my ($key, $value) = each(%datasrc)) { while ( my ($key, $value) = each(%datasrc)) {
next if ($key ne 'name'); next if ($key ne 'name');
next if (($sgraph eq 'slabevics') && ($value eq 'reclaimed') && ($stats{version} =~ /1\.4\.[0-2]/));
my $output = $currslab->{$value}; my $output = $currslab->{$value};
if (($sgraph eq 'slabevictime') || ($sgraph eq 'slabitemtime')) { if (($sgraph eq 'slabevictime') || ($sgraph eq 'slabitemtime')) {
$output = time_scale('data',$output); ; $output = time_scale('data',$output); ;
@ -533,17 +587,23 @@ sub print_submulti_output {
} }
} }
} }
return; return;
} }
## =head1 Config Subroutines
#### Subroutines for printing out config information for graphs ####
##
## These subroutines handle the config portion of munin calls.
#### This subroutine does the bulk printing the config info per graph ####
## =head2 do_config
This is the main call issued assuming we call up config and plugin specified exists
The subroutine takes one parameter $plugin, and returns when completed.
$plugin; main(root) graph being called
Example: do_config($plugin);
=cut
sub do_config { sub do_config {
my ($plugin) = (@_); my ($plugin) = (@_);
@ -579,22 +639,59 @@ sub do_config {
return; return;
} }
## =head2 get_conn
#### This subroutine is for the config info for sub multigraph graphs created via the multigraph plugin ####
## This subroutine returns a socket connection
=cut
sub get_conn {
my $s = undef;
# check if we want to use sockets instead of tcp
my ($sock) = ($host =~ /unix:\/\/(.+)*$/);
if ($sock) {
$s = IO::Socket::UNIX->new(
Peer => $sock
);
} else {
$s = IO::Socket::INET->new(
Proto => "tcp",
PeerAddr => $host,
PeerPort => $port,
Timeout => 10,
);
}
return $s;
}
=head2 print_submulti_config
This subroutine prints out the config information for all of the subgraphs.
It takes three parameters, $slabid, $plugin and @subgraphs, returns when
completed, this is the mutligraph config output for our subgraphs
$slabid; slab id that we will use to grab info from and print out
$plugin; main(root) being called, used for multigraph output and slab id
@subgraphs; graphs we are actually trying to print data values for
Example: print_submulti_config($slabid,$plugin,@subgraphs);
=cut
sub print_submulti_config { sub print_submulti_config {
# Lets get our slabid, plugin, and subgraphs
my ($slabid,$plugin,@subgraphs) = (@_); my ($slabid,$plugin,@subgraphs) = (@_);
my ($slabitems,$slabchnks) = undef; my ($slabitems,$slabchnks) = undef;
# Time to loop over our subgraphs array
foreach my $sgraph (@subgraphs) { foreach my $sgraph (@subgraphs) {
# Lets set our graph reference, and main graph config for easy handling
my $graph = $graphs{$sgraph}; my $graph = $graphs{$sgraph};
my %graphconf = %{$graph->{config}}; my %graphconf = %{$graph->{config}};
# Lets tell munin which graph we are graphing, and what our main graph config info is
print "multigraph memcached_$plugin.$sgraph\_$slabid\n"; print "multigraph memcached_$plugin.$sgraph\_$slabid\n";
while ( my ($key, $value) = each(%graphconf)) { while ( my ($key, $value) = each(%graphconf)) {
if ($key eq 'title') { if ($key eq 'title') {
print "graph_$key $value" . "$slabid" . " ($chnks{$slabid}->{chunk_size} Bytes)\n"; print "graph_$key $value" . "$slabid" . " ($chnks{$slabid}->{chunk_size} Bytes)\n";
@ -605,7 +702,7 @@ sub print_submulti_config {
print "graph_$key $value\n"; print "graph_$key $value\n";
} }
} }
# Lets tell munin about our data values and how to treat them
foreach my $dsrc (@{$graph->{datasrc}}) { foreach my $dsrc (@{$graph->{datasrc}}) {
my %datasrc = %$dsrc; my %datasrc = %$dsrc;
while ( my ($key, $value) = each(%datasrc)) { while ( my ($key, $value) = each(%datasrc)) {
@ -618,25 +715,28 @@ sub print_submulti_config {
return; return;
} }
## =head2 print_rootmulti_config
#### This subroutine is for the config info for root multigraph graphs which render on the main node page ####
## This subroutine prints out the config information for all of the main(root) graphs.
It takes one parameter, $plugin, returns when completed.
$plugin; main(root) graph used for multigraph call
Example: print_rootmulti_config($plugin);
=cut
sub print_rootmulti_config { sub print_rootmulti_config {
# Lets get out plugin, set our graph reference and our graph config info
my ($plugin) = (@_); my ($plugin) = (@_);
die 'Unknown Plugin Specified: ' . ($plugin ? $plugin : '') unless $graphs{$plugin};
my $graph = $graphs{$plugin}; my $graph = $graphs{$plugin};
my %graphconf = %{$graph->{config}}; my %graphconf = %{$graph->{config}};
# Lets tell munin about the graph we are referencing and print the main config
print "multigraph memcached_$plugin\n"; print "multigraph memcached_$plugin\n";
while ( my ($key, $value) = each(%graphconf)) { while ( my ($key, $value) = each(%graphconf)) {
print "graph_$key $value\n"; print "graph_$key $value\n";
} }
# Lets tell munin about our data values and how to treat them
foreach my $dsrc (@{$graph->{datasrc}}) { foreach my $dsrc (@{$graph->{datasrc}}) {
my %datasrc = %$dsrc; my %datasrc = %$dsrc;
while ( my ($key, $value) = each(%datasrc)) { while ( my ($key, $value) = each(%datasrc)) {
@ -644,29 +744,31 @@ sub print_rootmulti_config {
print "$dsrc->{name}.$key $value\n"; print "$dsrc->{name}.$key $value\n";
} }
} }
return; return;
} }
## =head2 print_root_config
#### This subroutine is for the config info for non multigraph graphs which render on the main node page ####
## This subroutine prints out the config information for all of the main(root) graphs.
It takes one parameter, $plugin, returns when completed.
$plugin; main(root) graph used for multigraph call
Example: print_root_config($plugin);
=cut
sub print_root_config { sub print_root_config {
# Lets get our plugin, set our graph reference and our graph config info
my ($plugin) = (@_); my ($plugin) = (@_);
die 'Unknown Plugin Specified: ' . ($plugin ? $plugin : '') unless $graphs{$plugin};
my $graph = $graphs{$plugin}; my $graph = $graphs{$plugin};
my %graphconf = %{$graph->{config}}; my %graphconf = %{$graph->{config}};
# Lets tell munin about the graph we are referencing and print the main config
print "graph memcached_$plugin\n"; print "graph memcached_$plugin\n";
while ( my ($key, $value) = each(%graphconf)) { while ( my ($key, $value) = each(%graphconf)) {
print "graph_$key $value\n"; print "graph_$key $value\n";
} }
# Lets tell munin about our data values and how to treat them
foreach my $dsrc (@{$graph->{datasrc}}) { foreach my $dsrc (@{$graph->{datasrc}}) {
my %datasrc = %$dsrc; my %datasrc = %$dsrc;
while ( my ($key, $value) = each(%datasrc)) { while ( my ($key, $value) = each(%datasrc)) {
@ -674,46 +776,46 @@ sub print_root_config {
print "$dsrc->{name}.$key $value\n"; print "$dsrc->{name}.$key $value\n";
} }
} }
return; return;
} }
## =head1 Misc Subroutines
#### This subroutine actually performs the data fetch for us ####
#### These commands do not lock up Memcache at all #### These subroutines are misc ones, and are referenced inside of the code. They
## should never be called up by Munin.
=head2 fetch_stats
This subroutine fetches the information from memcached and stores it into our
hashes for later referencing throughout the graph. Returns when completed
=cut
sub fetch_stats { sub fetch_stats {
my $s = IO::Socket::INET->new( # Lets try and connect to memcached
Proto => "tcp", my $s = get_conn();
PeerAddr => $host, # Die if we can't establish a connection to memcached
PeerPort => $port,
);
die "Error: Unable to Connect to $host\[:$port\]\n" unless $s; die "Error: Unable to Connect to $host\[:$port\]\n" unless $s;
# Lets print the stats command and store the info from the output
print $s "stats\r\n"; print $s "stats\r\n";
while (my $line = <$s>) { while (my $line = <$s>) {
if ($line =~ /STAT\s(.+?)\s(\d+)/) { if ($line =~ /STAT\s(.+?)\s(.*)/) {
my ($skey,$svalue) = ($1,$2); my ($skey,$svalue) = ($1,$2);
$stats{$skey} = $svalue; $stats{$skey} = $svalue;
} }
last if $line =~ /^END/; last if $line =~ /^END/;
} }
# Lets print the stats settings command and store the info from the output
print $s "stats settings\r\n"; print $s "stats settings\r\n";
while (my $line = <$s>) { while (my $line = <$s>) {
if ($line =~ /STAT\s(.+?)\s(\d+)/) { if ($line =~ /STAT\s(.+?)\s(.*)/) {
my ($skey,$svalue) = ($1,$2); my ($skey,$svalue) = ($1,$2);
$stats{$skey} = $svalue; $stats{$skey} = $svalue;
} }
last if $line =~ /^END/; last if $line =~ /^END/;
} }
# Lets print the stats slabs command and store the info from the output
print $s "stats slabs\r\n"; print $s "stats slabs\r\n";
while (my $line = <$s>) { while (my $line = <$s>) {
if ($line =~ /STAT\s(\d+):(.+)\s(\d+)/) { if ($line =~ /STAT\s(\d+):(.+)\s(\d+)/) {
my ($slabid,$slabkey,$slabvalue) = ($1,$2,$3); my ($slabid,$slabkey,$slabvalue) = ($1,$2,$3);
@ -721,9 +823,8 @@ sub fetch_stats {
} }
last if $line =~ /^END/; last if $line =~ /^END/;
} }
# Lets print the stats items command and store the info from the output
print $s "stats items\r\n"; print $s "stats items\r\n";
while (my $line = <$s>) { while (my $line = <$s>) {
if ($line =~ /STAT\sitems:(\d+):(.+?)\s(\d+)/) { if ($line =~ /STAT\sitems:(\d+):(.+?)\s(\d+)/) {
my ($itemid,$itemkey,$itemvalue) = ($1,$2,$3); my ($itemid,$itemkey,$itemvalue) = ($1,$2,$3);
@ -733,14 +834,23 @@ sub fetch_stats {
} }
} }
## =head2 time_scale
#### This subroutine is to help manage the time_scale settings for the graph
## This subroutine is here for me to adjust the timescale of the time graphs
for last evicted item and age of eldest item in cache.
Please note, after long usage I have noticed these counters may not
be accurate, I believe the developers are aware and have submitted
a patch upstream.
=cut
sub time_scale { sub time_scale {
# Lets get our config option and value to adjust
my ($configopt,$origvalue) = (@_); my ($configopt,$origvalue) = (@_);
my $value; my $value;
# If config is defined, it returns the config info for time scale
# If data is defined, it returns the original value after its been adjusted
if ($configopt eq 'config') { if ($configopt eq 'config') {
if ($timescale == 1) { if ($timescale == 1) {
$value = "Seconds" . $origvalue; $value = "Seconds" . $origvalue;