#!@@PERL@@ -w # -*- perl -*- # =head1 NAME ifx_concurrent_sessions_ - Munin wildcard plug-in that connects to Informix instance and counts number of concurrent sessions from syssqlstat view of sysmaster of instance. =head1 APPLICABLE SYSTEMS Connects over the network to Informix databases. Uses informix commands to connect to the databases so these must be present on the munin-node it runs on. =head1 CONFIGURATION As Informix installations can vary wildly the autoconf may fail. However, it is recommended to let munin-node-configure set the plugin links by e.g. # @@SBINDIR@@/munin-node-configure --families contrib --shell | grep concurrent | sh - Yet, for this plugin to work it is most likely required to grant select to the user the munin-node runs this plugin as. This usually requires to login as user "informix" and execute the following command: $ echo "grant select on syssqlstat to munin as informix" | INFORMIXDIR=/path/to/ifx_base INFORMIXSERVER=inst_name dbaccess sysmaster The value of INFORMIXSERVER usually equals to that of DBSERVERNAME in the $INFORMIXDIR/etc/onconfig file. =head1 BUGS This plugin hangs during autoconf - at least on systems without informix. Therefore capabilities magic marker has been removed. May not autoconfigure correctly as noted above. =head1 AUTHOR Contributed by =head1 LICENSE GPLv2 =head1 MAGIC MARKERS #%# family=manual =cut use strict; use File::Find; # In perl 5 since the start my @infdir; if (@ARGV && $ARGV[0] =~ /autoconf|suggest/) { # Taint mode requires this local $ENV{PATH} = '/bin:/usr/bin'; # First, try lookup in proc table # Note, this will only work if oninit was started with full path # On Linux we could easily retreive INFORMIXDIR from /proc by # tr \\00 \\012 < /proc/$PID/environ | grep INFORMIXDIR # Following ps command should work on Linux and Solaris my $pscmd = 'ps -p `pgrep -P1 oninit -d,` -o ppid= -o args='; # while HP-UX discerns itself once more $pscmd = 'UNIX95= ps -C oninit -o ppid= -o args=' if ($^O =~ /hp-?ux/i); @infdir = map $_->[1], grep $_->[0]==1, map [m|(\d+)\s+(\S+)/bin|], qx($pscmd); # Second, try lookup in filesystem Might also fail if we cannot # run find as root However, an oninit binary must exist somewhere # but for sanity reasons we restrict find to /opt and /usr. Note, # if this aborts with Perl Taint mode errors try removing -T in # shebang unless (@infdir) { no warnings; # to hush single usage of File::Find::name warning File::Find::find(sub { -f $_ && -r _ && /^oninit\z/s && push @infdir, $File::Find::name =~ m[(\S+)/bin]}, qw(/opt /usr)); } if ($ARGV[0] eq 'autoconf') { if (@infdir) { print "yes\n"; exit 0; } else { print "no (Could not find oninit on this host)\n"; exit 0; } } if ($ARGV[0] eq 'suggest') { # Here we need to retreive INFORMIXSERVER # Common Informix installations stick to $INFORMIXDIR/etc/onconfig foreach my $dir (@infdir) { local *ONCONFIG; my $onconfig = "$dir/etc/onconfig"; next unless -f $onconfig && -r _; open ONCONFIG, $onconfig or die "Couldn't open $onconfig\n"; my ($infsrv) = grep /^\s*DBSERVERNAME/sm, ; close ONCONFIG; # The directory separator must be replaced by some shell # immune unusual character Note, munin-run (as probably # munin-node) only permit "." as remaining valid character $dir =~ tr,/,.,; # Store INFORMIXDIR and INFORMIXSERVER in the symlink's # basename This releives the user from having to export # these via plugins.conf entries in matching instance # sections but leads to ugly link names print "$dir.$1\n" if $infsrv =~ /DBSERVERNAME\s+(\S+)/; } } exit 0; } # Retreive vital Informix environment from plugin's name @ENV{qw(INFORMIXDIR INFORMIXSERVER)} = $0 =~ /[^.]+(.+)\.(.+)/; $ENV{INFORMIXDIR} =~ tr,.,/,; $ENV{PATH} = "$ENV{INFORMIXDIR}/bin"; # Plugin's config section if (@ARGV && $ARGV[0] =~ /config/i) { my $config = qq{ graph_title Number of Concurrent Sessions of $ENV{INFORMIXSERVER} graph_category Informix graph_vlabel Number graph_info Number of concurrent sessions to $ENV{INFORMIXSERVER}. Note that a constant value of -1 indicates missing grantsfor the plugin user (often "munin") on syssqlstat view. sessions.label Sessions sessions.type GAUGE }; $config =~ s/^\s+//gm; print $config; exit 0; } #printf "%s\n%s\n", @ENV{qw(INFORMIXDIR INFORMIXSERVER)};exit; # Usually redundant double check #local *SQLHOSTS; #my $SQLHOSTS = "$ENV{INFORMIXDIR}/etc/sqlhosts"; #open SQLHOSTS, $SQLHOSTS or die "Cannot open $SQLHOSTS\n"; #my ($infpar) = map [(split /\s+/, $_)[0,2]], # grep /$IFX_INSTT/, ; #close SQLHOSTS; #$ENV{INFORMIXSERVER} = $infpar->[0]; # Actual SQL statement to count sessions # Could be easily replaced by any other valid Sysmaster query to extend plugin my $query = q{select count(*) from syssqlstat where sqs_dbname != '-';}; local *DBACCESS; open DBACCESS, "echo \"$query\"|dbaccess sysmaster 2>/dev/null|" or die "Cannot open reading pipe from dbaccess\n"; my ($sessions) = grep /^\s*\d+\s*$/sm, ; close DBACCESS; # Of course, we need to subtract our own session. Note, that constant # output of -1 often indicates lack of select grant on syssqlstat view # to the user the munin-node runs this plugin as (usually munin) print 'sessions.value ', $sessions ? --$sessions : 'U', "\n";