diff options
author | LaMont Jones <lamont@debian.org> | 2008-05-15 17:19:35 -0600 |
---|---|---|
committer | LaMont Jones <lamont@debian.org> | 2008-05-15 17:19:35 -0600 |
commit | 9116158c3091065ed0ddcb569209119ed98b4fed (patch) | |
tree | bc186f98afc84adcf396966561da35c8586d664a /bin/named/statschannel.c | |
parent | abd0f5d555ec9d919c33dd7f65ff8de625fb077a (diff) | |
download | bind9-9116158c3091065ed0ddcb569209119ed98b4fed.tar.gz |
9.5.0rc1
Diffstat (limited to 'bin/named/statschannel.c')
-rw-r--r-- | bin/named/statschannel.c | 638 |
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 */ +} |