Repository
Munin (2.0)
Last change
2020-03-15
Graph Categories
Family
manual
Language
Perl
License
GPL-2.0-only

ifx_concurrent_sessions_

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.

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.

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.

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.

Author

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

License

GPLv2

Magic Markers

#%# family=manual
#!@@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 <ralph dot grothe at itdz minus berlin dot de>

=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, <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 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/, <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";