mirror of
https://github.com/munin-monitoring/contrib.git
synced 2025-07-24 18:07:20 +00:00
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.
209 lines
5 KiB
Perl
Executable file
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));
|
|
}
|