On Fri, 2009-03-27 at 09:25 -0400, John D. Vo wrote: > What do you guys use to turn this: > --- Statistics Dump --- (1238151600) > +++ Statistics Dump +++ (1238155200) > success 3280261 > referral 363 > nxrrset 745513 > nxdomain 392614 > recursion 1173408 > failure 1115632 > --- Statistics Dump --- (1238155200)
The following works (for me!) with either this (above) format of dump or the richer format used in more recent BIND releases. I'm not certain that the statistics selected for processing in each case correspond exactly. I think they're pretty close. #!/usr/bin/perl -w use strict; use Data::Dumper; my $PROG = $0; $PROG =~ s|.*/||; # Configuration my $Config = { statpath => '/var/named/run', statfilename => 'named.stats', probe => [ qw( /usr/local/sbin/rndc stats ) ], }; my $State = { skip => 0, time => undef, chain => [ { } ], }; my $x; # Result my $MRTGdata = { in => '-1', out => '-1', uptime => '0', name => '0' }; # Check that statpath directory exists $x = $Config->{statpath}; -d $x or die(sprintf("%s: %s: %s\n", $PROG, $!, $x)); # Check that probe binary is a file and executable $x = $Config->{probe}->[0]; (-f $x and -x $x) or die(sprintf("%s: %s: %s\n", $PROG, $!, $x)); # Save current size of file, if it exists my $file = join('/', map { $Config->{$_} } (qw(statpath statfilename))); $State->{skip} = (stat($file))[7] if ( -f $file ); # Save current time $State->{'time'} = time(); # Issue probe open(PROBE, '-|', @{$Config->{probe}}) or die "$PROG: $!\n"; close PROBE; # Collect data open(FILE, '<', $file) or die(sprintf("%s: %s: %s\n", $PROG, $!, $file)); $State->{size} = (stat(FILE))[7]; seek(FILE,$State->{skip},0) if $State->{size} > $State->{skip}; my @stats = <FILE>; close FILE; # Process stats # warn join('', @stats); for ( my ($i, $j, $phase, $stamp, $bucket) = (0, 0, 'IDLE'); $i < scalar(@stats); $i++ ) { my $line = $stats[$i]; if ( $line =~ /^\++\s+Statistics Dump\s+\++\s+\((\d+)\)/ ) { $stamp = $1; if ($stamp >= $State->{time}) { $phase = $stamp; $bucket = $State->{chain}->[++$j] = [ ]; $State->{chain}->[0]->{$phase} = $j; push @$bucket, $i; } } if ($phase eq 'IDLE') { # warn "$PROG: skipping: ", $line; next; } if ( $line =~ /^-+\s+Statistics Dump\s+-+\s+\((\d+)\)/ ) { $stamp = $1; if ($stamp eq $phase) { push @$bucket, $i; $State->{chain}->[0]->{last} = $State->{chain}->[0]->{$phase}; $phase = 'IDLE'; } } } foreach my $chain ( $State->{chain} ) { my $last = $chain->[0]->{last}; last unless defined $last; my ($lo, $hi) = @{$chain->[$last]}; # warn sprintf("%s: scanning lines %d - %d\n", $PROG, $lo, $hi); my $format = ( $stats[++$lo] =~ /^\+/ ) ? 'new' : 'old'; # warn "$PROG: format: $format\n"; # Analyze new format if ($format eq 'new') { $MRTGdata->{in} = 0; $MRTGdata->{out} = 0; my $group = ''; foreach ( @stats[$lo .. $hi] ) { $group = $1 if /^\++ (.*) \++/; next unless $group eq 'Name Server Statistics'; $MRTGdata->{in} += $1 if /\s+(\d+) IPv4 requests received/; $MRTGdata->{out} += $1 if /\s+(\d+) queries resulted in non authoritative answer/; } } # Analyze old format elsif ($format eq 'old') { $MRTGdata->{in} = 0; $MRTGdata->{out} = 0; foreach ( @stats[$lo .. $hi] ) { $MRTGdata->{in} += $1 if /^success (\d+)/; $MRTGdata->{in} += $1 if /^referral (\d+)/; $MRTGdata->{in} += $1 if /^nxrrset (\d+)/; $MRTGdata->{in} += $1 if /^nxdomain (\d+)/; $MRTGdata->{in} += $1 if /^failure (\d+)/; $MRTGdata->{out} += $1 if /^recursion (\d+)/; } } } # Present result as expected by MRTG map { printf "%s\n", $MRTGdata->{$_} } ( qw(in out uptime name) ); print "\n"; _______________________________________________ bind-users mailing list bind-users@lists.isc.org https://lists.isc.org/mailman/listinfo/bind-users