I spent some time reworking the bind9-stats-snmpd.pl script to work with Bind 9.5 and SNMPD 5.4.1. There were several problems that I had to fix. First, the layout of the file changed for the Bind9 stats and the script didn't work with the newer version of SNMPD. I hope that this will help some other folks out.
This script is based on the work of Cory Powers. You can find the rest of the files at
http://uversaconsulting.net/download/bind9-stats-1.0.tar.gz
Code:
#!/usr/bin/perl
#
# Script to parse bind9 stats file for net-snmp snmpd agent
#
# Created By: Cory Powers <cory@uversaconsulting.net>
# Modified By: Jeff Roberson <jroberson@bethelks.edu> 16-Jan-2009
# To work with BIND 9.5.0-P2 and SNMPD 5.4.1
#
#
# Include in snmpd.conf
# pass_persist .1.3.6.1.4.1.2021.55 /usr/bin/perl /usr/local/bin/bind9-stats-snmpd.pl
#
#
# This program requires the SNMP::Extension::PassPersist module from CPAN
#
# cpan SNMP::Extension::PassPersist
#
# This will create the following MIB trees
#
# .1.3.6.1.4.1.2021.55.1 = Indexes
# .1.3.6.1.4.1.2021.55.2 = Names
# .1.3.6.1.4.1.2021.55.3 = Succesful query count
# .1.3.6.1.4.1.2021.55.4 = Failed query count
# .1.3.6.1.4.1.2021.55.5 = NXDOMAIN query count
# .1.3.6.1.4.1.2021.55.6 = NXRRSET query count
# .1.3.6.1.4.1.2021.55.7 = Referred query count
# .1.3.6.1.4.1.2021.55.8 = Recursive query count
#
# To get the global name server stats you would consult the following oids
#
# .1.3.6.1.4.1.2021.55.1.1 = INTEGER: 1
# .1.3.6.1.4.1.2021.55.2.1 = STRING: GLOBAL
# .1.3.6.1.4.1.2021.55.3.1 = INTEGER: 0
# .1.3.6.1.4.1.2021.55.4.1 = INTEGER: 0
# .1.3.6.1.4.1.2021.55.5.1 = INTEGER: 0
# .1.3.6.1.4.1.2021.55.6.1 = INTEGER: 0
# .1.3.6.1.4.1.2021.55.7.1 = INTEGER: 0
# .1.3.6.1.4.1.2021.55.8.1 = INTEGER: 0
#
# If per zone statistics are enabled you will receive a tree like
# the one above for each zone. The string will be the zone name and
# view name with an underscore (_) between them.
#
# mydomain.com_internal - zone = mydomain.com, view = internal
#
#
use SNMP::Extension::PassPersist;
$DEBUG = 0;
$STAT_FILE = "/var/cache/bind/named.stats";
$OID = ".1.3.6.1.4.1.2021.55";
$LOG = "/var/log/bind9-stats.log";
%count_ids = (
"index" => 1,
"name" => 2,
"queries resulted in successful answer" => 3,
"queries resulted in SERVFAIL" => 4,
"queries resulted in NXDOMAIN" => 5,
"queries resulted in nxrrset" => 6,
"queries resulted in non authoritative answer" => 7,
"queries caused recursion" => 8
);
# pass_persist handler setup
my $extsnmp = SNMP::Extension::PassPersist->new(
backend_collect => \&process_stats,
idle_count => 60, # no more than 60 idle cycles
refresh => 245, # refresh every 245 sec
);
sub process_stats{
# If the file doesn't exist, just return.
if (!open(STATS,$STAT_FILE)) {
return;
}
my $counter=0;
my $zone = "";
# A place holder seems to be needed at the top of the tree
$extsnmp->add_oid_entry("$OID.1.0", "integer", "0");
while (<STATS>) {
if (/(.+)\ Name\ Server\ Statistics./) {
$zone="GLOBAL";
}
next if /^[\-\+]/;
next if /^\s*$/;
next if /\[View./;
next if /\[Common./;
if (/\[(.+)\]/) {
$zone=formatzone($1);
}elsif (/^(\s+) (\d+) (.*)$/) {
if(!exists($indexes{$zone}) && $zone ne ""){
$indexes{$zone} = ++$counter;
# Initial population of the OID tree
print("add_oid_entry($OID.1.$counter, 'integer', $counter)\n") if ($DEBUG);
$extsnmp->add_oid_entry("$OID.1.$counter", "integer", $counter);
print("add_oid_entry($OID.2.$counter, 'integer', $zone)\n") if ($DEBUG);
$extsnmp->add_oid_entry("$OID.2.$counter", "string", $zone);
# Acutal values from the stats file will overwrite the zeros
for (my $i=3; $i < 9; $i++) {
print("add_oid_entry($OID.$i.$counter, 'integer', $zone)\n") if ($DEBUG);
$extsnmp->add_oid_entry("$OID.$i.$counter", "integer", 0);
}
}
$INDEX=$indexes{$zone};
$COUNT_ID=$count_ids{$3};
$VALUE=$2;
}else{
next;
}
print(">>add_oid_entry($OID.$COUNT_ID.$INDEX, 'integer', $VALUE)\n") if ($DEBUG && $COUNT_ID > 0);
$extsnmp->add_oid_entry("$OID.$COUNT_ID.$INDEX", "integer", $VALUE) if ($COUNT_ID > 0);
}
close(STATS);
}
sub formatzone{
$input = shift @_;
for ($input) {
s/^\s+//;
s/\s+$//;
s/\s/_/;
}
return $input
}
# run the program
$extsnmp->run;
exit(0);