Modification for Bind 9 graphing

Based upon DNS graph by Nathan Campi and modified for Bind 9.CSIM Logo WelcomeCourses
Faculty, Student, Staff
Projects and reports
Conferences, workshop and seminars
Laboratories and reasearch facilities
Information related to CSIM
Information non-related to CSIM
Address, map, phone, etc.

In his scripts for graphing DNS activity, Nathan is proposing a workaround for Bind 9.The need for a workaround arises because with Bind 8, the statistics kept by named used to include the number of queries received by the server for each type of query, it was easy to retreive the data from the statistics of named to draw the graph; whileBind 9 do not collect such data anymore, they should be collected by logging all the queries and calculating statistics.

Nathan proposes to log the queries to stderr and run named though a shell script; the script will read from stderr.

I don't like that solution because:

While at same time, named knows how to log the queries to a separate file and it includes builtin a mechanism to rotate the file when it reaches a certain size a Perl module like File::Tail knows how to read from a file that get rotated like syslog files or this named quey log file.

The solution I propose decribed bellow.

Log the queries to a file

Configure Bind 9 to log all the queries to a file. In the example bellow, the file is called query-log, it rotates everytime the file grows over 1 MB and named keeps up to three backup versions of the file.

  logging { channel query-log { file "query-log" versions 3 size 1m; }; category queries { query-log; }; ... rest of named logging configuration }; options { querylog yes; ... rest of named options  
Example of named.conf configuration file for Bind 9

There will be up to four files created in named default directory, query-log, query-log.0, query-log.1 and query-log.2. The file that contains the most recent queries is query-log.

Examine the log file and collect statistics

The following Perl script uses the module File::Tail to read the file event when it rotates, it computes the number of queries by type.

The script saves its own PID in the file $pidfile. Upon receiving a hang-up signal, it writes the statistics in the file $dumpfile. The $log_wait_interval is used by File::Tail to set the tick clock when the Perl script should become active and try to read new entries in the log file.

This script should loop indefinitely, it should be launch at boot time (use your prefered method to launch that script).

  #!/usr/local/bin/perl $logfile = "/var/chroot/named/etc/named/query-log"; # where to read the queries $dumpfile="/var/run/bind9_stats_count.dump"; # where to write the statistics $pidfile="/var/run/"; # where to write the PID $log_wait_interval=1; # tick clock for reading the query log file use File::Tail; $SIG{'HUP'}='dump'; open OUT, ">$pidfile"; print OUT $$; close OUT; @query_list=("A", "PTR", "ANY", "MX", "NS", "CNAME", "SOA", "SRV", "AAAA"); sub init{ foreach $i (@query_list) { $query{$i}=0; } } sub dump { # dump the statistics when receiving a HUP signal my $total=0; open OUT, ">$dumpfile"; flock OUT, 2; foreach $i (@query_list) { print OUT "$query{$i} "; $total+=$query{$i}; } print OUT "$total\n"; flock OUT, 8; close OUT; init(); } sub getlogline { # The first time we're called; open the logfile, skip to the end, # and remember the inode we opened. if (!defined($lffd)) { $lffd = File::Tail->new(name=>$logfile, maxinterval=>5, interval=>$log_wait_interval); if (!defined($lffd)) { die "Can't open $logfile\n"; } } return $lffd->read; } init(); while ($line=getlogline) { # regexpr to read a query from the log file next unless $line=~/^client\s+\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\#\d+:\s+query:\s+.*\s+IN\s+([A-Z]+)\s+/; $query{$1}++; }  
The script count_stat should be started at boot time

The script

It corresponds to the script use for Bind 8 on Nathan's page. But to collect the statistics, it only has to send an hang-up signal to the script above and read the data from the file as designed in $dumpfile.

  #!/bin/sh kill -1 `/bin/cat /var/run/` /bin/sleep 2 /bin/cat /var/run/bind9_stats_count.dump  
The script /usr/local/sbin/

This script is called by SNMP in the exact way defined on Nathan's page for Bind 8.

Integration with SMF under Solaris

The following modification has been suggested to me by Robert Jansen from Brussels University:

  To have this e.g. integrated under SMF under Solaris, one can define the start method in the xml. manifest as follows: snip.... <exec_method type='method' name='start' exec='/usr/local/packages/bindstats/count_stat &amp;amp' ..... snip...... but,... the "count_stat" script returns a value where the Solaris SMF facility isn't to happy about,... namely "256" and thinks the script is "offline". By adding "return 0;" at the end of your script, Solaris's SMF will think this service is online. It's a workaround. snip..... init(); while ($line=getlogline) { # regexpr to read a query from the log file next unless $line=~/^client\s+\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\#\d+:\s+query:\s+.*\s+IN\s+([A-Z]+)\s+/; $query{}++; } return 0;  
Integration in SMF under Solaris

CSIM home pageWMailAccount managementCSIM LibraryNetwork test toolsSearch CSIM directories
Contact us: Olivier Nicole CSIM    SET    AIT Last update: Aug 2007