summaryrefslogtreecommitdiff
path: root/bin/named/statschannel.c
diff options
context:
space:
mode:
authorLaMont Jones <lamont@debian.org>2008-05-15 17:19:35 -0600
committerLaMont Jones <lamont@debian.org>2008-05-15 17:19:35 -0600
commit9116158c3091065ed0ddcb569209119ed98b4fed (patch)
treebc186f98afc84adcf396966561da35c8586d664a /bin/named/statschannel.c
parentabd0f5d555ec9d919c33dd7f65ff8de625fb077a (diff)
downloadbind9-9116158c3091065ed0ddcb569209119ed98b4fed.tar.gz
9.5.0rc1
Diffstat (limited to 'bin/named/statschannel.c')
-rw-r--r--bin/named/statschannel.c638
1 files changed, 615 insertions, 23 deletions
diff --git a/bin/named/statschannel.c b/bin/named/statschannel.c
index 3b4bd831..e5b7c338 100644
--- a/bin/named/statschannel.c
+++ b/bin/named/statschannel.c
@@ -14,7 +14,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: statschannel.c,v 1.2.2.4 2008/01/24 02:29:56 jinmei Exp $ */
+/* $Id: statschannel.c,v 1.2.2.9 2008/04/09 22:53:06 tbox Exp $ */
/*! \file */
@@ -23,17 +23,25 @@
#include <isc/buffer.h>
#include <isc/httpd.h>
#include <isc/mem.h>
+#include <isc/once.h>
#include <isc/print.h>
#include <isc/socket.h>
#include <isc/task.h>
+#include <dns/db.h>
+#include <dns/opcode.h>
+#include <dns/rdataclass.h>
+#include <dns/rdatatype.h>
#include <dns/stats.h>
#include <dns/view.h>
+#include <dns/zt.h>
#include <named/log.h>
#include <named/server.h>
#include <named/statschannel.h>
+#include "bind9.xsl.h"
+
struct ns_statschannel {
/* Unlocked */
isc_httpdmgr_t *httpdmgr;
@@ -51,6 +59,190 @@ struct ns_statschannel {
ISC_LINK(struct ns_statschannel) link;
};
+typedef enum { statsformat_file, statsformat_xml } statsformat_t;
+
+typedef struct
+stats_dumparg {
+ statsformat_t type;
+ void *arg; /* type dependent argument */
+ const char **desc; /* used for general statistics */
+ int ncounters; /* used for general statistics */
+} stats_dumparg_t;
+
+static isc_once_t once = ISC_ONCE_INIT;
+
+static void
+generalstat_dump(dns_statscounter_t counter, isc_uint64_t val, void *arg) {
+ stats_dumparg_t *dumparg = arg;
+ FILE *fp;
+#ifdef HAVE_LIBXML2
+ xmlTextWriterPtr writer;
+#endif
+
+ REQUIRE(counter < dumparg->ncounters);
+
+ switch (dumparg->type) {
+ case statsformat_file:
+ fp = dumparg->arg;
+ fprintf(fp, "%20" ISC_PRINT_QUADFORMAT "u %s\n", val,
+ dumparg->desc[counter]);
+ break;
+ case statsformat_xml:
+#ifdef HAVE_LIBXML2
+ writer = dumparg->arg;
+
+ xmlTextWriterStartElement(writer, ISC_XMLCHAR
+ dumparg->desc[counter]);
+ xmlTextWriterWriteFormatString(writer,
+ "%" ISC_PRINT_QUADFORMAT "u",
+ val);
+ xmlTextWriterEndElement(writer);
+#endif
+ break;
+ }
+}
+
+static void
+rdtypestat_dump(dns_rdatastatstype_t type, isc_uint64_t val, void *arg) {
+ char typebuf[64];
+ const char *typestr;
+ stats_dumparg_t *dumparg = arg;
+ FILE *fp;
+#ifdef HAVE_LIBXML2
+ xmlTextWriterPtr writer;
+#endif
+
+ if ((DNS_RDATASTATSTYPE_ATTR(type) & DNS_RDATASTATSTYPE_ATTR_OTHERTYPE)
+ == 0) {
+ dns_rdatatype_format(DNS_RDATASTATSTYPE_BASE(type), typebuf,
+ sizeof(typebuf));
+ typestr = typebuf;
+ } else
+ typestr = "Others";
+
+ switch (dumparg->type) {
+ case statsformat_file:
+ fp = dumparg->arg;
+ fprintf(fp, "%20" ISC_PRINT_QUADFORMAT "u %s\n", val, typestr);
+ break;
+ case statsformat_xml:
+#ifdef HAVE_LIBXML2
+ writer = dumparg->arg;
+
+ xmlTextWriterStartElement(writer, ISC_XMLCHAR "rdtype");
+
+ xmlTextWriterStartElement(writer, ISC_XMLCHAR "name");
+ xmlTextWriterWriteString(writer, ISC_XMLCHAR typestr);
+ xmlTextWriterEndElement(writer); /* name */
+
+ xmlTextWriterStartElement(writer, ISC_XMLCHAR "counter");
+ xmlTextWriterWriteFormatString(writer,
+ "%" ISC_PRINT_QUADFORMAT "u",
+ val);
+ xmlTextWriterEndElement(writer); /* counter */
+
+ xmlTextWriterEndElement(writer); /* rdtype */
+#endif
+ break;
+ }
+}
+
+static void
+rdatasetstats_dump(dns_rdatastatstype_t type, isc_uint64_t val, void *arg) {
+ stats_dumparg_t *dumparg = arg;
+ FILE *fp;
+ char typebuf[64];
+ const char *typestr;
+ isc_boolean_t nxrrset = ISC_FALSE;
+#ifdef HAVE_LIBXML2
+ xmlTextWriterPtr writer;
+#endif
+
+ if ((DNS_RDATASTATSTYPE_ATTR(type) & DNS_RDATASTATSTYPE_ATTR_NXDOMAIN)
+ != 0) {
+ typestr = "NXDOMAIN";
+ } else if ((DNS_RDATASTATSTYPE_ATTR(type) &
+ DNS_RDATASTATSTYPE_ATTR_OTHERTYPE) != 0) {
+ typestr = "Others";
+ } else {
+ dns_rdatatype_format(DNS_RDATASTATSTYPE_BASE(type), typebuf,
+ sizeof(typebuf));
+ typestr = typebuf;
+ }
+
+ if ((DNS_RDATASTATSTYPE_ATTR(type) & DNS_RDATASTATSTYPE_ATTR_NXRRSET)
+ != 0)
+ nxrrset = ISC_TRUE;
+
+ switch (dumparg->type) {
+ case statsformat_file:
+ fp = dumparg->arg;
+ fprintf(fp, "%20" ISC_PRINT_QUADFORMAT "u %s%s\n", val,
+ nxrrset ? "!" : "", typestr);
+ break;
+ case statsformat_xml:
+#ifdef HAVE_LIBXML2
+ writer = dumparg->arg;
+
+ xmlTextWriterStartElement(writer, ISC_XMLCHAR "rrset");
+ xmlTextWriterStartElement(writer, ISC_XMLCHAR "name");
+ xmlTextWriterWriteFormatString(writer, "%s%s",
+ nxrrset ? "!" : "", typestr);
+ xmlTextWriterEndElement(writer); /* name */
+
+ xmlTextWriterStartElement(writer, ISC_XMLCHAR "counter");
+ xmlTextWriterWriteFormatString(writer,
+ "%" ISC_PRINT_QUADFORMAT "u",
+ val);
+ xmlTextWriterEndElement(writer); /* counter */
+
+ xmlTextWriterEndElement(writer); /* rrset */
+#endif
+ break;
+ }
+}
+
+static void
+opcodestat_dump(dns_opcode_t code, isc_uint64_t val, void *arg) {
+ FILE *fp = arg;
+ isc_buffer_t b;
+ char codebuf[64];
+ stats_dumparg_t *dumparg = arg;
+#ifdef HAVE_LIBXML2
+ xmlTextWriterPtr writer;
+#endif
+
+ isc_buffer_init(&b, codebuf, sizeof(codebuf) - 1);
+ dns_opcode_totext(code, &b);
+ codebuf[isc_buffer_usedlength(&b)] = '\0';
+
+ switch (dumparg->type) {
+ case statsformat_file:
+ fp = dumparg->arg;
+ fprintf(fp, "%20" ISC_PRINT_QUADFORMAT "u %s\n", val, codebuf);
+ break;
+ case statsformat_xml:
+#ifdef HAVE_LIBXML2
+ writer = dumparg->arg;
+
+ xmlTextWriterStartElement(writer, ISC_XMLCHAR "opcode");
+
+ xmlTextWriterStartElement(writer, ISC_XMLCHAR "name");
+ xmlTextWriterWriteString(writer, ISC_XMLCHAR codebuf);
+ xmlTextWriterEndElement(writer); /* name */
+
+ xmlTextWriterStartElement(writer, ISC_XMLCHAR "counter");
+ xmlTextWriterWriteFormatString(writer,
+ "%" ISC_PRINT_QUADFORMAT "u",
+ val);
+ xmlTextWriterEndElement(writer); /* counter */
+
+ xmlTextWriterEndElement(writer); /* opcode */
+#endif
+ break;
+ }
+}
+
#ifdef HAVE_LIBXML2
/* XXXMLG below here sucks. */
@@ -58,8 +250,50 @@ struct ns_statschannel {
#define TRY(a) do { result = (a); INSIST(result == ISC_R_SUCCESS); } while(0);
#define TRY0(a) do { xmlrc = (a); INSIST(xmlrc >= 0); } while(0);
-#define NODES 8
-#define SPACES 3
+static isc_result_t
+zone_xmlrender(dns_zone_t *zone, void *arg) {
+ char buf[1024 + 32]; /* sufficiently large for zone name and class */
+ dns_rdataclass_t rdclass;
+ isc_uint32_t serial;
+ xmlTextWriterPtr writer = arg;
+ stats_dumparg_t dumparg;
+ dns_stats_t *zonestats;
+
+ xmlTextWriterStartElement(writer, ISC_XMLCHAR "zone");
+
+ dns_zone_name(zone, buf, sizeof(buf));
+ xmlTextWriterStartElement(writer, ISC_XMLCHAR "name");
+ xmlTextWriterWriteString(writer, ISC_XMLCHAR buf);
+ xmlTextWriterEndElement(writer);
+
+ rdclass = dns_zone_getclass(zone);
+ dns_rdataclass_format(rdclass, buf, sizeof(buf));
+ xmlTextWriterStartElement(writer, ISC_XMLCHAR "rdataclass");
+ xmlTextWriterWriteString(writer, ISC_XMLCHAR buf);
+ xmlTextWriterEndElement(writer);
+
+ serial = dns_zone_getserial(zone);
+ xmlTextWriterStartElement(writer, ISC_XMLCHAR "serial");
+ xmlTextWriterWriteFormatString(writer, "%u", serial);
+ xmlTextWriterEndElement(writer);
+
+ dumparg.type = statsformat_xml;
+ dumparg.arg = writer;
+ dumparg.desc = nsstats_xmldesc;
+ dumparg.ncounters = dns_nsstatscounter_max;
+
+ zonestats = dns_zone_getrequeststats(zone);
+ if (zonestats != NULL) {
+ xmlTextWriterStartElement(writer, ISC_XMLCHAR "counters");
+ dns_generalstats_dump(zonestats, generalstat_dump,
+ &dumparg, DNS_STATSDUMP_VERBOSE);
+ xmlTextWriterEndElement(writer); /* counters */
+ }
+
+ xmlTextWriterEndElement(writer); /* zone */
+
+ return (ISC_R_SUCCESS);
+}
static void
generatexml(ns_server_t *server, int *buflen, xmlChar **buf) {
@@ -70,8 +304,8 @@ generatexml(ns_server_t *server, int *buflen, xmlChar **buf) {
xmlDocPtr doc;
int xmlrc;
dns_view_t *view;
- int i;
- isc_uint64_t counters[DNS_STATS_NCOUNTERS];
+ stats_dumparg_t dumparg;
+ dns_stats_t *cachestats;
isc_time_now(&now);
isc_time_formatISO8601(&ns_g_boottime, boottime, sizeof boottime);
@@ -90,6 +324,10 @@ generatexml(ns_server_t *server, int *buflen, xmlChar **buf) {
TRY0(xmlTextWriterWriteAttribute(writer, ISC_XMLCHAR "version",
ISC_XMLCHAR "1.0"));
+ /* Set common fields for statistics dump */
+ dumparg.type = statsformat_xml;
+ dumparg.arg = writer;
+
/*
* Start by rendering the views we know of here. For each view we
* know of, call its rendering function.
@@ -97,7 +335,43 @@ generatexml(ns_server_t *server, int *buflen, xmlChar **buf) {
view = ISC_LIST_HEAD(server->viewlist);
TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "views"));
while (view != NULL) {
- dns_view_xmlrender(view, writer, ISC_XML_RENDERALL);
+ xmlTextWriterStartElement(writer, ISC_XMLCHAR "view");
+
+ xmlTextWriterStartElement(writer, ISC_XMLCHAR "name");
+ xmlTextWriterWriteString(writer, ISC_XMLCHAR view->name);
+ xmlTextWriterEndElement(writer);
+
+ xmlTextWriterStartElement(writer, ISC_XMLCHAR "zones");
+ dns_zt_apply(view->zonetable, ISC_FALSE, zone_xmlrender,
+ writer);
+ xmlTextWriterEndElement(writer);
+
+ if (view->resquerystats != NULL) {
+ dns_rdatatypestats_dump(view->resquerystats,
+ rdtypestat_dump, &dumparg, 0);
+ }
+
+ if (view->resstats != NULL) {
+ xmlTextWriterStartElement(writer,
+ ISC_XMLCHAR "resstats");
+ dumparg.ncounters = dns_resstatscounter_max;
+ dumparg.desc = resstats_xmldesc; /* auto-generated */
+ dns_generalstats_dump(view->resstats, generalstat_dump,
+ &dumparg, DNS_STATSDUMP_VERBOSE);
+ xmlTextWriterEndElement(writer); /* resstats */
+ }
+
+ cachestats = dns_db_getrrsetstats(view->cachedb);
+ if (cachestats != NULL) {
+ xmlTextWriterStartElement(writer,
+ ISC_XMLCHAR "cache");
+ dns_rdatasetstats_dump(cachestats, rdatasetstats_dump,
+ &dumparg, 0);
+ xmlTextWriterEndElement(writer); /* cache */
+ }
+
+ xmlTextWriterEndElement(writer); /* view */
+
view = ISC_LIST_NEXT(view, link);
}
TRY0(xmlTextWriterEndElement(writer)); /* views */
@@ -117,21 +391,42 @@ generatexml(ns_server_t *server, int *buflen, xmlChar **buf) {
xmlTextWriterStartElement(writer, ISC_XMLCHAR "current-time");
xmlTextWriterWriteString(writer, ISC_XMLCHAR nowstr);
xmlTextWriterEndElement(writer);
- TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "counters"));
- dns_stats_copy(server->querystats, counters);
- for (i = 0; i < DNS_STATS_NCOUNTERS; i++) {
- xmlTextWriterStartElement(writer,
- ISC_XMLCHAR dns_statscounter_names[i]);
- xmlTextWriterWriteFormatString(writer,
- "%" ISC_PRINT_QUADFORMAT "u",
- counters[i]);
- xmlTextWriterEndElement(writer);
- }
- xmlTextWriterEndElement(writer); /* counters */
+
+ TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "requests"));
+ dns_opcodestats_dump(server->opcodestats, opcodestat_dump, &dumparg,
+ 0);
+ xmlTextWriterEndElement(writer); /* requests */
+
+ TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "queries-in"));
+ dns_rdatatypestats_dump(server->rcvquerystats, rdtypestat_dump,
+ &dumparg, 0);
+ xmlTextWriterEndElement(writer); /* queries-in */
+
+ TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "nsstats"));
+ dumparg.desc = nsstats_xmldesc; /* auto-generated in bind9.xsl.h */
+ dumparg.ncounters = dns_nsstatscounter_max;
+ dns_generalstats_dump(server->nsstats, generalstat_dump, &dumparg,
+ DNS_STATSDUMP_VERBOSE);
+ xmlTextWriterEndElement(writer); /* nsstats */
+
+ TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "zonestats"));
+ dumparg.desc = zonestats_xmldesc; /* auto-generated in bind9.xsl.h */
+ dumparg.ncounters = dns_zonestatscounter_max;
+ dns_generalstats_dump(server->zonestats, generalstat_dump, &dumparg,
+ DNS_STATSDUMP_VERBOSE);
+ xmlTextWriterEndElement(writer); /* zonestats */
+
+ xmlTextWriterStartElement(writer, ISC_XMLCHAR "resstats");
+ dumparg.ncounters = dns_resstatscounter_max;
+ dumparg.desc = resstats_xmldesc;
+ dns_generalstats_dump(server->resolverstats, generalstat_dump,
+ &dumparg, DNS_STATSDUMP_VERBOSE);
+ xmlTextWriterEndElement(writer); /* resstats */
+
xmlTextWriterEndElement(writer); /* server */
TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "memory"));
- isc_mem_renderxml(server->mctx, writer);
+ isc_mem_renderxml(writer);
TRY0(xmlTextWriterEndElement(writer)); /* memory */
TRY0(xmlTextWriterEndElement(writer)); /* statistics */
@@ -187,8 +482,6 @@ render_xsl(const char *url, const char *querystring, void *args,
isc_buffer_t *b, isc_httpdfree_t **freecb,
void **freecb_args)
{
-#include "bind9.xsl.h"
-
UNUSED(url);
UNUSED(querystring);
UNUSED(args);
@@ -196,8 +489,8 @@ render_xsl(const char *url, const char *querystring, void *args,
*retcode = 200;
*retmsg = "OK";
*mimetype = "text/xslt+xml";
- isc_buffer_reinit(b, msg, strlen(msg));
- isc_buffer_add(b, strlen(msg));
+ isc_buffer_reinit(b, xslmsg, strlen(xslmsg));
+ isc_buffer_add(b, strlen(xslmsg));
*freecb = NULL;
*freecb_args = NULL;
@@ -249,7 +542,7 @@ destroy_listener(void *arg) {
REQUIRE(listener != NULL);
REQUIRE(!ISC_LINK_LINKED(listener, link));
- /* We don't to have acquire the lock here since it's already unlinked */
+ /* We don't have to acquire the lock here since it's already unlinked */
dns_acl_detach(&listener->acl);
DESTROYLOCK(&listener->lock);
@@ -533,3 +826,302 @@ ns_statschannels_shutdown(ns_server_t *server) {
shutdown_listener(listener);
}
}
+
+/*%
+ * Statistics descriptions. These could be statistically initialized at
+ * compile time, but we configure them run time in the init_desc() function
+ * below so that they'll be less susceptible to counter name changes.
+ * Note that bind9.xsl must still be updated consistently with the counter
+ * numbering.
+ */
+static const char *nsstats_desc[dns_nsstatscounter_max];
+static const char *resstats_desc[dns_resstatscounter_max];
+static const char *zonestats_desc[dns_zonestatscounter_max];
+
+static inline void
+set_desc(int counter, int maxcounter, const char *desc, const char **descs) {
+ REQUIRE(counter < maxcounter);
+ REQUIRE(descs[counter] == NULL);
+
+ descs[counter] = desc;
+}
+
+static void
+init_desc() {
+ int i;
+
+ /* Initialize name server statistics */
+ memset(nsstats_desc, 0,
+ dns_nsstatscounter_max * sizeof(nsstats_desc[0]));
+ set_desc(dns_nsstatscounter_requestv4, dns_nsstatscounter_max,
+ "IPv4 requests received", nsstats_desc);
+ set_desc(dns_nsstatscounter_requestv6, dns_nsstatscounter_max,
+ "IPv6 requests received", nsstats_desc);
+ set_desc(dns_nsstatscounter_edns0in, dns_nsstatscounter_max,
+ "requests with EDNS(0) received", nsstats_desc);
+ set_desc(dns_nsstatscounter_badednsver, dns_nsstatscounter_max,
+ "requests with unsupported EDNS version received",
+ nsstats_desc);
+ set_desc(dns_nsstatscounter_tsigin, dns_nsstatscounter_max,
+ "requests with TSIG received", nsstats_desc);
+ set_desc(dns_nsstatscounter_sig0in, dns_nsstatscounter_max,
+ "requests with SIG(0) received", nsstats_desc);
+ set_desc(dns_nsstatscounter_invalidsig, dns_nsstatscounter_max,
+ "requests with invalid signature", nsstats_desc);
+ set_desc(dns_nsstatscounter_tcp, dns_nsstatscounter_max,
+ "TCP requests received", nsstats_desc);
+ set_desc(dns_nsstatscounter_authrej, dns_nsstatscounter_max,
+ "auth queries rejected", nsstats_desc);
+ set_desc(dns_nsstatscounter_recurserej, dns_nsstatscounter_max,
+ "recursive queries rejected", nsstats_desc);
+ set_desc(dns_nsstatscounter_xfrrej, dns_nsstatscounter_max,
+ "transfer requests rejected", nsstats_desc);
+ set_desc(dns_nsstatscounter_updaterej, dns_nsstatscounter_max,
+ "update requests rejected", nsstats_desc);
+ set_desc(dns_nsstatscounter_response, dns_nsstatscounter_max,
+ "responses sent", nsstats_desc);
+ set_desc(dns_nsstatscounter_truncatedresp, dns_nsstatscounter_max,
+ "truncated responses sent", nsstats_desc);
+ set_desc(dns_nsstatscounter_edns0out, dns_nsstatscounter_max,
+ "responses with EDNS(0) sent", nsstats_desc);
+ set_desc(dns_nsstatscounter_tsigout, dns_nsstatscounter_max,
+ "responses with TSIG sent", nsstats_desc);
+ set_desc(dns_nsstatscounter_sig0out, dns_nsstatscounter_max,
+ "responses with SIG(0) sent", nsstats_desc);
+ set_desc(dns_nsstatscounter_success, dns_nsstatscounter_max,
+ "queries resulted in successful answer", nsstats_desc);
+ set_desc(dns_nsstatscounter_authans, dns_nsstatscounter_max,
+ "queries resulted in authoritative answer", nsstats_desc);
+ set_desc(dns_nsstatscounter_nonauthans, dns_nsstatscounter_max,
+ "queries resulted in non authoritative answer", nsstats_desc);
+ set_desc(dns_nsstatscounter_referral, dns_nsstatscounter_max,
+ "queries resulted in referral answer", nsstats_desc);
+ set_desc(dns_nsstatscounter_nxrrset, dns_nsstatscounter_max,
+ "queries resulted in nxrrset", nsstats_desc);
+ set_desc(dns_nsstatscounter_servfail, dns_nsstatscounter_max,
+ "queries resulted in SERVFAIL", nsstats_desc);
+ set_desc(dns_nsstatscounter_formerr, dns_nsstatscounter_max,
+ "queries resulted in FORMERR", nsstats_desc);
+ set_desc(dns_nsstatscounter_nxdomain, dns_nsstatscounter_max,
+ "queries resulted in NXDOMAIN", nsstats_desc);
+ set_desc(dns_nsstatscounter_recursion, dns_nsstatscounter_max,
+ "queries caused recursion", nsstats_desc);
+ set_desc(dns_nsstatscounter_duplicate, dns_nsstatscounter_max,
+ "duplicate queries received", nsstats_desc);
+ set_desc(dns_nsstatscounter_dropped, dns_nsstatscounter_max,
+ "queries dropped", nsstats_desc);
+ set_desc(dns_nsstatscounter_failure, dns_nsstatscounter_max,
+ "other query failures", nsstats_desc);
+ set_desc(dns_nsstatscounter_xfrdone, dns_nsstatscounter_max,
+ "requested transfers completed", nsstats_desc);
+ set_desc(dns_nsstatscounter_updatereqfwd, dns_nsstatscounter_max,
+ "update requests forwarded", nsstats_desc);
+ set_desc(dns_nsstatscounter_updaterespfwd, dns_nsstatscounter_max,
+ "update responses forwarded", nsstats_desc);
+ set_desc(dns_nsstatscounter_updatefwdfail, dns_nsstatscounter_max,
+ "update forward failed", nsstats_desc);
+ set_desc(dns_nsstatscounter_updatedone, dns_nsstatscounter_max,
+ "updates completed", nsstats_desc);
+ set_desc(dns_nsstatscounter_updatefail, dns_nsstatscounter_max,
+ "updates failed", nsstats_desc);
+ set_desc(dns_nsstatscounter_updatebadprereq, dns_nsstatscounter_max,
+ "updates rejected due to prerequisite failure", nsstats_desc);
+
+ /* Initialize resolver statistics */
+ memset(resstats_desc, 0,
+ dns_resstatscounter_max * sizeof(resstats_desc[0]));
+ set_desc(dns_resstatscounter_queryv4, dns_resstatscounter_max,
+ "IPv4 queries sent", resstats_desc);
+ set_desc(dns_resstatscounter_queryv6, dns_resstatscounter_max,
+ "IPv6 queries sent", resstats_desc);
+ set_desc(dns_resstatscounter_responsev4, dns_resstatscounter_max,
+ "IPv4 responses received", resstats_desc);
+ set_desc(dns_resstatscounter_responsev6, dns_resstatscounter_max,
+ "IPv6 responses received", resstats_desc);
+ set_desc(dns_resstatscounter_nxdomain, dns_resstatscounter_max,
+ "NXDOMAIN received", resstats_desc);
+ set_desc(dns_resstatscounter_servfail, dns_resstatscounter_max,
+ "SERVFAIL received", resstats_desc);
+ set_desc(dns_resstatscounter_formerr, dns_resstatscounter_max,
+ "FORMERR received", resstats_desc);
+ set_desc(dns_resstatscounter_othererror, dns_resstatscounter_max,
+ "other errors received", resstats_desc);
+ set_desc(dns_resstatscounter_edns0fail, dns_resstatscounter_max,
+ "EDNS(0) query failures", resstats_desc);
+ set_desc(dns_resstatscounter_mismatch, dns_resstatscounter_max,
+ "mismatch responses received", resstats_desc);
+ set_desc(dns_resstatscounter_truncated, dns_resstatscounter_max,
+ "truncated responses received", resstats_desc);
+ set_desc(dns_resstatscounter_lame, dns_resstatscounter_max,
+ "lame delegations received", resstats_desc);
+ set_desc(dns_resstatscounter_retry, dns_resstatscounter_max,
+ "query retries", resstats_desc);
+ set_desc(dns_resstatscounter_gluefetchv4, dns_resstatscounter_max,
+ "IPv4 NS address fetches", resstats_desc);
+ set_desc(dns_resstatscounter_gluefetchv6, dns_resstatscounter_max,
+ "IPv6 NS address fetches", resstats_desc);
+ set_desc(dns_resstatscounter_gluefetchv4fail, dns_resstatscounter_max,
+ "IPv4 NS address fetch failed", resstats_desc);
+ set_desc(dns_resstatscounter_gluefetchv6fail, dns_resstatscounter_max,
+ "IPv6 NS address fetch failed", resstats_desc);
+ set_desc(dns_resstatscounter_val, dns_resstatscounter_max,
+ "DNSSEC validation attempted", resstats_desc);
+ set_desc(dns_resstatscounter_valsuccess, dns_resstatscounter_max,
+ "DNSSEC validation succeeded", resstats_desc);
+ set_desc(dns_resstatscounter_valnegsuccess, dns_resstatscounter_max,
+ "DNSSEC NX validation succeeded", resstats_desc);
+ set_desc(dns_resstatscounter_valfail, dns_resstatscounter_max,
+ "DNSSEC validation failed", resstats_desc);
+
+ /* Initialize zone statistics */
+ memset(zonestats_desc, 0,
+ dns_zonestatscounter_max * sizeof(zonestats_desc[0]));
+ set_desc(dns_zonestatscounter_notifyoutv4, dns_zonestatscounter_max,
+ "IPv4 notifies sent", zonestats_desc);
+ set_desc(dns_zonestatscounter_notifyoutv6, dns_zonestatscounter_max,
+ "IPv6 notifies sent", zonestats_desc);
+ set_desc(dns_zonestatscounter_notifyinv4, dns_zonestatscounter_max,
+ "IPv4 notifies received", zonestats_desc);
+ set_desc(dns_zonestatscounter_notifyinv6, dns_zonestatscounter_max,
+ "IPv6 notifies received", zonestats_desc);
+ set_desc(dns_zonestatscounter_notifyrej, dns_zonestatscounter_max,
+ "notifies rejected", zonestats_desc);
+ set_desc(dns_zonestatscounter_soaoutv4, dns_zonestatscounter_max,
+ "IPv4 SOA queries sent", zonestats_desc);
+ set_desc(dns_zonestatscounter_soaoutv6, dns_zonestatscounter_max,
+ "IPv6 SOA queries sent", zonestats_desc);
+ set_desc(dns_zonestatscounter_axfrreqv4, dns_zonestatscounter_max,
+ "IPv4 AXFR requested", zonestats_desc);
+ set_desc(dns_zonestatscounter_axfrreqv6, dns_zonestatscounter_max,
+ "IPv6 AXFR requested", zonestats_desc);
+ set_desc(dns_zonestatscounter_ixfrreqv4, dns_zonestatscounter_max,
+ "IPv4 IXFR requested", zonestats_desc);
+ set_desc(dns_zonestatscounter_ixfrreqv6, dns_zonestatscounter_max,
+ "IPv6 IXFR requested", zonestats_desc);
+ set_desc(dns_zonestatscounter_xfrsuccess, dns_zonestatscounter_max,
+ "transfer requests succeeded", zonestats_desc);
+ set_desc(dns_zonestatscounter_xfrfail, dns_zonestatscounter_max,
+ "transfer requests failed", zonestats_desc);
+
+ /* Sanity check */
+ for (i = 0; i < dns_nsstatscounter_max; i++)
+ INSIST(nsstats_desc[i] != NULL);
+ for (i = 0; i < dns_resstatscounter_max; i++)
+ INSIST(resstats_desc[i] != NULL);
+ for (i = 0; i < dns_zonestatscounter_max; i++)
+ INSIST(zonestats_desc[i] != NULL);
+}
+
+isc_result_t
+ns_stats_dump(ns_server_t *server, FILE *fp) {
+ isc_stdtime_t now;
+ isc_result_t result;
+ dns_view_t *view;
+ dns_zone_t *zone, *next;
+ stats_dumparg_t dumparg;
+
+ RUNTIME_CHECK(isc_once_do(&once, init_desc) == ISC_R_SUCCESS);
+
+ /* Set common fields */
+ dumparg.type = statsformat_file;
+ dumparg.arg = fp;
+
+ isc_stdtime_get(&now);
+ fprintf(fp, "+++ Statistics Dump +++ (%lu)\n", (unsigned long)now);
+
+ fprintf(fp, "++ Incoming Requests ++\n");
+ dns_opcodestats_dump(server->opcodestats, opcodestat_dump, &dumparg, 0);
+
+ fprintf(fp, "++ Incoming Queries ++\n");
+ dns_rdatatypestats_dump(server->rcvquerystats, rdtypestat_dump,
+ &dumparg, 0);
+
+ fprintf(fp, "++ Outgoing Queries ++\n");
+ for (view = ISC_LIST_HEAD(server->viewlist);
+ view != NULL;
+ view = ISC_LIST_NEXT(view, link)) {
+ if (view->resquerystats == NULL)
+ continue;
+ if (strcmp(view->name, "_default") == 0)
+ fprintf(fp, "[View: default]\n");
+ else
+ fprintf(fp, "[View: %s]\n", view->name);
+ dns_rdatatypestats_dump(view->resquerystats, rdtypestat_dump,
+ &dumparg, 0);
+ }
+
+ fprintf(fp, "++ Name Server Statistics ++\n");
+ dumparg.desc = nsstats_desc;
+ dumparg.ncounters = dns_nsstatscounter_max;
+ dns_generalstats_dump(server->nsstats, generalstat_dump, &dumparg, 0);
+ fprintf(fp, "++ Zone Maintenance Statistics ++\n");
+ dumparg.desc = zonestats_desc;
+ dumparg.ncounters = dns_zonestatscounter_max;
+ dns_generalstats_dump(server->zonestats, generalstat_dump, &dumparg, 0);
+
+ fprintf(fp, "++ Resolver Statistics ++\n");
+ fprintf(fp, "[Common]\n");
+ dumparg.desc = resstats_desc;
+ dumparg.ncounters = dns_resstatscounter_max;
+ dns_generalstats_dump(server->resolverstats, generalstat_dump, &dumparg,
+ 0);
+ for (view = ISC_LIST_HEAD(server->viewlist);
+ view != NULL;
+ view = ISC_LIST_NEXT(view, link)) {
+ if (view->resstats == NULL)
+ continue;
+ if (strcmp(view->name, "_default") == 0)
+ fprintf(fp, "[View: default]\n");
+ else
+ fprintf(fp, "[View: %s]\n", view->name);
+ dns_generalstats_dump(view->resstats, generalstat_dump,
+ &dumparg, 0);
+ }
+
+ fprintf(fp, "++ Cache DB RRsets ++\n");
+ for (view = ISC_LIST_HEAD(server->viewlist);
+ view != NULL;
+ view = ISC_LIST_NEXT(view, link)) {
+ dns_stats_t *cachestats;
+
+ cachestats = dns_db_getrrsetstats(view->cachedb);
+ if (cachestats == NULL)
+ continue;
+ if (strcmp(view->name, "_default") == 0)
+ fprintf(fp, "[View: default]\n");
+ else
+ fprintf(fp, "[View: %s]\n", view->name);
+ dns_rdatasetstats_dump(cachestats, rdatasetstats_dump, &dumparg,
+ 0);
+ }
+
+ fprintf(fp, "++ Per Zone Query Statistics ++\n");
+ zone = NULL;
+ for (result = dns_zone_first(server->zonemgr, &zone);
+ result == ISC_R_SUCCESS;
+ next = NULL, result = dns_zone_next(zone, &next), zone = next)
+ {
+ dns_stats_t *zonestats = dns_zone_getrequeststats(zone);
+ if (zonestats != NULL) {
+ char zonename[DNS_NAME_FORMATSIZE];
+
+ dns_name_format(dns_zone_getorigin(zone),
+ zonename, sizeof(zonename));
+ view = dns_zone_getview(zone);
+
+ fprintf(fp, "[%s", zonename);
+ if (strcmp(view->name, "_default") != 0)
+ fprintf(fp, " (view: %s)", view->name);
+ fprintf(fp, "]\n");
+
+ dumparg.desc = nsstats_desc;
+ dumparg.ncounters = dns_nsstatscounter_max;
+ dns_generalstats_dump(zonestats, generalstat_dump,
+ &dumparg, 0);
+ }
+ }
+
+ fprintf(fp, "--- Statistics Dump --- (%lu)\n", (unsigned long)now);
+
+ return (ISC_R_SUCCESS); /* this function currently always succeeds */
+}