#!/usr/bin/perl -Tw # Plugin to monitor ZEO load, connected clients and errors/conflicts # # Author: Terry Burton # # Revisions: # # 1.0 2010/07/08 First version # # # Invoke using symlinks to zeo_monitor_ in the form zeo_monitor_{load,clients,errors}_ # # Can be configured manually or by autoconf, for example: # # root@munin:~ munin-node-configure --shell # ln -s /usr/share/munin/plugins/zeo_monitor_ /etc/munin/plugins/zeo_monitor_clients_1 # ln -s /usr/share/munin/plugins/zeo_monitor_ /etc/munin/plugins/zeo_monitor_clients_temp # ln -s /usr/share/munin/plugins/zeo_monitor_ /etc/munin/plugins/zeo_monitor_errors_1 # ln -s /usr/share/munin/plugins/zeo_monitor_ /etc/munin/plugins/zeo_monitor_errors_temp # ln -s /usr/share/munin/plugins/zeo_monitor_ /etc/munin/plugins/zeo_monitor_load_1 # ln -s /usr/share/munin/plugins/zeo_monitor_ /etc/munin/plugins/zeo_monitor_load_temp # # # Configuration variables: # # zeomonitorsock - path to the zeo monitor server socket (default /var/run/zeo/zeo-monitor.sock) # # Parameters: # # config # autoconf # suggest # # Configuration example: # # [zeo_monitor_*] # user root # env.zeomonitorsock /var/run/zeo/zeo-monitor.sock # # Magic markers (optional - used by munin-config and installation # scripts): # #%# family=auto #%# capabilities=autoconf suggest use strict; use Munin::Plugin; use File::Basename; use IO::Socket::UNIX qw(SOCK_STREAM); my $zeomonitorsock = exists $ENV{'zeomonitorsock'} ? $ENV{'zeomonitorsock'} : '/var/run/zeo/zeo-monitor.sock'; ($zeomonitorsock)=$zeomonitorsock=~/(.*)/; if (basename($0) !~ /^zeo_monitor_/) { die qq(Please ensure that the name of the script and it's symlinks starts with "zeo_monitor_"\n); } ############ # autoconf # ############ if (defined $ARGV[0] && $ARGV[0] eq 'autoconf') { # Capture any croaks on the way eval { parse_zeo_monitor(); }; if ( !$@ ) { print "yes\n"; exit 0; } chomp $@; print "no ($@)\n"; exit 0; } ########### # suggest # ########### if (defined $ARGV[0] and $ARGV[0] eq 'suggest') { my @storage_names; eval { @storage_names=parse_zeo_monitor(); }; if ( $@ ) { chomp $@; print "no ($@)\n"; exit 1; } print "clients_$_\nload_$_\nerrors_$_\n" foreach @storage_names; exit 0; } # From now on we require the mode and storage name to be given (my $mode,my $storage_name)=$0=~/zeo_monitor_(.+)_(.+)$/; die qq(Symlink to this script by appending a mode and storage name such as "zeo_monitor_load_temp"\n) unless defined $storage_name; ########## # config # ########## if ( $ARGV[0] and $ARGV[0] eq "config") { print <<"EOF"; graph_title ZEO $mode for storage $storage_name graph_args --base 1000 --lower-limit 0 graph_vlabel events per \${graph_period} graph_category zeo graph_info ZEO performance monitoring EOF if ($mode eq 'clients') { print <new(Type => SOCK_STREAM,Peer => $zeomonitorsock ) or die("Can't connect to socket: $!\n"); my $response=join('',<$socket>); close $socket; # If no storage name is given then return list of all storage names if (!defined $storage_name) { return map {/: (.*)/} (grep /^Storage: /, split(/\n/,$response)); } # Otherwise, read the stats for the given storage name (my $stats)=$response=~/ ( Storage:\ $storage_name\n .*? \n ) \n /sx; my %name_var=( 'Clients' => 'clients', 'Commits' => 'commits', 'Aborts' => 'aborts', 'Loads' => 'loads', 'Stores' => 'stores', 'Conflicts' => 'conflicts', 'Conflicts resolved' => 'conflictsres', ); my %stats=(); foreach (split /\n/, $stats) { (my $name,my $value)=split ': ',$_,2; my $var=$name_var{$name}; next unless $var; $stats{$var}=$value; } return %stats; }