From aecadaf3b1bbbe0bd58f703989baf38eedd0ffca Mon Sep 17 00:00:00 2001 From: ckb Date: Wed, 14 Nov 2012 12:44:15 -0600 Subject: [PATCH] 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] --- CHANGES | 10 + bin/named/bind9.xsl | 1014 +++++++++++++++++++++--------------- bin/named/bind9.xsl.h | 857 ++++++++++++++++++------------ bin/named/query.c | 52 +- bin/named/statschannel.c | 238 ++++++--- bin/named/zoneconf.c | 14 +- lib/dns/include/dns/zone.h | 7 + lib/dns/zone.c | 36 +- 8 files changed, 1392 insertions(+), 836 deletions(-) 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) {