summaryrefslogtreecommitdiff
path: root/src/pmdas/named/pmdanamed.pl
diff options
context:
space:
mode:
Diffstat (limited to 'src/pmdas/named/pmdanamed.pl')
-rw-r--r--src/pmdas/named/pmdanamed.pl190
1 files changed, 190 insertions, 0 deletions
diff --git a/src/pmdas/named/pmdanamed.pl b/src/pmdas/named/pmdanamed.pl
new file mode 100644
index 0000000..a0f03ba
--- /dev/null
+++ b/src/pmdas/named/pmdanamed.pl
@@ -0,0 +1,190 @@
+#
+# Copyright (c) 2012 Red Hat.
+# Copyright (c) 2009 Aconex. All Rights Reserved.
+#
+# This program is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by the
+# Free Software Foundation; either version 2 of the License, or (at your
+# option) any later version.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+# for more details.
+#
+
+use strict;
+use warnings;
+use PCP::PMDA;
+
+my $pmda = PCP::PMDA->new('named', 100);
+my @paths = ( '/var/named/chroot/var/named/data', '/var/named/data' );
+my $filename = 'named_stats.txt';
+my $statscmd = 'rdnc stats'; # writes to $paths/$filename
+my ( $statsdir, $statsfile );
+my $interval = 10; # time (in seconds) between runs of $statscmd
+my %values; # hash with all values mapped to metric names
+
+sub named_update
+{
+ #$pmda->log('Updating values in named statistics file');
+ system 'rndc', 'stats';
+}
+
+# Parser formats (PMDA internal numbering scheme):
+# 0: not yet known what ondisk format is
+# 1: bind 8,9.[0-4] (<=rhel5.5)
+# 2: bind 9.5+ (>=rhel5.6)
+my $version = 0;
+
+sub named_parser
+{
+ ( undef, $_ ) = @_;
+
+ #$pmda->log("named_parser got line: $_");
+
+ if (m|^\+\+\+ Statistics Dump \+\+\+ \(\d+\)$|) {
+ $version = 1; # all observed formats have this
+ } elsif (m|^\+\+ Incoming Requests \+\+$|) {
+ $version = 2; # but, new format has this also.
+ }
+
+ if ($version == 2) {
+ if (m|^\s+(\d+) responses sent$|) {
+ $values{'named.nameserver.responses.sent'} = $1;
+ } elsif (m|^\s+(\d+) IPv4 requests received$|) {
+ $values{'named.nameserver.requests.IPv4'} = $1;
+ } elsif (m|^\s+(\d+) queries resulted in successful answer$|) {
+ $values{'named.nameserver.queries.successful'} = $1;
+ } elsif (m|^\s+(\d+) queries resulted in authoritative answer$|) {
+ $values{'named.nameserver.queries.authoritative'} = $1;
+ } elsif (m|^\s+(\d+) queries resulted in non authoritative answer$|) {
+ $values{'named.nameserver.queries.non_authoritative'} = $1;
+ } elsif (m|^\s+(\d+) queries resulted in nxrrset$|) {
+ $values{'named.nameserver.queries.nxrrset'} = $1;
+ } elsif (m|^\s+(\d+) queries resulted in NXDOMAIN$|) {
+ $values{'named.nameserver.queries.nxdomain'} = $1;
+ } elsif (m|^\s+(\d+) queries caused recursion$|) {
+ $values{'named.nameserver.queries.recursion'} = $1;
+ }
+ }
+ elsif ($version == 1) {
+ if (m|^success (\d+)$|) { $values{'named.success'} = $1; }
+ elsif (m|^referral (\d+)$|) { $values{'named.referral'} = $1; }
+ elsif (m|^nxrrset (\d+)$|) { $values{'named.nxrrset'} = $1; }
+ elsif (m|^nxdomain (\d+)$|) { $values{'named.nxdomain'} = $1; }
+ elsif (m|^recursion (\d+)$|) { $values{'named.recursion'} = $1; }
+ elsif (m|^failure (\d+)$|) { $values{'named.failure'} = $1; }
+ }
+}
+
+sub named_metrics
+{
+ my $id = 0;
+
+ open STATS, $statsfile || die "Cannot open statistics file: $statsfile\n";
+ while (<STATS>) { named_parser(undef, $_); }
+ close STATS;
+
+ $pmda->add_metric(pmda_pmid(0,$id++), PM_TYPE_U32, PM_INDOM_NULL,
+ PM_SEM_INSTANT, pmda_units(0,1,0,0,PM_TIME_SEC,0),
+ 'named.interval',
+ 'Time interval between invocations of rndc stats command', '');
+ foreach my $key (sort keys %values) {
+ $pmda->add_metric(pmda_pmid(0,$id++), PM_TYPE_U32, PM_INDOM_NULL,
+ PM_SEM_COUNTER, pmda_units(0,0,1,0,0,PM_COUNT_ONE),
+ $key, '', '');
+ #$pmda->log("named_metrics adding $key metric");
+ }
+}
+
+sub named_fetch_callback
+{
+ my ($cluster, $item, $inst) = @_;
+
+ if ($inst != PM_IN_NULL) { return (PM_ERR_INST, 0); }
+ if ($cluster != 0) { return (PM_ERR_PMID, 0); }
+ if ($item == 0) { return ($interval, 1); }
+
+ my $metric_name = pmda_pmid_name($cluster, $item);
+ my $value = $values{$metric_name};
+ #$pmda->log("named_fetch_callback for $metric_name: $cluster.$item");
+
+ return ($value, 1) if (defined($value));
+ return (PM_ERR_PMID, 0);
+}
+
+# PMDA starts here
+foreach $statsdir ( @paths ) {
+ $statsfile = $statsdir . '/' . $filename;
+ last if ( -f $statsfile );
+}
+die "Cannot find a valid named statistics file\n" unless -f $statsfile;
+named_update(); # push some values into the statistics file
+
+$pmda->set_fetch_callback(\&named_fetch_callback);
+$pmda->add_tail($statsfile, \&named_parser, 0);
+$pmda->add_timer($interval, \&named_update, 0);
+$pmda->set_user('named');
+
+named_metrics(); # fetch/parse the stats file, create metrics
+$pmda->run;
+
+=pod
+
+=head1 NAME
+
+pmdanamed - BIND (named) PMDA
+
+=head1 DESCRIPTION
+
+B<pmdanamed> is a Performance Metrics Domain Agent (PMDA) which
+exports metric values from the BIND DNS server.
+Further details on BIND can be found at http://isc.org/.
+
+=head1 INSTALLATION
+
+If you want access to the names and values for the named performance
+metrics, do the following as root:
+
+ # cd $PCP_PMDAS_DIR/named
+ # ./Install
+
+If you want to undo the installation, do the following as root:
+
+ # cd $PCP_PMDAS_DIR/named
+ # ./Remove
+
+B<pmdanamed> is launched by pmcd(1) and should never be executed
+directly. The Install and Remove scripts notify pmcd(1) when
+the agent is installed or removed.
+
+=head1 FILES
+
+=over
+
+=item /var/named/data/named_stats.txt
+
+statistics file showing values exported from named
+
+=item /var/named/chroot/var/named/data/named_stats.txt
+
+chroot variant of statistics file showing values exported from named
+
+=item $PCP_PMDAS_DIR/named/Install
+
+installation script for the B<pmdanamed> agent
+
+=item $PCP_PMDAS_DIR/named/Remove
+
+undo installation script for the B<pmdanamed> agent
+
+=item $PCP_LOG_DIR/pmcd/named.log
+
+default log file for error messages from B<pmdanamed>
+
+=back
+
+=head1 SEE ALSO
+
+pmcd(1), named.conf(5), named(8).