root / plugins / other / slapd_ @ 4eb89df7
Historique | Voir | Annoter | Télécharger (8,35 ko)
| 1 |
#!/usr/bin/perl -w |
|---|---|
| 2 |
|
| 3 |
# Copyright Bjorn Ruberg <bjorn@ruberg.no> |
| 4 |
# Licenced under GPL v2 |
| 5 |
# |
| 6 |
# TODO: |
| 7 |
# - Check for OpenLDAP version |
| 8 |
|
| 9 |
# We use one script for all monitoring. |
| 10 |
# This script may be symlinked with several names, all |
| 11 |
# performing different functions: |
| 12 |
# slapd_statistics_bytes |
| 13 |
# slapd_statistics_pdu |
| 14 |
# slapd_statistics_other |
| 15 |
# slapd_connections |
| 16 |
# slapd_waiters |
| 17 |
# slapd_operations |
| 18 |
# slapd_operations_diff |
| 19 |
|
| 20 |
# Magic markers |
| 21 |
#%# family=auto |
| 22 |
#%# capabilities=autoconf suggest |
| 23 |
|
| 24 |
# use strict; |
| 25 |
use Net::LDAP; |
| 26 |
use Data::Dumper; |
| 27 |
|
| 28 |
use vars qw ( $config $param $act $scope $descr $cn $vlabel |
| 29 |
$info $title ); |
| 30 |
|
| 31 |
# Change these to reflect your LDAP ACL. The given DN must have |
| 32 |
# read access to the Monitor branch. |
| 33 |
my $basedn = "cn=Monitor"; |
| 34 |
my $server = "localhost"; |
| 35 |
my $userdn = ($ENV{'binddn'} || '');
|
| 36 |
my $userpw = ($ENV{'bindpw'} || '');
|
| 37 |
|
| 38 |
# Remember: bytes, pdu needs scope=base |
| 39 |
|
| 40 |
# The possible measurements |
| 41 |
my %ops = |
| 42 |
('statistics_bytes'
|
| 43 |
=> {
|
| 44 |
'search' => "cn=Bytes,cn=Statistics", |
| 45 |
'desc' => "The number of bytes sent by the LDAP server.", |
| 46 |
'vlabel' => "Bytes", |
| 47 |
'title' => "Number of bytes sent", |
| 48 |
'info' => "The graph shows the number of bytes sent", |
| 49 |
'scope' => "base" |
| 50 |
}, |
| 51 |
'statistics_pdu' |
| 52 |
=> {
|
| 53 |
'search' => "cn=PDU,cn=Statistics", |
| 54 |
'desc' => "The number of PDUs sent by the LDAP server.", |
| 55 |
'vlabel' => "PDUs", |
| 56 |
'title' => "Number of PDUs sent", |
| 57 |
'info' => "The graph shows the number of PDUs sent", |
| 58 |
'scope' => "base" |
| 59 |
}, |
| 60 |
# Referrals |
| 61 |
'statistics_referrals' |
| 62 |
=> {
|
| 63 |
'search' => "cn=Referrals,cn=Statistics", |
| 64 |
'attrs' => "Referrals", |
| 65 |
'desc' => "The number of Referrals sent by the LDAP server.", |
| 66 |
'vlabel' => "Referrals", |
| 67 |
'title' => "Number of LDAP Referrals", |
| 68 |
'info' => "The graph shows the number of referrals sent", |
| 69 |
'scope' => "base" |
| 70 |
}, |
| 71 |
# Entries |
| 72 |
'statistics_entries' |
| 73 |
=> {
|
| 74 |
'search' => "cn=Entries,cn=Statistics", |
| 75 |
'attrs' => "Entries", |
| 76 |
'desc' => "The number of Entries sent by the LDAP server.", |
| 77 |
'vlabel' => "Entries", |
| 78 |
'title' => "Number of LDAP Entries", |
| 79 |
'info' => "The graph shows the number of entries sent", |
| 80 |
'scope' => "base" |
| 81 |
}, |
| 82 |
# Only read Current and Total |
| 83 |
'connections' |
| 84 |
=> {
|
| 85 |
'search' => 'cn=Connections', |
| 86 |
'filter' => '(|(cn=Current)(cn=Total))', |
| 87 |
'desc' => 'The number of Connections', |
| 88 |
'label' => {'current' => 'Current',
|
| 89 |
'total' => 'Total'}, |
| 90 |
'vlabel' => 'Connections', |
| 91 |
'title' => 'Number of Connections', |
| 92 |
'info' => 'Number of connections to the LDAP server' |
| 93 |
}, |
| 94 |
# dn: cn=Write,cn=Waiters,cn=Monitor |
| 95 |
# dn: cn=Read,cn=Waiters,cn=Monitor |
| 96 |
'waiters' |
| 97 |
=> {
|
| 98 |
'search' => 'cn=Waiters', |
| 99 |
'filter' => '(|(cn=Write)(cn=Read))', |
| 100 |
'desc' => "The number of Waiters|", |
| 101 |
'label' => {'write' => 'Write',
|
| 102 |
'read' => 'Read'}, |
| 103 |
'vlabel' => "Waiters", |
| 104 |
'title' => "Number of Waiters", |
| 105 |
'info' => "The graph shows the number of Waiters" |
| 106 |
}, |
| 107 |
'operations' |
| 108 |
=> {
|
| 109 |
'search' => "cn=Operations", |
| 110 |
'desc' => "Operations", |
| 111 |
'vlabel' => "Operations", |
| 112 |
'title' => "Operations", |
| 113 |
'info' => "Number of completed LDAP operations" |
| 114 |
}, |
| 115 |
'operations_diff' |
| 116 |
=> {
|
| 117 |
'search' => "cn=Operations", |
| 118 |
'desc' => "Operations deviance", |
| 119 |
'vlabel' => "Deviance", |
| 120 |
'title' => "Operations deviance", |
| 121 |
'info' => "Deviance between Initiated and Completed ops" |
| 122 |
} |
| 123 |
); |
| 124 |
|
| 125 |
# Config subroutine |
| 126 |
sub config {
|
| 127 |
my $action = shift; |
| 128 |
print <<EOF; |
| 129 |
graph_args --base 1000 -l 0 --vertical-label $ops{$action}->{'vlabel'}
|
| 130 |
graph_title $ops{$action}->{'title'}
|
| 131 |
graph_category OpenLDAP |
| 132 |
graph_info $ops{$action}->{'info'}
|
| 133 |
EOF |
| 134 |
|
| 135 |
if ($ops{$action}->{'label'}) {
|
| 136 |
while (my ($key, $val) = each (%{$ops{$action}->{'label'}})) {
|
| 137 |
my $name = $action . "_" . $key; |
| 138 |
print "$name.label $val\n"; |
| 139 |
print "$name.type DERIVE\n"; |
| 140 |
print "$name.min 0\n"; |
| 141 |
} |
| 142 |
} elsif ($action =~ /^operations(?:_diff)?$/) {
|
| 143 |
my $ldap = Net::LDAP->new ($server) or die "$@"; |
| 144 |
$ldap->bind ($userdn, password => $userpw) or die "$@"; |
| 145 |
my $searchdn = $ops{$action}->{'search'} . "," . $basedn;
|
| 146 |
my $mesg = |
| 147 |
$ldap->search ( |
| 148 |
base => $searchdn, |
| 149 |
scope => 'one', |
| 150 |
filter => '(objectclass=*)', |
| 151 |
attrs => ['monitorOpInitiated', |
| 152 |
'monitorOpCompleted', |
| 153 |
'cn'], |
| 154 |
); |
| 155 |
$mesg->code && die $mesg->error; |
| 156 |
|
| 157 |
my $max = $mesg->count; |
| 158 |
for (my $i = 0 ; $i < $max ; $i++) {
|
| 159 |
my $entry = $mesg->entry ($i); |
| 160 |
my $cn = $entry->get_value ('cn');
|
| 161 |
$name = $action . "_" . lc ($cn); |
| 162 |
print "$name.label $cn\n"; |
| 163 |
print "$name.type DERIVE\n"; |
| 164 |
print "$name.min 0\n"; |
| 165 |
if ($action eq "operations") {
|
| 166 |
print "$name.info The number of $cn operations\n"; |
| 167 |
} else {
|
| 168 |
print "$name.info The difference between Initiated "; |
| 169 |
print "and Completed operations (should be 0)\n"; |
| 170 |
print "$name.warning 1\n"; |
| 171 |
} |
| 172 |
} |
| 173 |
} else {
|
| 174 |
print "$action.label $ops{$action}->{'vlabel'}\n";
|
| 175 |
print "$action.type DERIVE\n"; |
| 176 |
print "$action.min 0\n"; |
| 177 |
} |
| 178 |
} |
| 179 |
|
| 180 |
if ($ARGV[0]) {
|
| 181 |
if ($ARGV[0] eq 'autoconf') {
|
| 182 |
# Check for Net::LDAP |
| 183 |
if (! eval "require Net::LDAP;") {
|
| 184 |
print "no (Net::LDAP not found)"; |
| 185 |
exit 1; |
| 186 |
} |
| 187 |
# Check for LDAP version 3 |
| 188 |
my $ldap = Net::LDAP->new ($server, version => 3) |
| 189 |
or die "no (Needs LDAPv3)"; |
| 190 |
$ldap->bind ($userdn, password => $userpw) |
| 191 |
or die ("no (Can't log in, check env file)");
|
| 192 |
} elsif ($ARGV[0] eq "config") {
|
| 193 |
if ($0 =~ /slapd_([\w\d_]+)$/) {
|
| 194 |
my $action = $1; |
| 195 |
&config ($1); |
| 196 |
} else {
|
| 197 |
die ("Can't run config without a symlinked name\n");
|
| 198 |
} |
| 199 |
} elsif ($ARGV[0] eq "suggest") {
|
| 200 |
print join ("\n", keys (%ops)), "\n";
|
| 201 |
} |
| 202 |
exit 0; |
| 203 |
} |
| 204 |
|
| 205 |
# We won't run this without parameters. |
| 206 |
die ("Can't run without a symlinked name\n") if $0 =~ /slapd_$/;
|
| 207 |
|
| 208 |
# Default scope for LDAP searches. We'll change to other scopes if |
| 209 |
# necessary. |
| 210 |
$scope = "one"; |
| 211 |
|
| 212 |
# The filename is teh key |
| 213 |
(my $action = $0) =~ s/^.*slapd_([\w\d_]+)$/$1/; |
| 214 |
|
| 215 |
# Net::LDAP variant |
| 216 |
my $ldap = Net::LDAP->new ($server, version => 3) |
| 217 |
or die "$@"; |
| 218 |
$ldap->bind ($userdn,password => $userpw) |
| 219 |
or die "$@"; |
| 220 |
|
| 221 |
my $searchdn = $ops{$action}->{'search'} . "," . $basedn;
|
| 222 |
my $searchattrs; |
| 223 |
|
| 224 |
if ($action =~ /^operations(_diff)?$/) {
|
| 225 |
# We look for different parameters in Operations branch |
| 226 |
$searchattrs = ['monitorOpInitiated', 'monitorOpCompleted', 'cn']; |
| 227 |
} else {
|
| 228 |
$searchattrs = ['monitorCounter', 'cn']; |
| 229 |
} |
| 230 |
|
| 231 |
my $filter; |
| 232 |
if ($ops{$action}->{'filter'}) {
|
| 233 |
$filter = "(&(objectclass=*)" . $ops{$action}->{'filter'} . ")";
|
| 234 |
} else {
|
| 235 |
$filter = "(objectClass=*)"; |
| 236 |
} |
| 237 |
|
| 238 |
if ($ops{$action}->{'scope'}) {
|
| 239 |
$scope = $ops{$action}->{'scope'};
|
| 240 |
} |
| 241 |
|
| 242 |
my $mesg = |
| 243 |
$ldap->search ( |
| 244 |
base => $searchdn, |
| 245 |
scope => $scope, |
| 246 |
filter => $filter, |
| 247 |
attrs => $searchattrs, |
| 248 |
); |
| 249 |
|
| 250 |
$mesg->code && die $mesg->error; |
| 251 |
|
| 252 |
my $max = $mesg->count; |
| 253 |
|
| 254 |
for (my $i = 0 ; $i < $max ; $i++) {
|
| 255 |
my $entry = $mesg->entry ($i); |
| 256 |
my $cn = $entry->get_value('cn');
|
| 257 |
if ($action =~ /operations(_diff)?$/) {
|
| 258 |
if ($1) {
|
| 259 |
my $opsInit = |
| 260 |
$entry->get_value('monitorOpInitiated');
|
| 261 |
my $opsComp = |
| 262 |
$entry->get_value('monitorOpCompleted');
|
| 263 |
print lc ("operations_diff_${cn}.value ");
|
| 264 |
print ($opsInit - $opsComp); |
| 265 |
print "\n"; |
| 266 |
} else {
|
| 267 |
print lc ("operations_${cn}.value ");
|
| 268 |
print $entry->get_value('monitorOpCompleted'),
|
| 269 |
"\n"; |
| 270 |
} |
| 271 |
} else {
|
| 272 |
# Hotfix, must do for now |
| 273 |
if ($action =~ /_/) {
|
| 274 |
print lc ("${action}.value ");
|
| 275 |
} else {
|
| 276 |
print lc ("${action}_${cn}.value ");
|
| 277 |
} |
| 278 |
print $entry->get_value('monitorCounter'), "\n";
|
| 279 |
} |
| 280 |
} |
| 281 |
$ldap->unbind; |
