Skip to content

Commit

Permalink
* Add Informix plugin for concurrent session counting contributed by …
Browse files Browse the repository at this point in the history
…Ralph Grothe
  • Loading branch information
Nicolai Langfeldt committed Feb 6, 2008
1 parent f647252 commit cb942df
Showing 1 changed file with 175 additions and 0 deletions.
175 changes: 175 additions & 0 deletions node/node.d/ifx_concurrent_sessions_.in
@@ -0,0 +1,175 @@
#!@@PERL@@ -Tw
#
#%# family=contrib
#%# capabilities=autoconf suggest

=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 VERSION

$Id: $

=head1 BUGS

May not autoconfigure correctly as noted above.

=head1 AUTHOR

Contributed by <ralph dot grothe at itdz minus berlin dot de>

=head1 LICENSE

GPLv2

=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} = '/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 = '/usr/bin/ps -p `/usr/bin/pgrep -P1 oninit -d,` -o ppid= -o args=';
# while HP-UX discerns itself once more
$pscmd = 'UNIX95= /usr/bin/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;
}
else {
print "no (Could not find oninit on this host)\n";
exit 1;
}
}

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, <ONCONFIG>;
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;
}

# 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;
}

#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/, <SQLHOSTS>;
#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, <DBACCESS>;
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";

0 comments on commit cb942df

Please sign in to comment.