1
0
Fork 0
mirror of https://github.com/munin-monitoring/contrib.git synced 2025-07-24 18:07:20 +00:00
Munin-Contrib/plugins/network/dns/dnsresponse_
Andreas Perhab eb257a9c3c dnsresponse_: enable verifying responses
add option verify to enable graphing the number of successful responses.
if verify is enabled (default it is not) then a warning is emitted when
we do not get a response for all queries and critical if no query
succeeded.

add option timeout to be able to limit the time the plugin takes for
unresponsive servers. old max time was 75 seconds times 20 (25minutes).
new default max is 30 seconds timeout times 20 (10 minutes). with
setting a timeout of a few seconds this can now be reduced even more.

added warnings if average and or mean get close to the timeout.
2023-07-19 12:37:14 +02:00

209 lines
5 KiB
Perl
Executable file

#!/usr/bin/perl -w
=head1 NAME
dnsresponse - Plugin to monitor DNS resolution times.
"Poor man's smokeping" :)
=head1 APPLICABLE SYSTEMS
Any unix system.
Dependencies:
- Net::DNS: https://metacpan.org/pod/Net::DNS e.g. libnet-dns-perl
=head1 CONFIGURATION
The following shows the default configuration.
[dnsresponse_*]
env.site www.google.com
env.times 20
env.verify no
env.timeout 30
Where the plugin suffix represents the DNS-Server which should be queried.
env.site: which domain-name should be queried.
env.times: how often a value should be queried.
env.verify: yes: check that we get a response back from the server and show the number of verified responses
env.timeout: timeout in seconds to use when querying servers
=head1 INTERPRETATION
The plugin shows the average and median times taken to resolve a site.
=head1 MAGIC MARKERS
#%# family=auto
#%# capabilities=autoconf,suggest
=head1 BUGS
None known.
=head1 VERSION
$Id: dnsresponse_ 61 2009-04-14 09:11:00Z stsimb $
=head1 AUTHOR
Copyright (c) 2009 by Sotiris Tsimbonis.
Copyright (c) 2023 by Andreas Perhab, WT-IO-IT GmbH.
=head1 LICENSE
GPLv2
=cut
#%# family=auto
#%# capabilities=autoconf suggest
use strict;
use warnings;
my $DEBUG = exists $ENV{'MUNIN_DEBUG'} ? $ENV{'MUNIN_DEBUG'} : 0;
my $site = exists $ENV{'site'} ? $ENV{'site'} : "www.google.com";
my $times = exists $ENV{'times'} ? $ENV{'times'} : "20";
my $verify = exists $ENV{'verify'} ? lc($ENV{'verify'}) eq "yes" : 0;
my $timeout = exists $ENV{'timeout'} ? $ENV{'timeout'} : 30;
my $resconf="/etc/resolv.conf";
use File::Basename;
my $basename=basename($0);
my $scriptname;
my $dnsip;
($scriptname, $dnsip) = split("_", $basename);
print "DBG: target dns ip $dnsip\n" if ($DEBUG>0);
if ( defined $ARGV[0] and $ARGV[0] eq "config" ) {
print "graph_title $dnsip DNS response time\n";
print "graph_vlabel milliseconds\n";
print "graph_scale no\n";
print "graph_category dns\n";
print "graph_info Time taken by $dnsip to resolve $site $times times.\n";
print "graph_info Time taken by $dnsip to resolve $site.\n";
#my @val = ("min", "avg", "median", "max");
my @val = ("avg", "median", "stddev");
my $value;
foreach $value ( @val ) {
if ($value eq "stddev") {
print "$value.info Standard deviation (variance).\n";
} else {
print "$value.info $value time taken by $dnsip to resolve $site $times times.\n";
}
print "$value.label $value\n";
# print "$value.type DERIVE\n";
# print "$value.min 0\n";
# print "$value.warning 100\n";
if ($value ne "stddev") {
print "$value.warning ".($timeout*1000)."\n";
}
# print "$value.critical 600\n";
}
if ( $verify ) {
print "verified.label Responses\n";
print "verified.info Number of responses received (sent $times queries)\n";
print "verified.min 0\n";
print "verified.warning $times:\n";
print "verified.critical 1:\n";
}
exit 0;
}
if ( defined $ARGV[0] and $ARGV[0] eq "suggest" ) {
if (-s $resconf) {
open (FILE, "< $resconf") || die "Could not open $resconf: $!\n";
my $line;
while ($line = <FILE>) {
if ($line =~ /^nameserver/) {
my $ns; my $ip;
($ns, $ip) = split(" ", $line);
print "$ip\n";
}
}
exit 0;
} else {
print "ERROR reading $resconf\n";
exit 1;
}
}
use Time::HiRes qw ( gettimeofday tv_interval );
use Net::DNS;
my $res = Net::DNS::Resolver->new(
nameservers => [$dnsip],
recurse => 1,
debug => $DEBUG,
);
# as we send multiple queries a retry in the DNS resolver would multiply the timeout value
$res->retry(0);
# set retrans time and udp timeout to the same time to effectively act as a timeout value
$res->retrans($timeout);
$res->udp_timeout($timeout);
my $i;
my @restimes;
my @verified_answers;
for ($i=1; $i<=$times; $i++) {
my $t0 = [gettimeofday];
my $answer = $res->send($site);
my $elapsed = tv_interval ($t0);
push(@restimes, $elapsed);
print "DBG: count $i elapsed $elapsed\n" if ($DEBUG>0);
if ($verify && $answer && $answer->string =~ /^;; (Answer|Response) received.*/) {
print "DBG: answer verified\n" if ($DEBUG>0);
push(@verified_answers, $answer)
}
}
@restimes=sort(@restimes);
#my $min=$restimes[0]*1000;
my $average=mean(@restimes)*1000;
my $median=median(@restimes)*1000;
my $stddev=std_dev_ref_sum(@restimes)*1000;
#my $max=$restimes[$times-1]*1000;
#print "min.value $min\n";
print "avg.value $average\n";
print "median.value $median\n";
print "stddev.value $stddev\n";
#print "max.value $max\n";
if ($verify) {
print "verified.value " . scalar(@verified_answers) . "\n";
}
sub mean {
my $result;
foreach (@_) { $result += $_ }
return $result / @_;
}
sub median {
my @ar = @_;
my $elements = scalar(@ar);
return $ar[(int($elements-1)/2)];
# if ($elements % 2) {
# return $ar[($elements-1)/2];
# } else {
# return ($ar[($elements-1)/2-0.5]+$ar[($elements-1)/2+0.5])/2;
# }
}
# Standard Deviance function from http://www.linuxjournal.com/article/6540
sub std_dev_ref_sum {
my @ar = @_;
my $elements = scalar @ar;
my $sum = 0;
my $sumsq = 0;
foreach (@ar) {
$sum += $_;
$sumsq += ($_ **2);
}
return sqrt( $sumsq/$elements - (($sum/$elements) ** 2));
}