]> git.openstreetmap.org Git - chef.git/blobdiff - cookbooks/munin/files/default/plugins/memcached_
Make replication delay monitoring more reliable
[chef.git] / cookbooks / munin / files / default / plugins / memcached_
index 4ee62294e0852a7cbbe02b328b27f76610ecc7e7..5838cda2a920c4362fca5406cf075ba4c1921544 100755 (executable)
@@ -1,6 +1,7 @@
 #!/usr/bin/perl
 #
-=head1 NAME
+
+=head1 MEMCACHED
 
 Memcached - A Plugin to monitor Memcached Servers
 
@@ -32,20 +33,18 @@ 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. 
+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
 
-The core of this plugin is based on the mysql_ plugin maintained by Kjell-Magne Ãierud
-
-Thanks to dormando as well for putting up with me ;)
+Thanks to dormando for putting up with me ;)
 
 =head1 AUTHOR
 
-Matt West < https://code.google.com/p/memcached-munin-plugin/ >
+Matt West < https://github.com/mhwest13/Memcached-Munin-Plugin >
 
 =head1 LICENSE
 
@@ -53,8 +52,8 @@ GPLv2
 
 =head1 MAGIC MARKERS
 
-    #%# family=manual
-    #%# capabilities=autoconf suggest
+#%# family=auto
+#%# capabilities=autoconf suggest
 
 =cut
 
@@ -63,8 +62,10 @@ 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.
 
@@ -92,88 +93,150 @@ my %graphs;
 
 $graphs{items} = {
     config => {
-        args => '--base 1000 --lower-limit 0',
-        vlabel => 'Items in Memcached',
+        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',
+        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' },
+        {
+            name  => 'total_items',
+            label => 'New Items',
+            min   => '0',
+            type  => 'DERIVE'
+        },
     ],
 };
 
 $graphs{memory} = {
     config => {
-        args => '--base 1024 --lower-limit 0',
-        vlabel => 'Bytes Used',
+        args     => '--base 1024 --lower-limit 0',
+        vlabel   => 'Bytes Used',
         category => 'memcached',
-        title => 'Memory Usage',
-        info => 'This graph shows the memory consumption of 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' },
+        {
+            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',
+        args     => '--base 1000',
+        vlabel   => 'bits in (-) / out (+)',
+        title    => 'Network Traffic',
         category => 'memcached',
-        info => 'This graph shows the network traffic in (-) / out (+) of the machine',
+        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' },
+        {
+            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}',
+        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',
+        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' },
+        { name => 'avg_conns',  label => 'Avg Connections',     min => '0' },
     ],
 };
 
 $graphs{commands} = {
     config => {
-        args => '--base 1000 --lower-limit 0',
-        vlabel => 'Commands per ${graph_period}',
+        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',
+        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' },
+        {
+            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}',
+        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',
+        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' },
+        {
+            name  => 'evictions',
+            label => 'Evictions',
+            info  => 'Cumulative Evictions Across All Slabs',
+            type  => 'DERIVE',
+            min   => '0'
+        },
     ],
 };
 
