package Collectd::Plugin::LDAP::Monitor;

#
# Use the built-in Monitor (unless your openldap installation doesn't have it) to get stats. This module assumes it's running on the same
# host as slapd and that there are no binds required to get to cn=Monitor for localhost connections, e.g.

# database monitor
#
# access to *
#	by peername.ip=127.0.0.1 read
#	by * none
#
#
# It could certainly be more properly secured but was fine for our installation. Ideas include parameterizing the host, username, pw in collected.conf.
#


use strict;
use Net::LDAP;
use Data::Dumper;
use Collectd qw| :all |;

my $host = "localhost";
my $base = "cn=operations,cn=Monitor";
my $attrs = [ "monitorOpInitiated", "monitorOpCompleted", ];


plugin_register( TYPE_CONFIG, "ldap_monitor", "ldap_monitor_config" );
plugin_register( TYPE_READ, "ldap_monitor", "ldap_monitor_read" );


# Keep collectd from printing warning about no config callback registered
sub ldap_monitor_config {
	return 1;
} # end sub


sub ldap_monitor_read {
	my ( %data_complete, %data_initiated, );

	my $conn = Net::LDAP->new( $host ) or die "$@";

	my $result = $conn->search( base => $base, scope => "sub", filter => "(objectClass=*)", attrs => $attrs, );


	if ( defined $result->{ entries } && ref $result->{ entries } eq 'ARRAY' ) {
		for my $entry ( @{ $result->{ entries } } ) {
			( my $name ) = $entry->dn =~ /^cn=(\S+),cn=Operations,cn=Monitor$/;

			next unless $name;

			my $monitorOpInitiated = $entry->get_value( "monitorOpInitiated" );
			my $monitorOpCompleted = $entry->get_value( "monitorOpCompleted" );

			$data_complete{ $name }		= $monitorOpCompleted;
			$data_initiated{ $name }	= $monitorOpInitiated;
		} # end for
	} else {
		return;
	} # end if


	foreach my $name ( keys %data_complete ) {
		plugin_dispatch_values( { plugin => "ldap_monitor", type => "ldap_ops", type_instance => "completed-$name",
					values => [ $data_complete{ $name }, ] } );
	} # end foreach


	foreach my $name ( keys %data_initiated ) {
		plugin_dispatch_values( { plugin => "ldap_monitor", type => "ldap_ops", type_instance => "initiated-$name",
					values => [ $data_initiated{ $name }, ] } );
	} # end foreach

	return 1;
} # end sub