#!/usr/bin/perl -w

=pod

=encoding UTF-8

=head1 NAME

slapd_bdb_cache_

=head1 CONFIGURATION

Environment variables:

=over 4

=item dbstat

The full path to a db_stat binary able to
communicate with the LDAP backend BDB
database files. RHEL and friends use
slapd_db_stat, while Debian and such use
e.g. db4.6_stat.

=item dbdir

The full path to the directory where
the LDAP backend BDB database files are.

=item title

(Optional) The plugin's title. Useful if you
have more than one DIT installed.

=item warning

(Optional) A threshold integer value. Triggers
plugin to send warnings if cache percentage
drops below the given value.

=back

=head2 LIMITATIONS

The plugin only checks _one_ database directory. To work
around that, i.e. if you have more than one DIT in your
OpenLDAP, create symlinked files and corresponding entries
in the Munin environment file(s). Note that this will
break autoconf, i.e. autoconf will probably still suggest
a default set of symlinks.

Sample config for multiple database directories:

  [slapd_bdb_cache_*]
  env.dbstat /usr/bin/db4.6_stat

  [slapd_bdb_cache_database1_*]
  env.dbdir /var/lib/ldap/database1

  [slapd_bdb_cache_database2_*]
  env.dbdir /var/lib/ldap/database2

=head1 COPYRIGHT

Bjørn Ruberg <bjorn@ruberg.no> 2005-2009

=head1 LICENSE

GPLv2

=head1 MAGIC MARKERS

 #%# family=auto
 #%# capabilities=autoconf suggest

=cut

use strict;
use vars qw ( $measure $config $dbdir $dbstat $warning);
my $arg = shift (@ARGV);

# Finding db_stat should be done here
$dbstat = ($ENV{'dbstat'} || "/usr/bin/db4.6_stat");

# Also the LDAP database files
$dbdir = ($ENV{'dbdir'} || "/var/lib/ldap");

# And the graph title
my $title = ($ENV{'title'} || '');

# Die if no valid file ending, unless suggest/autoconf.
if ($0 !~ /_(pages|percent)$/) {
    unless ($arg && $arg =~ /^(suggest|autoconf)$/) {
        die ("Plugin must be suffixed with 'percent' or 'pages'. Try running 'munin-node-configure suggest'");
    }
}

# Check file name
if ($0 =~ /_pages$/) {
    $measure = "pages";
} elsif ($0 =~ /_percent$/) {
    $measure = "percent";
}

# Parse command line arguments
if ($arg && $arg eq "config") {
    $config = 1;
} elsif ($arg && $arg eq "autoconf") {
    if (! -x $dbstat) {
	print "no (Can't execute db_stat file '$dbstat')\n";
    } elsif (! -d $dbdir || ! -r $dbdir) {
	print "no (Can't open database directory '$dbdir')";
    } else {
	print "yes\n";
    }
    exit 0;
} elsif ($arg && $arg eq "suggest") {
    print "pages\n";
    print "percent\n";
    exit 0;
}


if ($config) {
    print <<EOF;
graph_title Requested pages found in cache $title
graph_category auth
graph_info Pages found in cache (indexes)
EOF
    if ($measure eq "pages") {
	print <<EOF;
graph_args --base 1000 -l 0
graph_vlabel Cache hits per \${graph_period}
EOF
    } else {
	print <<EOF;
graph_args --base 1000 --upper-limit 100 -l 0 --vertical-label %
graph_vlabel Cache hits (percentage)
EOF
    }
}

my @output = `$dbstat -h $dbdir -m`;
my $file = ""; # "Total";
my $pages = undef;
my $percent = undef;
my $counter = 0;

foreach my $line (@output) {
    chomp $line;
    if ($line =~ /^Pool File\: (.*)$/) {
	$file = $1;
    }
    if ($file &&
	$line =~ /^(\d+)\s+Requested pages found in the cache \((\d+)\%\)/) {
	$pages = $1;
	$percent = $2;
    }
    if ($file && defined ($pages) && defined ($percent)) {
	$file =~ s/\.bdb$//;
	my $val = "slapd_bdb_cache_${measure}_${file}";
	if ($config) {
	    print "$val.label $file\n";
	    if ($measure eq "pages") {
		print "$val.type DERIVE\n";
		print "$val.min 0\n";
                if ($counter == 0) {
                    print "$val.draw AREA\n";
                } else {
                    print "$val.draw STACK\n";
                }
		print "$val.info Number of $file pages found in cache\n";
	    } else {
		print "$val.type GAUGE\n";
		print "$val.info Percentage of $file pages found in cache\n";
		print "$val.warning $warning:\n" if $ENV{'warning'};
	    }
	} else {
	    if ($measure eq "pages") {
                print "$val.value $pages\n";
	    } else {
		print "$val.value $percent\n";
	    }
	}
	$file = "";
	$pages = undef;
	$percent = undef;
	$counter++;
    }
}