@@ -181,38 +244,39 @@ $graphs{evictions} = {
 #### Config Check ####
 ##
 
-if (defined $ARGV[0] && $ARGV[0] eq 'config') {
+if ( defined $ARGV[0] && $ARGV[0] eq 'config' ) {
 
-    $0 =~ /memcached_(.+)*/;
-    my $plugin = $1;
+    $0 =~ /(?:([^\/]+)_)?memcached_(.+)$/;
+    my $prefix = $1 ? $1 : '';
+    my $plugin = $2;
 
-    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
     fetch_stats();
 
     # Now lets go ahead and print out our config.
-       do_config($plugin);
-       exit 0;
+    do_config( $prefix, $plugin );
+    exit 0;
 }
 
 ##
 #### Autoconf Check ####
 ##
 
-if (defined $ARGV[0] && $ARGV[0] eq 'autoconf') {
+if ( defined $ARGV[0] && $ARGV[0] eq 'autoconf' ) {
 
-    my $s = IO::Socket::INET->new(
-        Proto    => "tcp",
-        PeerAddr => $host,
-        PeerPort => $port,
-    );
+    # Lets attempt to connect to memcached
+    my $s = get_conn();
 
-    if (defined($s)) {
+    # Lets check that we did connect to memcached
+    if ( defined($s) ) {
         print "yes\n";
         exit 0;
-    } else {
-        print "no (unable to connect to $host\[:$port\])\n";
+    }
+    else {
+        print "no (unable to connect to $connection)\n";
         exit 0;
     }
 }
@@ -221,22 +285,22 @@ if (defined $ARGV[0] && $ARGV[0] eq 'autoconf') {
 #### Suggest Check ####
 ##
 
-if (defined $ARGV[0] && $ARGV[0] eq 'suggest') {
+if ( defined $ARGV[0] && $ARGV[0] eq 'suggest' ) {
 
-    my $s = IO::Socket::INET->new(
-        Proto    => "tcp",
-        PeerAddr => $host,
-        PeerPort => $port,
-    );
+    # Lets attempt to connect to memcached
+    my $s = get_conn();
 
-    if (defined($s)) {
-        my @rootplugins = ('bytes','conns','commands','evictions','items','memory');
+    # 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 $host\[:$port\])\n";
+    }
+    else {
+        print "no (unable to connect to $connection)\n";
         exit 0;
     }
 }
@@ -257,14 +321,16 @@ fetch_output();
 
 sub fetch_output {
 
-    $0 =~ /memcached_(.+)*/;
-    my $plugin = $1;
+    $0 =~ /(?:([^\/]+)_)?memcached_(.+)$/;
+    my $prefix = $1 ? $1 : '';
+    my $plugin = $2;
 
-    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.
     fetch_stats();
-    
+
     # Now lets go ahead and print out our output.
     print_root_output($plugin);
 
@@ -282,25 +348,29 @@ sub print_root_output {
 
     #print "graph memcached_$plugin\n";
 
-    if ($plugin ne 'conns') {
-        foreach my $dsrc (@{$graph->{datasrc}}) {
+    if ( $plugin ne 'conns' ) {
+        foreach my $dsrc ( @{ $graph->{datasrc} } ) {
             my %datasrc = %$dsrc;
-            while ( my ($key, $value) = each(%datasrc)) {
-                next if ($key ne 'name');
+            while ( my ( $key, $value ) = each(%datasrc) ) {
+                next if ( $key ne 'name' );
                 my $output = $stats{$value};
                 print "$dsrc->{name}.value $output\n";
             }
         }
-    } else {
+    }
+    else {
         my $output;
-        foreach my $dsrc (@{$graph->{datasrc}}) {
+        foreach my $dsrc ( @{ $graph->{datasrc} } ) {
             my %datasrc = %$dsrc;
-            while ( my ($key, $value) = each(%datasrc)) {
-                if ($value eq 'curr_conns') {
+            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 {
+                }
+                elsif ( $value eq 'avg_conns' ) {
+                    $output = sprintf( "%02d",
+                        $stats{total_connections} / $stats{uptime} );
+                }
+                else {
                     next;
                 }
                 print "$dsrc->{name}.value $output\n";
@@ -320,8 +390,8 @@ sub print_root_output {
 ##
 
 sub do_config {
-    my ($plugin) = (@_);
-    print_root_config($plugin);
+    my ( $prefix, $plugin ) = (@_);
+    print_root_config( $prefix, $plugin );
 
     return;
 }
@@ -331,24 +401,35 @@ sub do_config {
 ##
 
 sub print_root_config {
-    my ($plugin) = (@_);
+    my ( $prefix, $plugin ) = (@_);
 
-    die 'Unknown Plugin Specified: ' . ($plugin ? $plugin : '') unless $graphs{$plugin};
+    die 'Unknown Plugin Specified: ' . ( $plugin ? $plugin : '' )
+      unless $graphs{$plugin};
 
     my $graph = $graphs{$plugin};
 
-    my %graphconf = %{$graph->{config}};
+    my %graphconf = %{ $graph->{config} };
 
     #print "graph memcached_$plugin\n";
 
-    while ( my ($key, $value) = each(%graphconf)) {
-        print "graph_$key $value\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}}) {
+    foreach my $dsrc ( @{ $graph->{datasrc} } ) {
         my %datasrc = %$dsrc;
-        while ( my ($key, $value) = each(%datasrc)) {
-            next if ($key eq 'name');
+        while ( my ( $key, $value ) = each(%datasrc) ) {
+            next if ( $key eq 'name' );
             print "$dsrc->{name}.$key $value\n";
         }
     }
@@ -356,25 +437,48 @@ sub print_root_config {
     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 = IO::Socket::INET->new(
-        Proto    => "tcp",
-        PeerAddr => $host,
-        PeerPort => $port,
-    );
+    my $s = get_conn();
 
-    die "Error: Unable to Connect to $host\[:$port\]\n" unless $s;
+    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);
+    while ( my $line = <$s> ) {
+        if ( $line =~ /STAT\s(.+?)\s(\d+)/ ) {
+            my ( $skey, $svalue ) = ( $1, $2 );
             $stats{$skey} = $svalue;
         }
         last if $line =~ /^END/;