Unverified Commit 7a835354 authored by Gavin Brown's avatar Gavin Brown
Browse files

monitor both UDP and TCP, but only write the specified protocol to the stats file

parent 90a1dc37
......@@ -16,9 +16,11 @@ use Sys::Syslog qw(:standard :macros);
use Time::HiRes qw(time sleep);
use threads;
use constant NAME => 'rdnsd';
use vars qw($VERSION $CFILE $DEBUG $HELP $PACKET $CONF @SERVERS $RELOAD $REFRESH $CACHE $STATS $UPDATED);
use vars qw($VERSION $CFILE $DEBUG $HELP $PACKET $CONF @SERVERS $RELOAD $REFRESH $CACHE $STATS $UPDATED @PROTOCOLS);
use strict;
@PROTOCOLS = qw(udp tcp);
$VERSION = '0.10';
$CFILE = sprintf('/etc/%s/%s.conf', NAME, NAME);
......@@ -172,31 +174,35 @@ sub main_loop {
my $t0 = time();
my %threads;
my $threads = {};
foreach my $ns (sort(@SERVERS)) {
#
# resolve nameserver to IP addresses in the main thread
#
my @ips = resolve($ns, $CONF->{'AddressFamily'});
#
# spawn thread
#
$threads{$ns} = threads->create(\&time_query, ($CONF->{'AddressFamily'}, $CONF->{'Protocol'}, , @ips));
foreach my $proto (@PROTOCOLS) {
#
# spawn thread
#
$threads->{$ns}->{$proto} = threads->create(\&time_query, ($CONF->{'AddressFamily'}, $proto, @ips));
}
}
#
# gather threads
#
foreach my $ns (sort(@SERVERS)) {
$STATS->{$ns}->{'count'}++;
foreach my $ns (keys(%{$threads})) {
foreach my $proto (keys(%{$threads->{$ns}})) {
$STATS->{$ns}->{$proto}->{'count'}++;
my $dt = $threads{$ns}->join;
my $dt = $threads->{$ns}->{$proto}->join;
if ($dt) {
$STATS->{$ns}->{'time'} += $dt;
$STATS->{$ns}->{'success'}++;
push(@{$STATS->{$ns}->{'times'}}, $dt);
if ($dt) {
$STATS->{$ns}->{$proto}->{'time'} += $dt;
$STATS->{$ns}->{$proto}->{'success'}++;
push(@{$STATS->{$ns}->{$proto}->{'times'}}, $dt);
}
}
}
......@@ -397,63 +403,64 @@ sub update_stats {
$fh = IO::File->new($CONF->{'StatsFile'}, 'w');
}
foreach my $ns (sort(@SERVERS)) {
foreach my $ns (sort(keys(%{$STATS}))) {
foreach my $proto (keys(%{$STATS->{$ns}})) {
#
# no stats for this server, ignore it
#
next if ($STATS->{$ns}->{$proto}->{'count'} < 1);
#
# no stats for this server, ignore it
#
next if ($STATS->{$ns}->{'count'} < 1);
#
# compute success rate and average RTT
#
my $rate = ($STATS->{$ns}->{$proto}->{'success'} / $STATS->{$ns}->{$proto}->{'count'});
my $time = floor(1000 * $STATS->{$ns}->{$proto}->{'time'} / $STATS->{$ns}->{$proto}->{'count'});
#
# compute success rate and average RTT
#
my $rate = ($STATS->{$ns}->{'success'} / $STATS->{$ns}->{'count'});
my $time = floor(1000 * $STATS->{$ns}->{'time'} / $STATS->{$ns}->{'count'});
my @times = ($rate > 0 ? sort(@{$STATS->{$ns}->{$proto}->{'times'}}) : ());
my @times = ($rate > 0 ? sort(@{$STATS->{$ns}->{'times'}}) : ());
my $ptime;
if ($CONF->{'Percentile'}) {
#
# find the position in the array which corresponds to the percentile
#
my $pos = floor(scalar(@times) * $CONF->{'Percentile'} / 100) - 1;
#
# compute percentile time
#
$ptime = floor(1000 * $times[$pos]);
}
my $ptime;
if ($CONF->{'Percentile'}) {
#
# find the position in the array which corresponds to the percentile
# insert into database
#
my $pos = floor(scalar(@times) * $CONF->{'Percentile'} / 100) - 1;
if ($sth) {
$sth->execute(
lc($CONF->{'NodeID'}),
strftime('%Y-%m-%d %H:%M:%S', localtime($UPDATED)), # times are in the system's configured time zone
strftime('%Y-%m-%d %H:%M:%S', localtime(time())), # times are in the system's configured time zone
lc($ns),
int($CONF->{'AddressFamily'}),
$proto,
int($STATS->{$ns}->{$proto}->{'count'}),
int($STATS->{$ns}->{$proto}->{'success'}),
sprintf('%f', $rate),
int(1000 * min(@times)),
int($time),
int(1000 * max(@times)),
($ptime ? int($ptime) : undef),
);
}
#
# compute percentile time
# write line to file
#
$ptime = floor(1000 * $times[$pos]);
}
if ($fh && $proto eq $CONF->{'Protocol'}) {
my $line = sprintf('%s %0.2f %d', $ns, $rate, $time);
$line .= sprintf(' %d', $ptime) if defined($ptime);
#
# insert into database
#
if ($sth) {
$sth->execute(
lc($CONF->{'NodeID'}),
strftime('%Y-%m-%d %H:%M:%S', localtime($UPDATED)), # times are in the system's configured time zone
strftime('%Y-%m-%d %H:%M:%S', localtime(time())), # times are in the system's configured time zone
lc($ns),
int($CONF->{'AddressFamily'}),
lc($CONF->{'Protocol'}),
int($STATS->{$ns}->{'count'}),
int($STATS->{$ns}->{'success'}),
sprintf('%f', $rate),
int(1000 * min(@times)),
int($time),
int(1000 * max(@times)),
($ptime ? int($ptime) : undef),
);
}
#
# write line to file
#
if ($fh) {
my $line = sprintf('%s %0.2f %d', $ns, $rate, $time);
$line .= sprintf(' %d', $ptime) if defined($ptime);
$fh->print($line."\n");
$fh->print($line."\n");
}
}
}
......@@ -733,7 +740,6 @@ is an example:
Database /var/run/rdnsd/rdnsd.db
Percentile 95
AddressFamily 4
Protocol udp
Loop 3
Timeout 1
Recurse false
......@@ -865,12 +871,6 @@ the servers are identified by name rather than address (or when loaded
from SRV records). If not defined, the default behaviour is to prefer
IPv4.
=head2 C<Protocol (udp|tcp)>
Default: C<udp>
Specify the transport protocol (UDP or TCP) to use.
=head2 C<Loop SECONDS>
Default: C<3>
......@@ -929,12 +929,22 @@ directive.
Default: none
B<Note:> this is a legacy option to provide backwards compatibility with
older versions of C<rdnsd>. It specifies a file to which C<rdnsd> will
write statistics.
This is a legacy option to provide backwards compatibility with older
versions of C<rdnsd>. It specifies a file to which C<rdnsd> will write
statistics.
See L<LEGACY STATISTICS FILE FORMAT> for further information.
=head2 C<Protocol (udp|tcp)>
Default: C<udp>
This is a legacy option to provide backwards compatibility with
older versions of C<rdnsd>. It specifies the transport protocol for
which stats will be written to the statistics file (C<rdnsd> will still
monitor both UDP and TCP and will write stats for both protocols to the
database).
=head1 RELOADING THE CONFIGURATION FILE
C<rdnsd> will reload its configuration if you send it a C<SIGHUP>:
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment