diff --git a/CHANGES b/CHANGES index ce8ebbcaff..66b6b950e8 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,13 @@ +3418. [func] New XML schema (version 3.0) for the statistics channel + adds query type statistics at the zone level, and + flattens the XML tree and uses compressed format to + optimize parsing. Includes new XSL that permits + charting via the Google Charts API on browsers that + support javascript in XSL. The old XML schema has been + deprecated. [RT #30023] + +3417. [placeholder] + 3416. [bug] Named could die on shutdown if running with 128 UDP dispatches per interface. [RT #31743] diff --git a/bin/named/bind9.xsl b/bin/named/bind9.xsl index 1024eba7cf..af046d45f1 100644 --- a/bin/named/bind9.xsl +++ b/bin/named/bind9.xsl @@ -15,357 +15,535 @@ - PERFORMANCE OF THIS SOFTWARE. --> - - - - + + + + + + + + - BIND 9 Statistics + + ISC BIND 9 Statistics -
-

Bind 9 Configuration and Statistics

-
- -
- - - - - - - - - - - -
Times
boot-time
current-time
- -
- - - - - - - - - -
Incoming Requests
- -
- - - - - - - - - -
Incoming Queries
- -
- - - - - - - - - - - - -
Outgoing Queries from View
-
-
- -
- -
-

Server Statistics

- -
-
-
-
-
-
-
- -
-

Zone Maintenance Statistics

- -
-
-
-
-
-
-
- -
-

Resolver Statistics (Common)

- -
-
-
-
-
-
-
- - -
-

Resolver Statistics for View

- -
-
-
-
-
-
-
-
- -
- -
-

ADB Statistics (Common)

- -
-
-
-
-
-
-
- - -
-

ADB Statistics for View

- -
-
-
-
-
-
-
-
- -
- - - - - - - - - - - - -
Cache Statistics for View
-
-
- - - - - - - - - - - - -
Cache DB RRsets for View
-
-
- -
-

Socket I/O Statistics

- -
-
-
-
-
-
-
- -
- - - - - +
+

ISC Bind 9 Configuration and Statistics

+
+
+

Server Times

+
Zones for View
+ + + + + + + + +
Boot time: + +
Sample time: + +
+
+

Incoming Requests

+ + +
[graph incoming requests]
+
+ + + + + + - - - - - - - - - - - + + + + + +
+ + + +
NameClassSerialSuccessReferralNXRRSETNXDOMAINFailureXfrReqDoneXfrRej
Total: + +
+
+

Incoming Queries by Type

+ + +
[graph incoming qtypes]
+
+ + + + + + even + odd + + + + + - - + + + + + +
+ + + +
Total: + +
+
+

Outgoing Queries per view

+ +

View

+ + + + + + +
+ + + + + + + even + odd + + + + - - - - - - - - -
+ + - - - - - - - - - - - - - - - - - - - +

- +

Server Statistics

+ + + +
+ + + + + + + even + odd + + + + + + + +
+ + + +

+

Zone Maintenance Statistics

+ + + +
+ + + + + + + even + odd + + + + + + + +
+ + + +
+

Resolver Statistics (Common)

+ + + + + + even + odd + + + + + + + +
+ + + +
+ +

Resolver Statistics for View

+ + + + + + even + odd + + + + + + + +
+ + + +
+
+

Cache DB RRsets for View

+ + + + + + even + odd + + + + + + + +
+ + + +
+
+
+

Socket I/O Statistics

+ + + + + even + odd + + + + + + + +
+ + + +
+
+
+

Response Codes per view/zone

+ +

View

+ + + + + +

Zone

+ + + + + + +
+ + + + + + + even + odd + + + + + + + +
+ + + +
+ + + +

Received QTYPES per view/zone

+ +

View

+ + + + + +

Zone

+ + + + + + +
+ + + + + + + even + odd + + + + + + + +
+ + + +
+ + + +

Network Status

+ + - + @@ -373,7 +551,14 @@ div.statcounter br { - + + + + even + odd + + + @@ -401,56 +586,52 @@ div.statcounter br {
IDNameName Type References LocalAddressState

- - - - - - +

Task Manager Configuration

+
Task Manager Configuration
Thread-Model
+ + - - + + - - + + - - + + - - - -
Thread-Model
Worker Threads
Worker Threads
Default Quantum
Default Quantum
Tasks Running
Tasks Running
Tasks Ready - -

- - - - - +

Tasks

+
Tasks
+ - - + + + + even + odd + + + @@ -466,77 +647,88 @@ div.statcounter br { + + +
ID Name References State QuantumEvents
+
+

Memory Usage Summary

+ + + + + even + odd + + + +
+ + - +
-
- - - +
+

Memory Contexts

+
Memory Usage Summary
+ + + + + + + + + + + - - - - - - -
IDNameReferencesTotalUseInUseMaxUseBlockSizePoolsHiWaterLoWater
-
- - - - - - - - - - - - - - - - - - - + + + + + even + odd + + + + - - - - - - - - - - -
Memory Contexts
IDNameReferencesTotalUseInUseMaxUseBlockSizePoolsHiWaterLoWater
- -
+ + - - - - - - - - - - - - - - - -
- + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ diff --git a/bin/named/bind9.xsl.h b/bin/named/bind9.xsl.h index 946d907614..c6042c7a5f 100644 --- a/bin/named/bind9.xsl.h +++ b/bin/named/bind9.xsl.h @@ -1,11 +1,11 @@ /* * Generated by convertxsl.pl 1.14 2008/07/17 23:43:26 jinmei Exp - * From bind9.xsl 1.21 2009/01/27 23:47:54 tbox Exp + * From \n" - "\n" "\n" - "\n" - "\n" - " \n" + "\n" + " \n" + " \n" " \n" " \n" + " \n" + " \n" + " \n" + " \n" " \n" - " BIND 9 Statistics\n" + " ISC BIND 9 Statistics\n" " \n" " \n" "
\n" - "

Bind 9 Configuration and Statistics

\n" + "

ISC Bind 9 Configuration and Statistics

\n" "
\n" - "\n" - "
\n" - "\n" - " \n" - " \n" - " \n" - " \n" - " \n" + "
\n" + "

Server Times

\n" + "
Times
boot-time
\n" + " \n" + " \n" + " \n" " \n" - " \n" - " \n" - " \n" + " \n" + " \n" + " \n" " \n" "
Boot time:\n" + " \n" + "
current-time
Sample time:\n" + " \n" + "
\n" - "\n" "
\n" - "\n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" + "

Incoming Requests

\n" + " \n" + " \n" + "
[graph incoming requests]
\n" + "
\n" + "
Incoming Requests
\n" + " \n" + " \n" + " \n" + " \n" + " \n" " \n" " \n" + " \n" + " \n" + " \n" + " \n" "
\n" + " \n" + " \n" + " \n" + "
Total:\n" + " \n" + "
\n" - "\n" "
\n" - "\n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" + "

Incoming Queries by Type

\n" + " \n" + " \n" + "
[graph incoming qtypes]
\n" + "
\n" + "
Incoming Queries
\n" + " \n" + " \n" + " \n" + " \n" + " even\n" + " odd\n" + " \n" + " \n" + " \n" + " \n" + " \n" " \n" " \n" - "
\n" + " \n" + " \n" + " \n" + "
\n" - "\n" - "
\n" - "\n" - " \n" - " \n" - " \n" - " \n" + " \n" + " \n" + " \n" " \n" - " \n" - " \n" - " \n" - " \n" + "
Outgoing Queries from View
Total:\n" + " \n" + "
\n" + "
\n" + "

Outgoing Queries per view

\n" + " \n" + "

View

\n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + "
\n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " even\n" + " odd\n" + " \n" + " \n" + " \n" + " \n" + " \n" " \n" " \n" "
\n" + " \n" + " \n" + " \n" + "
\n" "
\n" " \n" - "\n" - "
\n" - "\n" - "
\n" "

Server Statistics

\n" - " \n" - "
\n" - "
\n" - "
\n" - "
\n" + " \n" + " \n" + " \n" + "
\n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " even\n" + " odd\n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" " \n" + "
\n" + " \n" + " \n" + " \n" + "
\n" "
\n" - "
\n" - "\n" - "
\n" "

Zone Maintenance Statistics

\n" - " \n" - "
\n" - "
\n" - "
\n" - "
\n" - "
\n" - "
\n" - "
\n" + " \n" + " \n" + " \n" + "
\n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " even\n" + " odd\n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + "
\n" + " \n" + " \n" + " \n" + "
\n" "

Resolver Statistics (Common)

\n" - " \n" - "
\n" - "
\n" - "
\n" - "
\n" - "
\n" - "
\n" - "
\n" - "\n" - " \n" - "
\n" - "

Resolver Statistics for View

\n" - " \n" - "
\n" - "
\n" - "
\n" - "
\n" - "
\n" - "
\n" - "
\n" - "
\n" - "\n" - "
\n" - "\n" - "
\n" - "

ADB Statistics (Common)

\n" - " \n" - "
\n" - "
\n" - "
\n" - "
\n" - "
\n" - "
\n" - "
\n" - "\n" - " \n" - "
\n" - "

ADB Statistics for View

\n" - " \n" - "
\n" - "
\n" - "
\n" - "
\n" - "
\n" - "
\n" - "
\n" - "
\n" - "\n" - "
\n" - "\n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" + "
Cache Statistics for View
\n" + " \n" + " \n" + " \n" + " \n" + " even\n" + " odd\n" + " \n" + " \n" + " \n" + " \n" + " \n" " \n" " \n" "
\n" + " \n" + " \n" + " \n" + "
\n" - "
\n" - "
\n" - "\n" " \n" - " \n" - " \n" - " \n" + "

Resolver Statistics for View

\n" + "
Cache DB RRsets for View
\n" + " \n" + " \n" + " \n" + " \n" + " even\n" + " odd\n" + " \n" + " \n" + " \n" + " \n" + " \n" " \n" + " \n" + "
\n" + " \n" + " \n" + " \n" + "
\n" + "
\n" + "

Cache DB RRsets for View

\n" + " \n" + " \n" " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - "
\n" - "
\n" - "
\n" - "\n" - "
\n" - "

Socket I/O Statistics

\n" - " \n" - "
\n" - "
\n" - "
\n" - "
\n" - "
\n" - "
\n" - "
\n" - "\n" - "
\n" - "\n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" + " \n" " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" " \n" " \n" "
Zones for View
NameClassSerialSuccessReferralNXRRSETNXDOMAINFailureXfrReqDoneXfrRej
\n" + " \n" + " \n" + " even\n" + " odd\n" + " \n" + " \n" + "
\n" " \n" - " \n" + " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" + " \n" "
\n" "
\n" "
\n" - "\n" - "
\n" - "\n" - " \n" - " \n" - " \n" + "

Socket I/O Statistics

\n" + "
Network Status
\n" + " \n" + " \n" + " \n" + " even\n" + " odd\n" + " \n" + " \n" + " \n" + " \n" + " \n" " \n" - " \n" + " \n" + "
\n" + " \n" + " \n" + " \n" + "
\n" + "
\n" + "
\n" + "

Response Codes per view/zone

\n" + " \n" + "

View

\n" + " \n" + " \n" + " \n" + " \n" + " \n" + "

Zone

\n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + "
\n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " even\n" + " odd\n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + "
\n" + " \n" + " \n" + " \n" + "
\n" + " \n" + " \n" + " \n" + "

Received QTYPES per view/zone

\n" + " \n" + "

View

\n" + " \n" + " \n" + " \n" + " \n" + " \n" + "

Zone

\n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + "
\n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " even\n" + " odd\n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + "
\n" + " \n" + " \n" + " \n" + "
\n" + " \n" + " \n" + " \n" + "

Network Status

\n" + " \n" + " \n" " \n" " \n" " \n" @@ -378,7 +555,14 @@ static char xslmsg[] = " \n" " \n" " \n" - " \n" + " \n" + " \n" + " \n" + " even\n" + " odd\n" + " \n" + " \n" + " \n" " \n" @@ -406,56 +590,52 @@ static char xslmsg[] = " \n" "
IDNameTypeState
\n" " \n" "
\n" "
\n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" + "

Task Manager Configuration

\n" + "
Task Manager Configuration
Thread-Model
\n" + " \n" + " \n" " \n" " \n" - " \n" - " \n" + " \n" + " \n" " \n" " \n" - " \n" - " \n" + " \n" + " \n" " \n" " \n" - " \n" - " \n" + " \n" + " \n" " \n" " \n" - " \n" - " \n" - " \n" - " \n" "
Thread-Model\n" " \n" "
Worker Threads
Worker Threads\n" " \n" "
Default Quantum
Default Quantum\n" " \n" "
Tasks Running
Tasks Running\n" " \n" "
Tasks Ready\n" - " \n" - "
\n" "
\n" - " \n" - " \n" - " \n" - " \n" - " \n" + "

Tasks

\n" + "
Tasks
\n" + " \n" " \n" " \n" " \n" " \n" " \n" - " \n" " \n" " \n" - " \n" + " \n" + " \n" + " \n" + " even\n" + " odd\n" + " \n" + " \n" + " \n" " \n" @@ -471,30 +651,33 @@ static char xslmsg[] = " \n" + " \n" + " \n" + "
IDNameReferencesStateQuantumEvents
\n" " \n" " \n" " \n" "
\n" + "
\n" + "

Memory Usage Summary

\n" + " \n" + " \n" + " \n" + " \n" + " even\n" + " odd\n" + " \n" + " \n" + " \n" + " \n" " \n" " \n" " \n" "
\n" + " \n" + " \n" - " \n" + " \n" "
\n" - "
\n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - "
Memory Usage Summary
\n" - "
\n" - " \n" - " \n" - " \n" - " \n" - " \n" + "
\n" + "

Memory Contexts

\n" + "
Memory Contexts
\n" + " \n" " \n" " \n" " \n" @@ -507,7 +690,14 @@ static char xslmsg[] = " \n" " \n" " \n" - " \n" + " \n" + " \n" + " \n" + " even\n" + " odd\n" + " \n" + " \n" + " \n" " \n" @@ -541,7 +731,8 @@ static char xslmsg[] = " \n" " \n" "
IDNameReferencesLoWater
\n" " \n" "
\n" - "\n" + "
\n" + "

Internet Systems Consortium Inc.
http://www.isc.org

\n" " \n" " \n" " \n" diff --git a/bin/named/query.c b/bin/named/query.c index 2c794af924..25b70d82a5 100644 --- a/bin/named/query.c +++ b/bin/named/query.c @@ -173,39 +173,62 @@ rpz_st_clear(ns_client_t *client); static inline void inc_stats(ns_client_t *client, isc_statscounter_t counter) { dns_zone_t *zone = client->query.authzone; + dns_rdatatype_t qtype; + dns_rdataset_t *rdataset; + isc_stats_t *zonestats; + dns_stats_t *querystats = NULL; isc_stats_increment(ns_g_server->nsstats, counter); - if (zone != NULL) { - isc_stats_t *zonestats = dns_zone_getrequeststats(zone); - if (zonestats != NULL) - isc_stats_increment(zonestats, counter); + if (zone == NULL) + return; + + /* Do regular response type stats */ + zonestats = dns_zone_getrequeststats(zone); + + if (zonestats != NULL) + isc_stats_increment(zonestats, counter); + + /* Do query type statistics + * + * We only increment per-type if we're using the authoriative + * answer counter, preventing double-counting. + */ + if (counter == dns_nsstatscounter_authans) { + querystats = dns_zone_getrcvquerystats(zone); + if (querystats != NULL) { + rdataset = ISC_LIST_HEAD(client->query.qname->list); + if (rdataset != NULL) { + qtype = rdataset->type; + dns_rdatatypestats_increment(querystats, qtype); + } + } } } static void query_send(ns_client_t *client) { isc_statscounter_t counter; + if ((client->message->flags & DNS_MESSAGEFLAG_AA) == 0) inc_stats(client, dns_nsstatscounter_nonauthans); else inc_stats(client, dns_nsstatscounter_authans); + if (client->message->rcode == dns_rcode_noerror) { - if (ISC_LIST_EMPTY(client->message->sections[DNS_SECTION_ANSWER])) { - if (client->query.isreferral) { + dns_section_t answer = DNS_SECTION_ANSWER; + if (ISC_LIST_EMPTY(client->message->sections[answer])) { + if (client->query.isreferral) counter = dns_nsstatscounter_referral; - } else { + else counter = dns_nsstatscounter_nxrrset; - } - } else { + } else counter = dns_nsstatscounter_success; - } - } else if (client->message->rcode == dns_rcode_nxdomain) { + } else if (client->message->rcode == dns_rcode_nxdomain) counter = dns_nsstatscounter_nxdomain; - } else { - /* We end up here in case of YXDOMAIN, and maybe others */ + else /* We end up here in case of YXDOMAIN, and maybe others */ counter = dns_nsstatscounter_failure; - } + inc_stats(client, counter); ns_client_send(client); } @@ -7476,6 +7499,7 @@ ns_query_start(ns_client_t *client) { INSIST(rdataset != NULL); qtype = rdataset->type; dns_rdatatypestats_increment(ns_g_server->rcvquerystats, qtype); + if (dns_rdatatype_ismeta(qtype)) { switch (qtype) { case dns_rdatatype_any: diff --git a/bin/named/statschannel.c b/bin/named/statschannel.c index 8cb5ce4f79..bfa6dd4b2b 100644 --- a/bin/named/statschannel.c +++ b/bin/named/statschannel.c @@ -189,7 +189,7 @@ init_desc(void) { SET_NSSTATDESC(servfail, "queries resulted in SERVFAIL", "QrySERVFAIL"); SET_NSSTATDESC(formerr, "queries resulted in FORMERR", "QryFORMERR"); SET_NSSTATDESC(nxdomain, "queries resulted in NXDOMAIN", "QryNXDOMAIN"); - SET_NSSTATDESC(recursion, "queries caused recursion","QryRecursion"); + SET_NSSTATDESC(recursion, "queries caused recursion", "QryRecursion"); SET_NSSTATDESC(duplicate, "duplicate queries received", "QryDuplicate"); SET_NSSTATDESC(dropped, "queries dropped", "QryDropped"); SET_NSSTATDESC(failure, "other query failures", "QryFailure"); @@ -334,7 +334,8 @@ init_desc(void) { SET_ZONESTATDESC(axfrreqv6, "IPv6 AXFR requested", "AXFRReqv6"); SET_ZONESTATDESC(ixfrreqv4, "IPv4 IXFR requested", "IXFRReqv4"); SET_ZONESTATDESC(ixfrreqv6, "IPv6 IXFR requested", "IXFRReqv6"); - SET_ZONESTATDESC(xfrsuccess, "transfer requests succeeded","XfrSuccess"); + SET_ZONESTATDESC(xfrsuccess, "transfer requests succeeded", + "XfrSuccess"); SET_ZONESTATDESC(xfrfail, "transfer requests failed", "XfrFail"); INSIST(i == dns_zonestatscounter_max); @@ -463,7 +464,7 @@ init_desc(void) { do { \ set_desc(dns_dnssecstats_ ## counterid, \ dns_dnssecstats_max, \ - desc, dnssecstats_desc,\ + desc, dnssecstats_desc, \ xmldesc, dnssecstats_xmldesc); \ dnssecstats_index[i++] = dns_dnssecstats_ ## counterid; \ } while (0) @@ -562,32 +563,48 @@ dump_counters(isc_stats_t *stats, isc_statsformat_t type, void *arg, writer = arg; if (category != NULL) { + /* */ TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR category)); + + /* inside category */ TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "name")); TRY0(xmlTextWriterWriteString(writer, ISC_XMLCHAR desc[index])); - TRY0(xmlTextWriterEndElement(writer)); /* name */ + TRY0(xmlTextWriterEndElement(writer)); + /* */ + /* */ TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "counter")); + TRY0(xmlTextWriterWriteFormatString(writer, + "%" ISC_PRINT_QUADFORMAT "u", value)); + + TRY0(xmlTextWriterEndElement(writer)); + /* */ + TRY0(xmlTextWriterEndElement(writer)); + /* */ + } else { TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR - desc[index])); + "counter")); + TRY0(xmlTextWriterWriteAttribute(writer, + ISC_XMLCHAR + "name", + ISC_XMLCHAR + desc[index])); + TRY0(xmlTextWriterWriteFormatString(writer, + "%" ISC_PRINT_QUADFORMAT "u", value)); + TRY0(xmlTextWriterEndElement(writer)); + /* counter */ } - TRY0(xmlTextWriterWriteFormatString(writer, - "%" - ISC_PRINT_QUADFORMAT - "u", value)); - TRY0(xmlTextWriterEndElement(writer)); /* counter */ - if (category != NULL) - TRY0(xmlTextWriterEndElement(writer)); /* category */ + #endif break; } @@ -595,6 +612,8 @@ dump_counters(isc_stats_t *stats, isc_statsformat_t type, void *arg, return (ISC_R_SUCCESS); #ifdef HAVE_LIBXML2 error: + isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_SERVER, + ISC_LOG_ERROR, "failed at dump_counters()"); return (ISC_R_FAILURE); #endif } @@ -627,25 +646,24 @@ rdtypestat_dump(dns_rdatastatstype_t type, isc_uint64_t val, void *arg) { #ifdef HAVE_LIBXML2 writer = dumparg->arg; - TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "rdtype")); - - TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "name")); - TRY0(xmlTextWriterWriteString(writer, ISC_XMLCHAR typestr)); - TRY0(xmlTextWriterEndElement(writer)); /* name */ TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "counter")); + TRY0(xmlTextWriterWriteAttribute(writer, ISC_XMLCHAR "name", + ISC_XMLCHAR typestr)); + TRY0(xmlTextWriterWriteFormatString(writer, "%" ISC_PRINT_QUADFORMAT "u", val)); - TRY0(xmlTextWriterEndElement(writer)); /* counter */ - TRY0(xmlTextWriterEndElement(writer)); /* rdtype */ + TRY0(xmlTextWriterEndElement(writer)); /* type */ #endif break; } return; #ifdef HAVE_LIBXML2 error: + isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_SERVER, + ISC_LOG_ERROR, "failed at rdtypestat_dump()"); dumparg->result = ISC_R_FAILURE; return; #endif @@ -714,6 +732,8 @@ rdatasetstats_dump(dns_rdatastatstype_t type, isc_uint64_t val, void *arg) { return; #ifdef HAVE_LIBXML2 error: + isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_SERVER, + ISC_LOG_ERROR, "failed at rdatasetstats_dump()"); dumparg->result = ISC_R_FAILURE; #endif @@ -742,20 +762,13 @@ opcodestat_dump(dns_opcode_t code, isc_uint64_t val, void *arg) { case isc_statsformat_xml: #ifdef HAVE_LIBXML2 writer = dumparg->arg; - - TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "opcode")); - - TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "name")); - TRY0(xmlTextWriterWriteString(writer, ISC_XMLCHAR codebuf)); - TRY0(xmlTextWriterEndElement(writer)); /* name */ - TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "counter")); + TRY0(xmlTextWriterWriteAttribute(writer, ISC_XMLCHAR "name", + ISC_XMLCHAR codebuf )); TRY0(xmlTextWriterWriteFormatString(writer, - "%" ISC_PRINT_QUADFORMAT "u", - val)); + "%" ISC_PRINT_QUADFORMAT "u", + val)); TRY0(xmlTextWriterEndElement(writer)); /* counter */ - - TRY0(xmlTextWriterEndElement(writer)); /* opcode */ #endif break; } @@ -763,6 +776,8 @@ opcodestat_dump(dns_opcode_t code, isc_uint64_t val, void *arg) { #ifdef HAVE_LIBXML2 error: + isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_SERVER, + ISC_LOG_ERROR, "failed at opcodestat_dump()"); dumparg->result = ISC_R_FAILURE; return; #endif @@ -770,56 +785,89 @@ opcodestat_dump(dns_opcode_t code, isc_uint64_t val, void *arg) { #ifdef HAVE_LIBXML2 -/* XXXMLG below here sucks. */ +/* XXXMLG below here sucks. (not so much) */ static isc_result_t zone_xmlrender(dns_zone_t *zone, void *arg) { + char buf[1024 + 32]; /* sufficiently large for zone name and class */ + char *zone_name_only = NULL; dns_rdataclass_t rdclass; isc_uint32_t serial; xmlTextWriterPtr writer = arg; isc_stats_t *zonestats; + dns_stats_t *rcvquerystats; + isc_uint64_t nsstat_values[dns_nsstatscounter_max]; int xmlrc; isc_result_t result; - TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "zone")); + stats_dumparg_t dumparg; + dumparg.type = isc_statsformat_xml; + dumparg.arg = writer; + + + TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "zone")); dns_zone_name(zone, buf, sizeof(buf)); - TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "name")); - TRY0(xmlTextWriterWriteString(writer, ISC_XMLCHAR buf)); - TRY0(xmlTextWriterEndElement(writer)); + zone_name_only = strtok(buf, "/"); + if(zone_name_only == NULL){ + zone_name_only = buf; + } + TRY0(xmlTextWriterWriteAttribute(writer, ISC_XMLCHAR "name", + ISC_XMLCHAR zone_name_only)); rdclass = dns_zone_getclass(zone); dns_rdataclass_format(rdclass, buf, sizeof(buf)); - TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "rdataclass")); - TRY0(xmlTextWriterWriteString(writer, ISC_XMLCHAR buf)); - TRY0(xmlTextWriterEndElement(writer)); + TRY0(xmlTextWriterWriteAttribute(writer, ISC_XMLCHAR "rdataclass", + ISC_XMLCHAR buf)); TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "serial")); if (dns_zone_getserial2(zone, &serial) == ISC_R_SUCCESS) TRY0(xmlTextWriterWriteFormatString(writer, "%u", serial)); else TRY0(xmlTextWriterWriteString(writer, ISC_XMLCHAR "-")); - TRY0(xmlTextWriterEndElement(writer)); + TRY0(xmlTextWriterEndElement(writer)); /* serial */ zonestats = dns_zone_getrequeststats(zone); - if (zonestats != NULL) { + rcvquerystats = dns_zone_getrcvquerystats(zone); + if (zonestats != NULL ) { TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "counters")); + TRY0(xmlTextWriterWriteAttribute(writer, ISC_XMLCHAR "type", + ISC_XMLCHAR "rcode")); + result = dump_counters(zonestats, isc_statsformat_xml, writer, NULL, nsstats_xmldesc, dns_nsstatscounter_max, nsstats_index, nsstat_values, ISC_STATSDUMP_VERBOSE); if (result != ISC_R_SUCCESS) goto error; - TRY0(xmlTextWriterEndElement(writer)); /* counters */ + /* counters type="rcode"*/ + TRY0(xmlTextWriterEndElement(writer)); + } + + if(rcvquerystats != NULL){ + TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "counters")); + TRY0(xmlTextWriterWriteAttribute(writer, ISC_XMLCHAR "type", + ISC_XMLCHAR "qtype")); + + dumparg.result = ISC_R_SUCCESS; + dns_rdatatypestats_dump(rcvquerystats, rdtypestat_dump, + &dumparg, 0); + if(dumparg.result != ISC_R_SUCCESS) + goto error; + + /* counters type="qtype"*/ + TRY0(xmlTextWriterEndElement(writer)); } TRY0(xmlTextWriterEndElement(writer)); /* zone */ return (ISC_R_SUCCESS); error: + isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_SERVER, + ISC_LOG_ERROR, "Failed at zone_xmlrender()"); return (ISC_R_FAILURE); } @@ -851,14 +899,9 @@ generatexml(ns_server_t *server, int *buflen, xmlChar **buf) { TRY0(xmlTextWriterStartDocument(writer, NULL, "UTF-8", NULL)); TRY0(xmlTextWriterWritePI(writer, ISC_XMLCHAR "xml-stylesheet", ISC_XMLCHAR "type=\"text/xsl\" href=\"/bind9.xsl\"")); - TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "isc")); - TRY0(xmlTextWriterWriteAttribute(writer, ISC_XMLCHAR "version", - ISC_XMLCHAR "1.0")); - - TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "bind")); TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "statistics")); TRY0(xmlTextWriterWriteAttribute(writer, ISC_XMLCHAR "version", - ISC_XMLCHAR "2.2")); + ISC_XMLCHAR "3.0")); /* Set common fields for statistics dump */ dumparg.type = isc_statsformat_xml; @@ -872,17 +915,20 @@ generatexml(ns_server_t *server, int *buflen, xmlChar **buf) { TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "views")); while (view != NULL) { TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "view")); - - TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "name")); - TRY0(xmlTextWriterWriteString(writer, ISC_XMLCHAR view->name)); - TRY0(xmlTextWriterEndElement(writer)); + TRY0(xmlTextWriterWriteAttribute(writer, ISC_XMLCHAR "name", + ISC_XMLCHAR view->name)); TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "zones")); result = dns_zt_apply(view->zonetable, ISC_TRUE, zone_xmlrender, writer); if (result != ISC_R_SUCCESS) goto error; - TRY0(xmlTextWriterEndElement(writer)); + TRY0(xmlTextWriterEndElement(writer)); /* zones */ + + TRY0(xmlTextWriterStartElement(writer, + ISC_XMLCHAR "counters")); + TRY0(xmlTextWriterWriteAttribute(writer, ISC_XMLCHAR "type", + ISC_XMLCHAR "resqtype")); if (view->resquerystats != NULL) { dumparg.result = ISC_R_SUCCESS; @@ -891,17 +937,23 @@ generatexml(ns_server_t *server, int *buflen, xmlChar **buf) { if (dumparg.result != ISC_R_SUCCESS) goto error; } + TRY0(xmlTextWriterEndElement(writer)); + /* */ + TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "counters")); + TRY0(xmlTextWriterWriteAttribute(writer, ISC_XMLCHAR "type", + ISC_XMLCHAR "resstats")); if (view->resstats != NULL) { result = dump_counters(view->resstats, isc_statsformat_xml, writer, - "resstat", resstats_xmldesc, + NULL, resstats_xmldesc, dns_resstatscounter_max, resstats_index, resstat_values, ISC_STATSDUMP_VERBOSE); if (result != ISC_R_SUCCESS) goto error; } + TRY0(xmlTextWriterEndElement(writer)); /* */ cacherrstats = dns_db_getrrsetstats(view->cachedb); if (cacherrstats != NULL) { @@ -952,60 +1004,92 @@ generatexml(ns_server_t *server, int *buflen, xmlChar **buf) { TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "server")); TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "boot-time")); TRY0(xmlTextWriterWriteString(writer, ISC_XMLCHAR boottime)); - TRY0(xmlTextWriterEndElement(writer)); + TRY0(xmlTextWriterEndElement(writer)); /* boot-time */ TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "current-time")); TRY0(xmlTextWriterWriteString(writer, ISC_XMLCHAR nowstr)); - TRY0(xmlTextWriterEndElement(writer)); + TRY0(xmlTextWriterEndElement(writer)); /* current-time */ - TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "requests")); dumparg.result = ISC_R_SUCCESS; + + TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "counters")); + TRY0(xmlTextWriterWriteAttribute(writer, ISC_XMLCHAR "type", + ISC_XMLCHAR "opcode")); + dns_opcodestats_dump(server->opcodestats, opcodestat_dump, &dumparg, 0); if (dumparg.result != ISC_R_SUCCESS) goto error; - TRY0(xmlTextWriterEndElement(writer)); /* requests */ - TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "queries-in")); + TRY0(xmlTextWriterEndElement(writer)); /* counters type=opcode */ + + TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "counters")); + TRY0(xmlTextWriterWriteAttribute(writer, ISC_XMLCHAR "type", + ISC_XMLCHAR "qtype")); + dumparg.result = ISC_R_SUCCESS; dns_rdatatypestats_dump(server->rcvquerystats, rdtypestat_dump, &dumparg, 0); if (dumparg.result != ISC_R_SUCCESS) goto error; - TRY0(xmlTextWriterEndElement(writer)); /* queries-in */ + TRY0(xmlTextWriterEndElement(writer)); /* counters */ - result = dump_counters(server->nsstats, isc_statsformat_xml, writer, - "nsstat", nsstats_xmldesc, - dns_nsstatscounter_max, - nsstats_index, nsstat_values, - ISC_STATSDUMP_VERBOSE); + TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "counters")); + TRY0(xmlTextWriterWriteAttribute(writer, ISC_XMLCHAR "type", + ISC_XMLCHAR "nsstat")); + + result = dump_counters(server->nsstats, isc_statsformat_xml, + writer, NULL, nsstats_xmldesc, + dns_nsstatscounter_max, + nsstats_index, nsstat_values, + ISC_STATSDUMP_VERBOSE); if (result != ISC_R_SUCCESS) goto error; + TRY0(xmlTextWriterEndElement(writer)); /* counters type=nsstat */ + + TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "counters")); + TRY0(xmlTextWriterWriteAttribute(writer, ISC_XMLCHAR "type", + ISC_XMLCHAR "zonestat")); + result = dump_counters(server->zonestats, isc_statsformat_xml, writer, - "zonestat", zonestats_xmldesc, + NULL, zonestats_xmldesc, dns_zonestatscounter_max, zonestats_index, zonestat_values, ISC_STATSDUMP_VERBOSE); if (result != ISC_R_SUCCESS) goto error; + TRY0(xmlTextWriterEndElement(writer)); /* counters type=zonestat */ + /* * Most of the common resolver statistics entries are 0, so we don't * use the verbose dump here. */ - result = dump_counters(server->resolverstats, isc_statsformat_xml, writer, - "resstat", resstats_xmldesc, + + TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "counters")); + TRY0(xmlTextWriterWriteAttribute(writer, ISC_XMLCHAR "type", + ISC_XMLCHAR "resstat")); + result = dump_counters(server->resolverstats, isc_statsformat_xml, + writer, NULL, resstats_xmldesc, dns_resstatscounter_max, resstats_index, resstat_values, 0); if (result != ISC_R_SUCCESS) goto error; - result = dump_counters(server->sockstats, isc_statsformat_xml, writer, - "sockstat", sockstats_xmldesc, + TRY0(xmlTextWriterEndElement(writer)); /* counters type=resstat */ + + TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "counters")); + TRY0(xmlTextWriterWriteAttribute(writer, ISC_XMLCHAR "type", + ISC_XMLCHAR "sockstat")); + + result = dump_counters(server->sockstats, isc_statsformat_xml, + writer, NULL, sockstats_xmldesc, isc_sockstatscounter_max, sockstats_index, sockstat_values, ISC_STATSDUMP_VERBOSE); if (result != ISC_R_SUCCESS) goto error; + TRY0(xmlTextWriterEndElement(writer)); /* counters type=sockstat */ + TRY0(xmlTextWriterEndElement(writer)); /* server */ TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "memory")); @@ -1013,18 +1097,18 @@ generatexml(ns_server_t *server, int *buflen, xmlChar **buf) { TRY0(xmlTextWriterEndElement(writer)); /* memory */ TRY0(xmlTextWriterEndElement(writer)); /* statistics */ - TRY0(xmlTextWriterEndElement(writer)); /* bind */ - TRY0(xmlTextWriterEndElement(writer)); /* isc */ TRY0(xmlTextWriterEndDocument(writer)); xmlFreeTextWriter(writer); - xmlDocDumpFormatMemoryEnc(doc, buf, buflen, "UTF-8", 1); + xmlDocDumpFormatMemoryEnc(doc, buf, buflen, "UTF-8", 0); xmlFreeDoc(doc); return (ISC_R_SUCCESS); error: + isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_SERVER, + ISC_LOG_ERROR, "failed generating XML response"); if (writer != NULL) xmlFreeTextWriter(writer); if (doc != NULL) @@ -1063,7 +1147,10 @@ render_index(const char *url, const char *querystring, void *arg, isc_buffer_add(b, msglen); *freecb = wrap_xmlfree; *freecb_args = NULL; - } + } else + isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, + NS_LOGMODULE_SERVER, ISC_LOG_ERROR, + "failed at rendering XML()"); return (result); } @@ -1095,7 +1182,7 @@ static void shutdown_listener(ns_statschannel_t *listener) { char socktext[ISC_SOCKADDR_FORMATSIZE]; isc_sockaddr_format(&listener->address, socktext, sizeof(socktext)); - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL,NS_LOGMODULE_SERVER, + isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_SERVER, ISC_LOG_NOTICE, "stopping statistics channel on %s", socktext); @@ -1348,7 +1435,8 @@ ns_statschannels_configure(ns_server_t *server, const cfg_obj_t *config, obj = cfg_tuple_get(listen_params, "address"); addr = *cfg_obj_assockaddr(obj); if (isc_sockaddr_getport(&addr) == 0) - isc_sockaddr_setport(&addr, NS_STATSCHANNEL_HTTPPORT); + isc_sockaddr_setport(&addr, + NS_STATSCHANNEL_HTTPPORT); isc_sockaddr_format(&addr, socktext, sizeof(socktext)); diff --git a/bin/named/zoneconf.c b/bin/named/zoneconf.c index 4dc9c130ce..21d88684a3 100644 --- a/bin/named/zoneconf.c +++ b/bin/named/zoneconf.c @@ -820,6 +820,7 @@ ns_zone_configure(const cfg_obj_t *config, const cfg_obj_t *vconfig, isc_boolean_t ixfrdiff; dns_masterformat_t masterformat; isc_stats_t *zoneqrystats; + dns_stats_t *rcvquerystats; isc_boolean_t zonestats_on; int seconds; dns_zone_t *mayberaw = (raw != NULL) ? raw : zone; @@ -1006,15 +1007,24 @@ ns_zone_configure(const cfg_obj_t *config, const cfg_obj_t *vconfig, result = ns_config_get(maps, "zone-statistics", &obj); INSIST(result == ISC_R_SUCCESS && obj != NULL); zonestats_on = cfg_obj_asboolean(obj); - zoneqrystats = NULL; + + zoneqrystats = NULL; + rcvquerystats = NULL; if (zonestats_on) { RETERR(isc_stats_create(mctx, &zoneqrystats, dns_nsstatscounter_max)); + RETERR(dns_rdatatypestats_create(mctx, + &rcvquerystats)); } - dns_zone_setrequeststats(zone, zoneqrystats); + dns_zone_setrequeststats(zone, zoneqrystats ); + dns_zone_setrcvquerystats(zone, rcvquerystats); + if (zoneqrystats != NULL) isc_stats_detach(&zoneqrystats); + if(rcvquerystats != NULL) + dns_stats_detach(&rcvquerystats); + /* * Configure master functionality. This applies * to primary masters (type "master") and slaves diff --git a/lib/dns/include/dns/zone.h b/lib/dns/include/dns/zone.h index 60c87e1cb6..5bc370c6ea 100644 --- a/lib/dns/include/dns/zone.h +++ b/lib/dns/include/dns/zone.h @@ -1701,8 +1701,15 @@ dns_zone_setrequeststats(dns_zone_t *zone, isc_stats_t *stats); *\li stats is a valid statistics. */ +void +dns_zone_setrcvquerystats(dns_zone_t *zone, dns_stats_t *stats); + isc_stats_t * dns_zone_getrequeststats(dns_zone_t *zone); + +dns_stats_t * +dns_zone_getrcvquerystats(dns_zone_t *zone); + /*%< * Get the additional statistics for zone, if one is installed. * diff --git a/lib/dns/zone.c b/lib/dns/zone.c index bc871e8558..da7e868f17 100644 --- a/lib/dns/zone.c +++ b/lib/dns/zone.c @@ -310,6 +310,7 @@ struct dns_zone { */ isc_boolean_t requeststats_on; isc_stats_t *requeststats; + dns_stats_t *rcvquerystats; isc_uint32_t notifydelay; dns_isselffunc_t isself; void *isselfarg; @@ -903,6 +904,7 @@ dns_zone_create(dns_zone_t **zonep, isc_mem_t *mctx) { zone->stats = NULL; zone->requeststats_on = ISC_FALSE; zone->requeststats = NULL; + zone->rcvquerystats = NULL; zone->notifydelay = 5; zone->isself = NULL; zone->isselfarg = NULL; @@ -1018,6 +1020,8 @@ zone_free(dns_zone_t *zone) { isc_stats_detach(&zone->stats); if (zone->requeststats != NULL) isc_stats_detach(&zone->requeststats); + if(zone->rcvquerystats != NULL ) + dns_stats_detach(&zone->rcvquerystats); if (zone->db != NULL) zone_detachdb(zone); if (zone->acache != NULL) @@ -14750,8 +14754,11 @@ dns_zone_setstats(dns_zone_t *zone, isc_stats_t *stats) { void dns_zone_setrequeststats(dns_zone_t *zone, isc_stats_t *stats) { + REQUIRE(DNS_ZONE_VALID(zone)); + dns_zone_log(zone, ISC_LOG_INFO, "Setting zone query stats"); + LOCK_ZONE(zone); if (zone->requeststats_on && stats == NULL) zone->requeststats_on = ISC_FALSE; @@ -14762,8 +14769,23 @@ dns_zone_setrequeststats(dns_zone_t *zone, isc_stats_t *stats) { } } UNLOCK_ZONE(zone); +} - return; +void +dns_zone_setrcvquerystats(dns_zone_t *zone, dns_stats_t *stats) { + + REQUIRE(DNS_ZONE_VALID(zone)); + + dns_zone_log(zone, ISC_LOG_INFO, "Setting received query stats"); + + LOCK_ZONE(zone); + if (zone->requeststats_on && stats != NULL) { + if (zone->rcvquerystats == NULL) { + dns_stats_attach(stats, &zone->rcvquerystats); + zone->requeststats_on = ISC_TRUE; + } + } + UNLOCK_ZONE(zone); } isc_stats_t * @@ -14782,6 +14804,18 @@ dns_zone_getrequeststats(dns_zone_t *zone) { return (NULL); } +/* + * Return the received query stats bucket + * see note from dns_zone_getrequeststats() + */ +dns_stats_t * +dns_zone_getrcvquerystats(dns_zone_t *zone) { + if (zone->requeststats_on) + return (zone->rcvquerystats); + else + return (NULL); +} + void dns_zone_dialup(dns_zone_t *zone) {