+++ /dev/null
-#!/usr/bin/perl
-#
-
-=head1 MEMCACHED
-
-Memcached - A Plugin to monitor Memcached Servers
-
-=head1 MUNIN CONFIGURATION
-
-[memcached_*]
- env.host 127.0.0.1 *default*
- env.port 11211 *default*
-
-=head2 MUNIN ENVIRONMENT CONFIGURATION EXPLANATION
-
- host = host we are going to monitor
- port = port we are connecting to, in order to gather stats
-
-=head1 NODE CONFIGURATION
-
-Please make sure you can telnet to your memcache servers and issue the
- following commands: stats
-
-Available Graphs contained in this Plugin
-
-bytes => This graphs the current network traffic in and out
-
-commands => This graphs the current commands being issued to the memcache machine.
-
-conns => This graphs the current, max connections as well as avg conns per sec avg conns per sec is derived from total_conns / uptime.
-
-evictions => This graphs the current evictions on the node.
-
-items => This graphs the current items and total items in the memcached node.
-
-memory => This graphs the current and max memory allocation.
-
-The following example holds true for all graphing options in this plugin.
- Example: ln -s /usr/share/munin/plugins/memcached_ /etc/munin/plugins/memcached_bytes
-
-=head1 ACKNOWLEDGEMENTS
-
-Thanks to dormando for putting up with me ;)
-
-=head1 AUTHOR
-
-Matt West < https://github.com/mhwest13/Memcached-Munin-Plugin >
-
-=head1 LICENSE
-
-GPLv2
-
-=head1 MAGIC MARKERS
-
-#%# family=auto
-#%# capabilities=autoconf suggest
-
-=cut
-
-use strict;
-use IO::Socket;
-
-my $host = $ENV{host} || "127.0.0.1";
-my $port = $ENV{port} || 11211;
-my $connection;
-
-my %stats;
-
-# This hash contains the information contained in two memcache commands
-# stats and stats settings.
-
-# 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;
-
-$graphs{items} = {
- config => {
- args => '--base 1000 --lower-limit 0',
- vlabel => 'Items in Memcached',
- category => 'memcached',
- title => 'Items',
- info => 'This graph shows the number of items in use by memcached',
- },
- datasrc => [
- { name => 'curr_items', label => 'Current Items', min => '0' },
- {
- name => 'total_items',
- label => 'New Items',
- min => '0',
- type => 'DERIVE'
- },
- ],
-};
-
-$graphs{memory} = {
- config => {
- args => '--base 1024 --lower-limit 0',
- vlabel => 'Bytes Used',
- category => 'memcached',
- title => 'Memory Usage',
- info => 'This graph shows the memory consumption of memcached',
- },
- datasrc => [
- {
- name => 'limit_maxbytes',
- draw => 'AREA',
- label => 'Maximum Bytes Allocated',
- min => '0'
- },
- {
- name => 'bytes',
- draw => 'AREA',
- label => 'Current Bytes Used',
- min => '0'
- },
- ],
-};
-
-$graphs{bytes} = {
- config => {
- args => '--base 1000',
- vlabel => 'bits in (-) / out (+)',
- title => 'Network Traffic',
- category => 'memcached',
- info =>
-'This graph shows the network traffic in (-) / out (+) of the machine',
- order => 'bytes_read bytes_written',
- },
- datasrc => [
- {
- name => 'bytes_read',
- type => 'DERIVE',
- label => 'Network Traffic coming in (-)',
- graph => 'no',
- cdef => 'bytes_read,8,*',
- min => '0'
- },
- {
- name => 'bytes_written',
- type => 'DERIVE',
- label => 'Traffic in (-) / out (+)',
- negative => 'bytes_read',
- cdef => 'bytes_written,8,*',
- min => '0'
- },
- ],
-};
-
-$graphs{conns} = {
- config => {
- args => '--base 1000 --lower-limit 0',
- vlabel => 'Connections per ${graph_period}',
- category => 'memcached',
- title => 'Connections',
- info =>
-'This graph shows the number of connections being handled by memcached',
- order => 'curr_conns avg_conns',
- },
- datasrc => [
- { name => 'curr_conns', label => 'Current Connections', min => '0' },
- { name => 'avg_conns', label => 'Avg Connections', min => '0' },
- ],
-};
-
-$graphs{commands} = {
- config => {
- args => '--base 1000 --lower-limit 0',
- vlabel => 'Commands per ${graph_period}',
- category => 'memcached',
- title => 'Commands',
- info =>
- 'This graph shows the number of commands being handled by memcached',
- },
- datasrc => [
- {
- name => 'cmd_get',
- type => 'DERIVE',
- label => 'Gets',
- info => 'Cumulative number of retrieval reqs',
- min => '0'
- },
- {
- name => 'cmd_set',
- type => 'DERIVE',
- label => 'Sets',
- info => 'Cumulative number of storage reqs',
- min => '0'
- },
- {
- name => 'get_hits',
- type => 'DERIVE',
- label => 'Get Hits',
- info => 'Number of keys that were requested and found',
- min => '0'
- },
- {
- name => 'get_misses',
- type => 'DERIVE',
- label => 'Get Misses',
- info => 'Number of keys there were requested and not found',
- min => '0'
- },
- ],
-};
-
-$graphs{evictions} = {
- config => {
- args => '--base 1000 --lower-limit 0',
- vlabel => 'Evictions per ${graph_period}',
- category => 'memcached',
- title => 'Evictions',
- info => 'This graph shows the number of evictions per second',
- },
- datasrc => [
- {
- name => 'evictions',
- label => 'Evictions',
- info => 'Cumulative Evictions Across All Slabs',
- type => 'DERIVE',
- min => '0'
- },
- ],
-};
-
-##
-#### Config Check ####
-##
-
-if ( defined $ARGV[0] && $ARGV[0] eq 'config' ) {
-
- $0 =~ /(?:([^\/]+)_)?memcached_(.+)$/;
- my $prefix = $1 ? $1 : '';
- my $plugin = $2;
-
- 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
- fetch_stats();
-
- # Now lets go ahead and print out our config.
- do_config( $prefix, $plugin );
- exit 0;
-}
-
-##
-#### Autoconf Check ####
-##
-
-if ( defined $ARGV[0] && $ARGV[0] eq 'autoconf' ) {
-
- # Lets attempt to connect to memcached
- my $s = get_conn();
-
- # Lets check that we did connect to memcached
- if ( defined($s) ) {
- print "yes\n";
- exit 0;
- }
- else {
- print "no (unable to connect to $connection)\n";
- exit 0;
- }
-}
-
-##
-#### Suggest Check ####
-##
-
-if ( defined $ARGV[0] && $ARGV[0] eq 'suggest' ) {
-
- # Lets attempt to connect to memcached
- my $s = get_conn();
-
- # Lets check that we did connect to memcached
- if ( defined($s) ) {
- my @rootplugins =
- ( 'bytes', 'conns', 'commands', 'evictions', 'items', 'memory' );
- foreach my $plugin (@rootplugins) {
- print "$plugin\n";
- }
- exit 0;
- }
- else {
- print "no (unable to connect to $connection)\n";
- exit 0;
- }
-}
-
-##
-#### Well We aren't running (auto)config/suggest so lets print some stats ####
-##
-
-fetch_output();
-
-##
-#### Subroutines for printing info gathered from memcached ####
-##
-
-##
-#### This subroutine performs the bulk processing for printing statistics.
-##
-
-sub fetch_output {
-
- $0 =~ /(?:([^\/]+)_)?memcached_(.+)$/;
- my $prefix = $1 ? $1 : '';
- my $plugin = $2;
-
- die 'Unknown Plugin Specified: ' . ( $plugin ? $plugin : '' )
- unless $graphs{$plugin};
-
- # Well we need to actually fetch the stats before we do anything to them.
- fetch_stats();
-
- # Now lets go ahead and print out our output.
- print_root_output($plugin);
-
- return;
-}
-
-##
-#### This subroutine is for the root non-multigraph graphs which render on the main node page ####
-##
-
-sub print_root_output {
- my ($plugin) = (@_);
-
- my $graph = $graphs{$plugin};
-
- #print "graph memcached_$plugin\n";
-
- if ( $plugin ne 'conns' ) {
- foreach my $dsrc ( @{ $graph->{datasrc} } ) {
- my %datasrc = %$dsrc;
- while ( my ( $key, $value ) = each(%datasrc) ) {
- next if ( $key ne 'name' );
- my $output = $stats{$value};
- print "$dsrc->{name}.value $output\n";
- }
- }
- }
- else {
- my $output;
- foreach my $dsrc ( @{ $graph->{datasrc} } ) {
- my %datasrc = %$dsrc;
- while ( my ( $key, $value ) = each(%datasrc) ) {
- if ( $value eq 'curr_conns' ) {
- $output = $stats{curr_connections};
- }
- elsif ( $value eq 'avg_conns' ) {
- $output = sprintf( "%02d",
- $stats{total_connections} / $stats{uptime} );
- }
- else {
- next;
- }
- print "$dsrc->{name}.value $output\n";
- }
- }
- }
-
- return;
-}
-
-##
-#### Subroutines for printing out config information for graphs ####
-##
-
-##
-#### This subroutine does the bulk printing the config info per graph ####
-##
-
-sub do_config {
- my ( $prefix, $plugin ) = (@_);
- print_root_config( $prefix, $plugin );
-
- return;
-}
-
-##
-#### This subroutine is for the config info for non multigraph graphs which render on the main node page ####
-##
-
-sub print_root_config {
- my ( $prefix, $plugin ) = (@_);
-
- die 'Unknown Plugin Specified: ' . ( $plugin ? $plugin : '' )
- unless $graphs{$plugin};
-
- my $graph = $graphs{$plugin};
-
- my %graphconf = %{ $graph->{config} };
-
- #print "graph memcached_$plugin\n";
-
- while ( my ( $key, $value ) = each(%graphconf) ) {
- if ( $key eq 'title' ) {
- if ($prefix) {
- print "graph_$key " . ucfirst($prefix) . " $value\n";
- }
- else {
- print "graph_$key $value\n";
- }
- }
- else {
- print "graph_$key $value\n";
- }
- }
-
- foreach my $dsrc ( @{ $graph->{datasrc} } ) {
- my %datasrc = %$dsrc;
- while ( my ( $key, $value ) = each(%datasrc) ) {
- next if ( $key eq 'name' );
- print "$dsrc->{name}.$key $value\n";
- }
- }
-
- return;
-}
-
-##
-#### This subroutine returns a socket connection ####
-##
-
-sub get_conn {
- my $s = undef;
-
- # check if we want to use sockets instead of tcp
- my ($sock) = ( $host =~ /unix:\/\/(.+)$/ );
-
- if ($sock) {
- $connection = "unix:\/\/$sock";
- $s = IO::Socket::UNIX->new( Peer => $sock );
- }
- else {
- $connection = "$host:$port";
- $s = IO::Socket::INET->new(
- Proto => "tcp",
- PeerAddr => $host,
- PeerPort => $port,
- Timeout => 10,
- );
- }
-
- return $s;
-}
-
-##
-#### This subroutine actually performs the data fetch for us ####
-#### These commands do not lock up Memcache at all ####
-##
-
-sub fetch_stats {
- my $s = get_conn();
-
- die "Error: Unable to Connect to $connection\n" unless $s;
-
- print $s "stats\r\n";
-
- while ( my $line = <$s> ) {
- if ( $line =~ /STAT\s(.+?)\s(\d+)/ ) {
- my ( $skey, $svalue ) = ( $1, $2 );
- $stats{$skey} = $svalue;
- }
- last if $line =~ /^END/;
- }
-}