BIND 10 trac2157_2, updated. 577a426b8734d7f77e4dceae80fe0c344ab15330 [2157] fix systest failure

BIND 10 source code commits bind10-changes at lists.isc.org
Tue Oct 2 09:55:36 UTC 2012


The branch, trac2157_2 has been updated
       via  577a426b8734d7f77e4dceae80fe0c344ab15330 (commit)
       via  415e9b6a2c8544882c71e3cb91d47bb768e41a9f (commit)
       via  1b616670c801a181c8ba5718710bdeb6573e3e4b (commit)
       via  2f912a5d91267471e059ad8bc3e9f0377de2f487 (commit)
       via  72941a64efbe4843657cbb05f8945f7c6dc0e3a0 (commit)
       via  3c3bea55f38dac4d8fcc9c0cda55c6382d6c2cd7 (commit)
       via  307071b44a3b5e5e3e8d3cc75b00c69d81fefaee (commit)
       via  a7adf4e4fe023903dd4ca362a6cfa6cafc06241d (commit)
       via  98cdad7fa22451ef1ca067ee747c70a31262ee61 (commit)
       via  c76e3fc072e8b1b771b55b6547889863ba263f31 (commit)
       via  50c395e0d786b2330919498c37149edf22808a52 (commit)
      from  6de9ca4708fe4e56e17aedab38b89d7f76bf2515 (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
commit 577a426b8734d7f77e4dceae80fe0c344ab15330
Author: Yoshitaka Aharen <aharen at jprs.co.jp>
Date:   Tue Oct 2 18:54:09 2012 +0900

    [2157] fix systest failure
    
    update the name of statistics items in systest

commit 415e9b6a2c8544882c71e3cb91d47bb768e41a9f
Author: Yoshitaka Aharen <aharen at jprs.co.jp>
Date:   Tue Oct 2 18:43:48 2012 +0900

    [2157] some optimization of statistics in query processing

commit 1b616670c801a181c8ba5718710bdeb6573e3e4b
Author: Yoshitaka Aharen <aharen at jprs.co.jp>
Date:   Tue Oct 2 18:25:19 2012 +0900

    [2157] modified an interface to get statistics data
    
    Counters::get returns auth statistics data in the format defined in the
    spec file.

commit 2f912a5d91267471e059ad8bc3e9f0377de2f487
Author: Yoshitaka Aharen <aharen at jprs.co.jp>
Date:   Tue Oct 2 15:26:29 2012 +0900

    [2157] update spec file
    
    Added entries for statistics items into the spec file

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

Summary of changes:
 doc/Doxyfile                              |    4 +-
 src/bin/auth/Makefile.am                  |    3 +-
 src/bin/auth/auth.spec.pre.in             | 1346 +++++++++++++++++++++++------
 src/bin/auth/auth_srv.cc                  |  117 +--
 src/bin/auth/auth_srv.h                   |   46 +-
 src/bin/auth/benchmarks/Makefile.am       |    3 +-
 src/bin/auth/statistics.cc                |  323 +++----
 src/bin/auth/statistics.h                 |  312 ++++---
 src/bin/auth/statistics_items.h           |  682 +++++++++++++++
 src/bin/auth/tests/Makefile.am            |    3 +-
 src/bin/auth/tests/auth_srv_unittest.cc   |  206 ++++-
 src/bin/auth/tests/statistics_unittest.cc |  414 +++------
 src/lib/statistics/Makefile.am            |    6 +-
 src/lib/statistics/counter.cc             |   82 --
 src/lib/statistics/counter.h              |   54 +-
 src/lib/statistics/counter_dict.cc        |  265 ------
 src/lib/statistics/counter_dict.h         |  202 +++--
 src/lib/statistics/tests/Makefile.am      |    1 -
 tests/system/bindctl/tests.sh             |    4 +-
 19 files changed, 2608 insertions(+), 1465 deletions(-)
 create mode 100644 src/bin/auth/statistics_items.h
 delete mode 100644 src/lib/statistics/counter.cc
 delete mode 100644 src/lib/statistics/counter_dict.cc

-----------------------------------------------------------------------
diff --git a/doc/Doxyfile b/doc/Doxyfile
index 7e122e9..9f0f7f1 100644
--- a/doc/Doxyfile
+++ b/doc/Doxyfile
@@ -579,8 +579,8 @@ INPUT                  = ../src/lib/exceptions ../src/lib/cc \
     ../src/lib/log/compiler ../src/lib/asiolink/ ../src/lib/nsas \
     ../src/lib/testutils ../src/lib/cache ../src/lib/server_common/ \
     ../src/bin/sockcreator/ ../src/lib/util/ ../src/lib/util/io/ \
-    ../src/lib/resolve ../src/lib/acl ../src/bin/dhcp6 ../src/lib/dhcp \
-    ../src/bin/dhcp4 ../tests/tools/perfdhcp devel
+    ../src/lib/resolve ../src/lib/acl ../src/lib/statistics ../src/lib/dhcp \
+    ../src/bin/dhcp6 ../src/bin/dhcp4 ../tests/tools/perfdhcp devel
 
 # This tag can be used to specify the character encoding of the source files
 # that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is
diff --git a/src/bin/auth/Makefile.am b/src/bin/auth/Makefile.am
index 3efa9d3..2060ad6 100644
--- a/src/bin/auth/Makefile.am
+++ b/src/bin/auth/Makefile.am
@@ -54,7 +54,7 @@ b10_auth_SOURCES += auth_log.cc auth_log.h
 b10_auth_SOURCES += auth_config.cc auth_config.h
 b10_auth_SOURCES += command.cc command.h
 b10_auth_SOURCES += common.h common.cc
-b10_auth_SOURCES += statistics.cc statistics.h
+b10_auth_SOURCES += statistics.cc statistics.h statistics_items.h
 b10_auth_SOURCES += datasrc_configurator.h
 b10_auth_SOURCES += main.cc
 
@@ -73,7 +73,6 @@ b10_auth_LDADD += $(top_builddir)/src/lib/asiolink/libb10-asiolink.la
 b10_auth_LDADD += $(top_builddir)/src/lib/log/libb10-log.la
 b10_auth_LDADD += $(top_builddir)/src/lib/xfr/libb10-xfr.la
 b10_auth_LDADD += $(top_builddir)/src/lib/server_common/libb10-server-common.la
-b10_auth_LDADD += $(top_builddir)/src/lib/statistics/libb10-statistics.la
 b10_auth_LDADD += $(SQLITE_LIBS)
 
 # TODO: config.h.in is wrong because doesn't honor pkgdatadir
diff --git a/src/bin/auth/auth.spec.pre.in b/src/bin/auth/auth.spec.pre.in
index a471b7a..45a154c 100644
--- a/src/bin/auth/auth.spec.pre.in
+++ b/src/bin/auth/auth.spec.pre.in
@@ -141,284 +141,1076 @@
     ],
     "statistics": [
       {
-        "item_name": "queries.tcp",
-        "item_type": "integer",
-        "item_optional": false,
-        "item_default": 0,
-        "item_title": "Queries TCP ",
-        "item_description": "A number of total query counts which all auth servers receive over TCP since they started initially"
-      },
-      {
-        "item_name": "queries.udp",
-        "item_type": "integer",
+        "item_name": "zones",
+        "item_type": "named_set",
         "item_optional": false,
-        "item_default": 0,
-        "item_title": "Queries UDP",
-        "item_description": "A number of total query counts which all auth servers receive over UDP since they started initially"
-      },
-      {
-        "item_name": "opcode.query",
-        "item_type": "integer",
-        "item_optional": true,
-        "item_default": 0,
-        "item_title": "Received query requests",
-        "item_description": "The number of total request counts whose opcode is query"
-      },
-      {
-        "item_name": "opcode.iquery",
-        "item_type": "integer",
-        "item_optional": true,
-        "item_default": 0,
-        "item_title": "Received inverse query requests",
-        "item_description": "The number of total request counts whose opcode is inverse query"
-      },
-      {
-        "item_name": "opcode.status",
-        "item_type": "integer",
-        "item_optional": true,
-        "item_default": 0,
-        "item_title": "Received status requests",
-        "item_description": "The number of total request counts whose opcode is status"
-      },
-      {
-        "item_name": "opcode.reserved3",
-        "item_type": "integer",
-        "item_optional": true,
-        "item_default": 0,
-        "item_title": "Received requests opcode 3",
-        "item_description": "The number of total request counts whose opcode is 3 (reserved)"
-      },
-      {
-        "item_name": "opcode.notify",
-        "item_type": "integer",
-        "item_optional": true,
-        "item_default": 0,
-        "item_title": "Received notify requests",
-        "item_description": "The number of total request counts whose opcode is notify"
-      },
-      {
-        "item_name": "opcode.update",
-        "item_type": "integer",
-        "item_optional": true,
-        "item_default": 0,
-        "item_title": "Received update requests",
-        "item_description": "The number of total request counts whose opcode is update"
-      },
-      {
-        "item_name": "opcode.reserved6",
-        "item_type": "integer",
-        "item_optional": true,
-        "item_default": 0,
-        "item_title": "Received requests opcode 6",
-        "item_description": "The number of total request counts whose opcode is 6 (reserved)"
-      },
-      {
-        "item_name": "opcode.reserved7",
-        "item_type": "integer",
-        "item_optional": true,
-        "item_default": 0,
-        "item_title": "Received requests opcode 7",
-        "item_description": "The number of total request counts whose opcode is 7 (reserved)"
-      },
-      {
-        "item_name": "opcode.reserved8",
-        "item_type": "integer",
-        "item_optional": true,
-        "item_default": 0,
-        "item_title": "Received requests opcode 8",
-        "item_description": "The number of total request counts whose opcode is 8 (reserved)"
-      },
-      {
-        "item_name": "opcode.reserved9",
-        "item_type": "integer",
-        "item_optional": true,
-        "item_default": 0,
-        "item_title": "Received requests opcode 9",
-        "item_description": "The number of total request counts whose opcode is 9 (reserved)"
-      },
-      {
-        "item_name": "opcode.reserved10",
-        "item_type": "integer",
-        "item_optional": true,
-        "item_default": 0,
-        "item_title": "Received requests opcode 10",
-        "item_description": "The number of total request counts whose opcode is 10 (reserved)"
-      },
-      {
-        "item_name": "opcode.reserved11",
-        "item_type": "integer",
-        "item_optional": true,
-        "item_default": 0,
-        "item_title": "Received requests opcode 11",
-        "item_description": "The number of total request counts whose opcode is 11 (reserved)"
-      },
-      {
-        "item_name": "opcode.reserved12",
-        "item_type": "integer",
-        "item_optional": true,
-        "item_default": 0,
-        "item_title": "Received requests opcode 12",
-        "item_description": "The number of total request counts whose opcode is 12 (reserved)"
-      },
-      {
-        "item_name": "opcode.reserved13",
-        "item_type": "integer",
-        "item_optional": true,
-        "item_default": 0,
-        "item_title": "Received requests opcode 13",
-        "item_description": "The number of total request counts whose opcode is 13 (reserved)"
-      },
-      {
-        "item_name": "opcode.reserved14",
-        "item_type": "integer",
-        "item_optional": true,
-        "item_default": 0,
-        "item_title": "Received requests opcode 14",
-        "item_description": "The number of total request counts whose opcode is 14 (reserved)"
-      },
-      {
-        "item_name": "opcode.reserved15",
-        "item_type": "integer",
-        "item_optional": true,
-        "item_default": 0,
-        "item_title": "Received requests opcode 15",
-        "item_description": "The number of total request counts whose opcode is 15 (reserved)"
-      },
-      {
-        "item_name": "rcode.noerror",
-        "item_type": "integer",
-        "item_optional": true,
-        "item_default": 0,
-        "item_title": "Sent success response",
-        "item_description": "The number of total responses with rcode 0 (NOERROR)"
-      },
-      {
-        "item_name": "rcode.formerr",
-        "item_type": "integer",
-        "item_optional": true,
-        "item_default": 0,
-        "item_title": "Sent 'format error' response",
-        "item_description": "The number of total responses with rcode 1 (FORMERR)"
-      },
-      {
-        "item_name": "rcode.servfail",
-        "item_type": "integer",
-        "item_optional": true,
-        "item_default": 0,
-        "item_title": "Sent 'server failure' response",
-        "item_description": "The number of total responses with rcode 2 (SERVFAIL)"
-      },
-      {
-        "item_name": "rcode.nxdomain",
-        "item_type": "integer",
-        "item_optional": true,
-        "item_default": 0,
-        "item_title": "Sent 'name error' response",
-        "item_description": "The number of total responses with rcode 3 (NXDOMAIN)"
-      },
-      {
-        "item_name": "rcode.notimp",
-        "item_type": "integer",
-        "item_optional": true,
-        "item_default": 0,
-        "item_title": "Sent 'not implemented' response",
-        "item_description": "The number of total responses with rcode 4 (NOTIMP)"
-      },
-      {
-        "item_name": "rcode.refused",
-        "item_type": "integer",
-        "item_optional": true,
-        "item_default": 0,
-        "item_title": "Sent 'refused' response",
-        "item_description": "The number of total responses with rcode 5 (REFUSED)"
-      },
-      {
-        "item_name": "rcode.yxdomain",
-        "item_type": "integer",
-        "item_optional": true,
-        "item_default": 0,
-        "item_title": "Sent 'name unexpectedly exists' response",
-        "item_description": "The number of total responses with rcode 6 (YXDOMAIN)"
-      },
-      {
-        "item_name": "rcode.yxrrset",
-        "item_type": "integer",
-        "item_optional": true,
-        "item_default": 0,
-        "item_title": "Sent 'rrset unexpectedly exists' response",
-        "item_description": "The number of total responses with rcode 7 (YXRRSET)"
-      },
-      {
-        "item_name": "rcode.nxrrset",
-        "item_type": "integer",
-        "item_optional": true,
-        "item_default": 0,
-        "item_title": "Sent 'no such rrset' response",
-        "item_description": "The number of total responses with rcode 8 (NXRRSET)"
-      },
-      {
-        "item_name": "rcode.notauth",
-        "item_type": "integer",
-        "item_optional": true,
-        "item_default": 0,
-        "item_title": "Sent 'not authoritative' response",
-        "item_description": "The number of total responses with rcode 9 (NOTAUTH)"
-      },
-      {
-        "item_name": "rcode.notzone",
-        "item_type": "integer",
-        "item_optional": true,
-        "item_default": 0,
-        "item_title": "Sent 'name not in zone' response",
-        "item_description": "The number of total responses with rcode 10 (NOTZONE)"
-      },
-      {
-        "item_name": "rcode.reserved11",
-        "item_type": "integer",
-        "item_optional": true,
-        "item_default": 0,
-        "item_title": "Sent response with rcode 11",
-        "item_description": "The number of total responses with rcode 11 (reserved)"
-      },
-      {
-        "item_name": "rcode.reserved12",
-        "item_type": "integer",
-        "item_optional": true,
-        "item_default": 0,
-        "item_title": "Sent response with rcode 12",
-        "item_description": "The number of total responses with rcode 12 (reserved)"
-      },
-      {
-        "item_name": "rcode.reserved13",
-        "item_type": "integer",
-        "item_optional": true,
-        "item_default": 0,
-        "item_title": "Sent response with rcode 13",
-        "item_description": "The number of total responses with rcode 13 (reserved)"
-      },
-      {
-        "item_name": "rcode.reserved14",
-        "item_type": "integer",
-        "item_optional": true,
-        "item_default": 0,
-        "item_title": "Sent response with rcode 14",
-        "item_description": "The number of total responses with rcode 14 (reserved)"
-      },
-      {
-        "item_name": "rcode.reserved15",
-        "item_type": "integer",
-        "item_optional": true,
-        "item_default": 0,
-        "item_title": "Sent response with rcode 15",
-        "item_description": "The number of total responses with rcode 15 (reserved)"
-      },
-      {
-        "item_name": "rcode.badvers",
-        "item_type": "integer",
-        "item_optional": true,
-        "item_default": 0,
-        "item_title": "Sent 'EDNS version not implemented' response",
-        "item_description": "The number of total responses with rcode 16 (BADVERS)"
+        "item_title": "Zone statistics",
+        "item_description": "Zone statistics items. Items for all zones are stored in '_SERVER_'.",
+        "item_default": {
+          "_SERVER_": {
+            "request.v4": 0,
+            "request.v6": 0,
+            "request.edns0": 0,
+            "request.badednsver": 0,
+            "request.tsig": 0,
+            "request.sig0": 0,
+            "request.badsig": 0,
+            "request.udp": 0,
+            "request.tcp": 0,
+            "request.dnssec_ok": 0,
+            "opcode.query": 0,
+            "opcode.iquery": 0,
+            "opcode.status": 0,
+            "opcode.notify": 0,
+            "opcode.update": 0,
+            "opcode.other": 0,
+            "qtype.a": 0,
+            "qtype.ns": 0,
+            "qtype.md": 0,
+            "qtype.mf": 0,
+            "qtype.cname": 0,
+            "qtype.soa": 0,
+            "qtype.mb": 0,
+            "qtype.mg": 0,
+            "qtype.mr": 0,
+            "qtype.null": 0,
+            "qtype.wks": 0,
+            "qtype.ptr": 0,
+            "qtype.hinfo": 0,
+            "qtype.minfo": 0,
+            "qtype.mx": 0,
+            "qtype.txt": 0,
+            "qtype.rp": 0,
+            "qtype.afsdb": 0,
+            "qtype.x25": 0,
+            "qtype.isdn": 0,
+            "qtype.rt": 0,
+            "qtype.nsap": 0,
+            "qtype.nsap-ptr": 0,
+            "qtype.sig": 0,
+            "qtype.key": 0,
+            "qtype.px": 0,
+            "qtype.gpos": 0,
+            "qtype.aaaa": 0,
+            "qtype.loc": 0,
+            "qtype.nxt": 0,
+            "qtype.eid": 0,
+            "qtype.nimloc": 0,
+            "qtype.srv": 0,
+            "qtype.atma": 0,
+            "qtype.naptr": 0,
+            "qtype.kx": 0,
+            "qtype.cert": 0,
+            "qtype.a6": 0,
+            "qtype.dname": 0,
+            "qtype.sink": 0,
+            "qtype.opt": 0,
+            "qtype.apl": 0,
+            "qtype.ds": 0,
+            "qtype.sshfp": 0,
+            "qtype.ipseckey": 0,
+            "qtype.rrsig": 0,
+            "qtype.nsec": 0,
+            "qtype.dnskey": 0,
+            "qtype.dhcid": 0,
+            "qtype.nsec3": 0,
+            "qtype.nsec3param": 0,
+            "qtype.hip": 0,
+            "qtype.ninfo": 0,
+            "qtype.rkey": 0,
+            "qtype.talink": 0,
+            "qtype.spf": 0,
+            "qtype.uinfo": 0,
+            "qtype.uid": 0,
+            "qtype.gid": 0,
+            "qtype.unspec": 0,
+            "qtype.tkey": 0,
+            "qtype.tsig": 0,
+            "qtype.ixfr": 0,
+            "qtype.axfr": 0,
+            "qtype.mailb": 0,
+            "qtype.maila": 0,
+            "qtype.uri": 0,
+            "qtype.caa": 0,
+            "qtype.ta": 0,
+            "qtype.dlv": 0,
+            "qtype.other": 0,
+            "response": 0,
+            "response.truncated": 0,
+            "response.edns0": 0,
+            "response.tsig": 0,
+            "response.sig0": 0,
+            "qrysuccess": 0,
+            "qryauthans": 0,
+            "qrynoauthans": 0,
+            "qryreferral": 0,
+            "qrynxrrset": 0,
+            "authqryrej": 0,
+            "rcode.noerror": 0,
+            "rcode.formerr": 0,
+            "rcode.servfail": 0,
+            "rcode.nxdomain": 0,
+            "rcode.notimp": 0,
+            "rcode.refused": 0,
+            "rcode.yxdomain": 0,
+            "rcode.yxrrset": 0,
+            "rcode.nxrrset": 0,
+            "rcode.notauth": 0,
+            "rcode.notzone": 0,
+            "rcode.badsigvers": 0,
+            "rcode.badkey": 0,
+            "rcode.badtime": 0,
+            "rcode.badmode": 0,
+            "rcode.badname": 0,
+            "rcode.badalg": 0,
+            "rcode.badtrunc": 0,
+            "rcode.other": 0
+          }
+        },
+        "named_set_item_spec": {
+          "item_name": "zone",
+          "item_type": "map",
+          "item_optional": false,
+          "item_default": { },
+          "map_item_spec": [
+            {
+              "item_name": "request.v4",
+              "item_type": "integer",
+              "item_optional": false,
+              "item_default": 0,
+              "item_title": "request.v4",
+              "item_description": "Number of IPv4 requests received"
+            },
+            {
+              "item_name": "request.v6",
+              "item_type": "integer",
+              "item_optional": false,
+              "item_default": 0,
+              "item_title": "request.v6",
+              "item_description": "Number of IPv6 requests received"
+            },
+            {
+              "item_name": "request.edns0",
+              "item_type": "integer",
+              "item_optional": false,
+              "item_default": 0,
+              "item_title": "request.edns0",
+              "item_description": "Number of requests with EDNS(0) received"
+            },
+            {
+              "item_name": "request.badednsver",
+              "item_type": "integer",
+              "item_optional": false,
+              "item_default": 0,
+              "item_title": "request.badednsver",
+              "item_description": "Number of requests with unsupported EDNS version received"
+            },
+            {
+              "item_name": "request.tsig",
+              "item_type": "integer",
+              "item_optional": false,
+              "item_default": 0,
+              "item_title": "request.tsig",
+              "item_description": "Number of requests with TSIG received"
+            },
+            {
+              "item_name": "request.sig0",
+              "item_type": "integer",
+              "item_optional": false,
+              "item_default": 0,
+              "item_title": "request.sig0",
+              "item_description": "Number of requests with SIG(0) received; currently not implemented in BIND 10"
+            },
+            {
+              "item_name": "request.badsig",
+              "item_type": "integer",
+              "item_optional": false,
+              "item_default": 0,
+              "item_title": "request.badsig",
+              "item_description": "Number of requests with invalid TSIG or SIG(0) signature received"
+            },
+            {
+              "item_name": "request.udp",
+              "item_type": "integer",
+              "item_optional": false,
+              "item_default": 0,
+              "item_title": "request.udp",
+              "item_description": "Number of UDP requests received"
+            },
+            {
+              "item_name": "request.tcp",
+              "item_type": "integer",
+              "item_optional": false,
+              "item_default": 0,
+              "item_title": "request.tcp",
+              "item_description": "Number of TCP requests received"
+            },
+            {
+              "item_name": "request.dnssec_ok",
+              "item_type": "integer",
+              "item_optional": false,
+              "item_default": 0,
+              "item_title": "request.dnssec_ok",
+              "item_description": "Number of requests with DO bit"
+            },
+            {
+              "item_name": "opcode.query",
+              "item_type": "integer",
+              "item_optional": false,
+              "item_default": 0,
+              "item_title": "opcode.query",
+              "item_description": "Number of Opcode=QUERY requests received"
+            },
+            {
+              "item_name": "opcode.iquery",
+              "item_type": "integer",
+              "item_optional": false,
+              "item_default": 0,
+              "item_title": "opcode.iquery",
+              "item_description": "Number of Opcode=IQUERY requests received"
+            },
+            {
+              "item_name": "opcode.status",
+              "item_type": "integer",
+              "item_optional": false,
+              "item_default": 0,
+              "item_title": "opcode.status",
+              "item_description": "Number of Opcode=STATUS requests received"
+            },
+            {
+              "item_name": "opcode.notify",
+              "item_type": "integer",
+              "item_optional": false,
+              "item_default": 0,
+              "item_title": "opcode.notify",
+              "item_description": "Number of Opcode=NOTIFY requests received"
+            },
+            {
+              "item_name": "opcode.update",
+              "item_type": "integer",
+              "item_optional": false,
+              "item_default": 0,
+              "item_title": "opcode.update",
+              "item_description": "Number of Opcode=UPDATE requests received"
+            },
+            {
+              "item_name": "opcode.other",
+              "item_type": "integer",
+              "item_optional": false,
+              "item_default": 0,
+              "item_title": "opcode.other",
+              "item_description": "Number of requests in other OpCode received"
+            },
+            {
+              "item_name": "qtype.a",
+              "item_type": "integer",
+              "item_optional": false,
+              "item_default": 0,
+              "item_title": "qtype.a",
+              "item_description": "Number of QTYPE = A queries received"
+            },
+            {
+              "item_name": "qtype.ns",
+              "item_type": "integer",
+              "item_optional": false,
+              "item_default": 0,
+              "item_title": "qtype.ns",
+              "item_description": "Number of QTYPE = NS queries received"
+            },
+            {
+              "item_name": "qtype.md",
+              "item_type": "integer",
+              "item_optional": false,
+              "item_default": 0,
+              "item_title": "qtype.md",
+              "item_description": "Number of QTYPE = MD queries received"
+            },
+            {
+              "item_name": "qtype.mf",
+              "item_type": "integer",
+              "item_optional": false,
+              "item_default": 0,
+              "item_title": "qtype.mf",
+              "item_description": "Number of QTYPE = MF queries received"
+            },
+            {
+              "item_name": "qtype.cname",
+              "item_type": "integer",
+              "item_optional": false,
+              "item_default": 0,
+              "item_title": "qtype.cname",
+              "item_description": "Number of QTYPE = CNAME queries received"
+            },
+            {
+              "item_name": "qtype.soa",
+              "item_type": "integer",
+              "item_optional": false,
+              "item_default": 0,
+              "item_title": "qtype.soa",
+              "item_description": "Number of QTYPE = SOA queries received"
+            },
+            {
+              "item_name": "qtype.mb",
+              "item_type": "integer",
+              "item_optional": false,
+              "item_default": 0,
+              "item_title": "qtype.mb",
+              "item_description": "Number of QTYPE = MB queries received"
+            },
+            {
+              "item_name": "qtype.mg",
+              "item_type": "integer",
+              "item_optional": false,
+              "item_default": 0,
+              "item_title": "qtype.mg",
+              "item_description": "Number of QTYPE = MG queries received"
+            },
+            {
+              "item_name": "qtype.mr",
+              "item_type": "integer",
+              "item_optional": false,
+              "item_default": 0,
+              "item_title": "qtype.mr",
+              "item_description": "Number of QTYPE = MR queries received"
+            },
+            {
+              "item_name": "qtype.null",
+              "item_type": "integer",
+              "item_optional": false,
+              "item_default": 0,
+              "item_title": "qtype.null",
+              "item_description": "Number of QTYPE = NULL queries received"
+            },
+            {
+              "item_name": "qtype.wks",
+              "item_type": "integer",
+              "item_optional": false,
+              "item_default": 0,
+              "item_title": "qtype.wks",
+              "item_description": "Number of QTYPE = WKS queries received"
+            },
+            {
+              "item_name": "qtype.ptr",
+              "item_type": "integer",
+              "item_optional": false,
+              "item_default": 0,
+              "item_title": "qtype.ptr",
+              "item_description": "Number of QTYPE = PTR queries received"
+            },
+            {
+              "item_name": "qtype.hinfo",
+              "item_type": "integer",
+              "item_optional": false,
+              "item_default": 0,
+              "item_title": "qtype.hinfo",
+              "item_description": "Number of QTYPE = HINFO queries received"
+            },
+            {
+              "item_name": "qtype.minfo",
+              "item_type": "integer",
+              "item_optional": false,
+              "item_default": 0,
+              "item_title": "qtype.minfo",
+              "item_description": "Number of QTYPE = MINFO queries received"
+            },
+            {
+              "item_name": "qtype.mx",
+              "item_type": "integer",
+              "item_optional": false,
+              "item_default": 0,
+              "item_title": "qtype.mx",
+              "item_description": "Number of QTYPE = MX queries received"
+            },
+            {
+              "item_name": "qtype.txt",
+              "item_type": "integer",
+              "item_optional": false,
+              "item_default": 0,
+              "item_title": "qtype.txt",
+              "item_description": "Number of QTYPE = TXT queries received"
+            },
+            {
+              "item_name": "qtype.rp",
+              "item_type": "integer",
+              "item_optional": false,
+              "item_default": 0,
+              "item_title": "qtype.rp",
+              "item_description": "Number of QTYPE = RP queries received"
+            },
+            {
+              "item_name": "qtype.afsdb",
+              "item_type": "integer",
+              "item_optional": false,
+              "item_default": 0,
+              "item_title": "qtype.afsdb",
+              "item_description": "Number of QTYPE = AFSDB queries received"
+            },
+            {
+              "item_name": "qtype.x25",
+              "item_type": "integer",
+              "item_optional": false,
+              "item_default": 0,
+              "item_title": "qtype.x25",
+              "item_description": "Number of QTYPE = X25 queries received"
+            },
+            {
+              "item_name": "qtype.isdn",
+              "item_type": "integer",
+              "item_optional": false,
+              "item_default": 0,
+              "item_title": "qtype.isdn",
+              "item_description": "Number of QTYPE = ISDN queries received"
+            },
+            {
+              "item_name": "qtype.rt",
+              "item_type": "integer",
+              "item_optional": false,
+              "item_default": 0,
+              "item_title": "qtype.rt",
+              "item_description": "Number of QTYPE = RT queries received"
+            },
+            {
+              "item_name": "qtype.nsap",
+              "item_type": "integer",
+              "item_optional": false,
+              "item_default": 0,
+              "item_title": "qtype.nsap",
+              "item_description": "Number of QTYPE = NSAP queries received"
+            },
+            {
+              "item_name": "qtype.nsap-ptr",
+              "item_type": "integer",
+              "item_optional": false,
+              "item_default": 0,
+              "item_title": "qtype.nsap-ptr",
+              "item_description": "Number of QTYPE = NSAP-PTR queries received"
+            },
+            {
+              "item_name": "qtype.sig",
+              "item_type": "integer",
+              "item_optional": false,
+              "item_default": 0,
+              "item_title": "qtype.sig",
+              "item_description": "Number of QTYPE = SIG queries received"
+            },
+            {
+              "item_name": "qtype.key",
+              "item_type": "integer",
+              "item_optional": false,
+              "item_default": 0,
+              "item_title": "qtype.key",
+              "item_description": "Number of QTYPE = KEY queries received"
+            },
+            {
+              "item_name": "qtype.px",
+              "item_type": "integer",
+              "item_optional": false,
+              "item_default": 0,
+              "item_title": "qtype.px",
+              "item_description": "Number of QTYPE = PX queries received"
+            },
+            {
+              "item_name": "qtype.gpos",
+              "item_type": "integer",
+              "item_optional": false,
+              "item_default": 0,
+              "item_title": "qtype.gpos",
+              "item_description": "Number of QTYPE = GPOS queries received"
+            },
+            {
+              "item_name": "qtype.aaaa",
+              "item_type": "integer",
+              "item_optional": false,
+              "item_default": 0,
+              "item_title": "qtype.aaaa",
+              "item_description": "Number of QTYPE = AAAA queries received"
+            },
+            {
+              "item_name": "qtype.loc",
+              "item_type": "integer",
+              "item_optional": false,
+              "item_default": 0,
+              "item_title": "qtype.loc",
+              "item_description": "Number of QTYPE = LOC queries received"
+            },
+            {
+              "item_name": "qtype.nxt",
+              "item_type": "integer",
+              "item_optional": false,
+              "item_default": 0,
+              "item_title": "qtype.nxt",
+              "item_description": "Number of QTYPE = NXT queries received"
+            },
+            {
+              "item_name": "qtype.eid",
+              "item_type": "integer",
+              "item_optional": false,
+              "item_default": 0,
+              "item_title": "qtype.eid",
+              "item_description": "Number of QTYPE = EID queries received"
+            },
+            {
+              "item_name": "qtype.nimloc",
+              "item_type": "integer",
+              "item_optional": false,
+              "item_default": 0,
+              "item_title": "qtype.nimloc",
+              "item_description": "Number of QTYPE = NIMLOC queries received"
+            },
+            {
+              "item_name": "qtype.srv",
+              "item_type": "integer",
+              "item_optional": false,
+              "item_default": 0,
+              "item_title": "qtype.srv",
+              "item_description": "Number of QTYPE = SRV queries received"
+            },
+            {
+              "item_name": "qtype.atma",
+              "item_type": "integer",
+              "item_optional": false,
+              "item_default": 0,
+              "item_title": "qtype.atma",
+              "item_description": "Number of QTYPE = ATMA queries received"
+            },
+            {
+              "item_name": "qtype.naptr",
+              "item_type": "integer",
+              "item_optional": false,
+              "item_default": 0,
+              "item_title": "qtype.naptr",
+              "item_description": "Number of QTYPE = NAPTR queries received"
+            },
+            {
+              "item_name": "qtype.kx",
+              "item_type": "integer",
+              "item_optional": false,
+              "item_default": 0,
+              "item_title": "qtype.kx",
+              "item_description": "Number of QTYPE = KX queries received"
+            },
+            {
+              "item_name": "qtype.cert",
+              "item_type": "integer",
+              "item_optional": false,
+              "item_default": 0,
+              "item_title": "qtype.cert",
+              "item_description": "Number of QTYPE = CERT queries received"
+            },
+            {
+              "item_name": "qtype.a6",
+              "item_type": "integer",
+              "item_optional": false,
+              "item_default": 0,
+              "item_title": "qtype.a6",
+              "item_description": "Number of QTYPE = A6 queries received"
+            },
+            {
+              "item_name": "qtype.dname",
+              "item_type": "integer",
+              "item_optional": false,
+              "item_default": 0,
+              "item_title": "qtype.dname",
+              "item_description": "Number of QTYPE = DNAME queries received"
+            },
+            {
+              "item_name": "qtype.sink",
+              "item_type": "integer",
+              "item_optional": false,
+              "item_default": 0,
+              "item_title": "qtype.sink",
+              "item_description": "Number of QTYPE = SINK queries received"
+            },
+            {
+              "item_name": "qtype.opt",
+              "item_type": "integer",
+              "item_optional": false,
+              "item_default": 0,
+              "item_title": "qtype.opt",
+              "item_description": "Number of QTYPE = OPT queries received"
+            },
+            {
+              "item_name": "qtype.apl",
+              "item_type": "integer",
+              "item_optional": false,
+              "item_default": 0,
+              "item_title": "qtype.apl",
+              "item_description": "Number of QTYPE = APL queries received"
+            },
+            {
+              "item_name": "qtype.ds",
+              "item_type": "integer",
+              "item_optional": false,
+              "item_default": 0,
+              "item_title": "qtype.ds",
+              "item_description": "Number of QTYPE = DS queries received"
+            },
+            {
+              "item_name": "qtype.sshfp",
+              "item_type": "integer",
+              "item_optional": false,
+              "item_default": 0,
+              "item_title": "qtype.sshfp",
+              "item_description": "Number of QTYPE = SSHFP queries received"
+            },
+            {
+              "item_name": "qtype.ipseckey",
+              "item_type": "integer",
+              "item_optional": false,
+              "item_default": 0,
+              "item_title": "qtype.ipseckey",
+              "item_description": "Number of QTYPE = IPSECKEY queries received"
+            },
+            {
+              "item_name": "qtype.rrsig",
+              "item_type": "integer",
+              "item_optional": false,
+              "item_default": 0,
+              "item_title": "qtype.rrsig",
+              "item_description": "Number of QTYPE = RRSIG queries received"
+            },
+            {
+              "item_name": "qtype.nsec",
+              "item_type": "integer",
+              "item_optional": false,
+              "item_default": 0,
+              "item_title": "qtype.nsec",
+              "item_description": "Number of QTYPE = NSEC queries received"
+            },
+            {
+              "item_name": "qtype.dnskey",
+              "item_type": "integer",
+              "item_optional": false,
+              "item_default": 0,
+              "item_title": "qtype.dnskey",
+              "item_description": "Number of QTYPE = DNSKEY queries received"
+            },
+            {
+              "item_name": "qtype.dhcid",
+              "item_type": "integer",
+              "item_optional": false,
+              "item_default": 0,
+              "item_title": "qtype.dhcid",
+              "item_description": "Number of QTYPE = DHCID queries received"
+            },
+            {
+              "item_name": "qtype.nsec3",
+              "item_type": "integer",
+              "item_optional": false,
+              "item_default": 0,
+              "item_title": "qtype.nsec3",
+              "item_description": "Number of QTYPE = NSEC3 queries received"
+            },
+            {
+              "item_name": "qtype.nsec3param",
+              "item_type": "integer",
+              "item_optional": false,
+              "item_default": 0,
+              "item_title": "qtype.nsec3param",
+              "item_description": "Number of QTYPE = NSEC3PARAM queries received"
+            },
+            {
+              "item_name": "qtype.hip",
+              "item_type": "integer",
+              "item_optional": false,
+              "item_default": 0,
+              "item_title": "qtype.hip",
+              "item_description": "Number of QTYPE = HIP queries received"
+            },
+            {
+              "item_name": "qtype.ninfo",
+              "item_type": "integer",
+              "item_optional": false,
+              "item_default": 0,
+              "item_title": "qtype.ninfo",
+              "item_description": "Number of QTYPE = NINFO queries received"
+            },
+            {
+              "item_name": "qtype.rkey",
+              "item_type": "integer",
+              "item_optional": false,
+              "item_default": 0,
+              "item_title": "qtype.rkey",
+              "item_description": "Number of QTYPE = RKEY queries received"
+            },
+            {
+              "item_name": "qtype.talink",
+              "item_type": "integer",
+              "item_optional": false,
+              "item_default": 0,
+              "item_title": "qtype.talink",
+              "item_description": "Number of QTYPE = TALINK queries received"
+            },
+            {
+              "item_name": "qtype.spf",
+              "item_type": "integer",
+              "item_optional": false,
+              "item_default": 0,
+              "item_title": "qtype.spf",
+              "item_description": "Number of QTYPE = SPF queries received"
+            },
+            {
+              "item_name": "qtype.uinfo",
+              "item_type": "integer",
+              "item_optional": false,
+              "item_default": 0,
+              "item_title": "qtype.uinfo",
+              "item_description": "Number of QTYPE = UINFO queries received"
+            },
+            {
+              "item_name": "qtype.uid",
+              "item_type": "integer",
+              "item_optional": false,
+              "item_default": 0,
+              "item_title": "qtype.uid",
+              "item_description": "Number of QTYPE = UID queries received"
+            },
+            {
+              "item_name": "qtype.gid",
+              "item_type": "integer",
+              "item_optional": false,
+              "item_default": 0,
+              "item_title": "qtype.gid",
+              "item_description": "Number of QTYPE = GID queries received"
+            },
+            {
+              "item_name": "qtype.unspec",
+              "item_type": "integer",
+              "item_optional": false,
+              "item_default": 0,
+              "item_title": "qtype.unspec",
+              "item_description": "Number of QTYPE = UNSPEC queries received"
+            },
+            {
+              "item_name": "qtype.tkey",
+              "item_type": "integer",
+              "item_optional": false,
+              "item_default": 0,
+              "item_title": "qtype.tkey",
+              "item_description": "Number of QTYPE = TKEY queries received"
+            },
+            {
+              "item_name": "qtype.tsig",
+              "item_type": "integer",
+              "item_optional": false,
+              "item_default": 0,
+              "item_title": "qtype.tsig",
+              "item_description": "Number of QTYPE = TSIG queries received"
+            },
+            {
+              "item_name": "qtype.ixfr",
+              "item_type": "integer",
+              "item_optional": false,
+              "item_default": 0,
+              "item_title": "qtype.ixfr",
+              "item_description": "Number of QTYPE = IXFR queries received"
+            },
+            {
+              "item_name": "qtype.axfr",
+              "item_type": "integer",
+              "item_optional": false,
+              "item_default": 0,
+              "item_title": "qtype.axfr",
+              "item_description": "Number of QTYPE = AXFR queries received"
+            },
+            {
+              "item_name": "qtype.mailb",
+              "item_type": "integer",
+              "item_optional": false,
+              "item_default": 0,
+              "item_title": "qtype.mailb",
+              "item_description": "Number of QTYPE = MAILB queries received"
+            },
+            {
+              "item_name": "qtype.maila",
+              "item_type": "integer",
+              "item_optional": false,
+              "item_default": 0,
+              "item_title": "qtype.maila",
+              "item_description": "Number of QTYPE = MAILA queries received"
+            },
+            {
+              "item_name": "qtype.uri",
+              "item_type": "integer",
+              "item_optional": false,
+              "item_default": 0,
+              "item_title": "qtype.uri",
+              "item_description": "Number of QTYPE = URI queries received"
+            },
+            {
+              "item_name": "qtype.caa",
+              "item_type": "integer",
+              "item_optional": false,
+              "item_default": 0,
+              "item_title": "qtype.caa",
+              "item_description": "Number of QTYPE = CAA queries received"
+            },
+            {
+              "item_name": "qtype.ta",
+              "item_type": "integer",
+              "item_optional": false,
+              "item_default": 0,
+              "item_title": "qtype.ta",
+              "item_description": "Number of QTYPE = TA queries received"
+            },
+            {
+              "item_name": "qtype.dlv",
+              "item_type": "integer",
+              "item_optional": false,
+              "item_default": 0,
+              "item_title": "qtype.dlv",
+              "item_description": "Number of QTYPE = DLV queries received"
+            },
+            {
+              "item_name": "qtype.other",
+              "item_type": "integer",
+              "item_optional": false,
+              "item_default": 0,
+              "item_title": "qtype.other",
+              "item_description": "Number of queries in other QTYPE received"
+            },
+            {
+              "item_name": "response",
+              "item_type": "integer",
+              "item_optional": false,
+              "item_default": 0,
+              "item_title": "response",
+              "item_description": "Number of responses sent"
+            },
+            {
+              "item_name": "response.truncated",
+              "item_type": "integer",
+              "item_optional": false,
+              "item_default": 0,
+              "item_title": "response.truncated",
+              "item_description": "Number of truncated responses sent"
+            },
+            {
+              "item_name": "response.edns0",
+              "item_type": "integer",
+              "item_optional": false,
+              "item_default": 0,
+              "item_title": "response.edns0",
+              "item_description": "Number of responses with EDNS0"
+            },
+            {
+              "item_name": "response.tsig",
+              "item_type": "integer",
+              "item_optional": false,
+              "item_default": 0,
+              "item_title": "response.tsig",
+              "item_description": "Number of responses with TSIG"
+            },
+            {
+              "item_name": "response.sig0",
+              "item_type": "integer",
+              "item_optional": false,
+              "item_default": 0,
+              "item_title": "response.sig0",
+              "item_description": "Number of responses with SIG(0); currently not implemented in BIND 10"
+            },
+            {
+              "item_name": "qrysuccess",
+              "item_type": "integer",
+              "item_optional": false,
+              "item_default": 0,
+              "item_title": "qrysuccess",
+              "item_description": "Number of queries resulted in rcode = NOERROR and answer RR >= 1"
+            },
+            {
+              "item_name": "qryauthans",
+              "item_type": "integer",
+              "item_optional": false,
+              "item_default": 0,
+              "item_title": "qryauthans",
+              "item_description": "Number of queries resulted in authoritative answer"
+            },
+            {
+              "item_name": "qrynoauthans",
+              "item_type": "integer",
+              "item_optional": false,
+              "item_default": 0,
+              "item_title": "qrynoauthans",
+              "item_description": "Number of queries resulted in non-authoritative answer"
+            },
+            {
+              "item_name": "qryreferral",
+              "item_type": "integer",
+              "item_optional": false,
+              "item_default": 0,
+              "item_title": "qryreferral",
+              "item_description": "Number of queries resulted in referral answer"
+            },
+            {
+              "item_name": "qrynxrrset",
+              "item_type": "integer",
+              "item_optional": false,
+              "item_default": 0,
+              "item_title": "qrynxrrset",
+              "item_description": "Number of queries resulted in NOERROR but answer RR == 0"
+            },
+            {
+              "item_name": "authqryrej",
+              "item_type": "integer",
+              "item_optional": false,
+              "item_default": 0,
+              "item_title": "authqryrej",
+              "item_description": "Number of authoritative queries rejected"
+            },
+            {
+              "item_name": "rcode.noerror",
+              "item_type": "integer",
+              "item_optional": false,
+              "item_default": 0,
+              "item_title": "rcode.noerror",
+              "item_description": "Number of queries resulted in RCODE = 0 (NoError)"
+            },
+            {
+              "item_name": "rcode.formerr",
+              "item_type": "integer",
+              "item_optional": false,
+              "item_default": 0,
+              "item_title": "rcode.formerr",
+              "item_description": "Number of queries resulted in RCODE = 1 (FormErr)"
+            },
+            {
+              "item_name": "rcode.servfail",
+              "item_type": "integer",
+              "item_optional": false,
+              "item_default": 0,
+              "item_title": "rcode.servfail",
+              "item_description": "Number of queries resulted in RCODE = 2 (ServFail)"
+            },
+            {
+              "item_name": "rcode.nxdomain",
+              "item_type": "integer",
+              "item_optional": false,
+              "item_default": 0,
+              "item_title": "rcode.nxdomain",
+              "item_description": "Number of queries resulted in RCODE = 3 (NXDomain)"
+            },
+            {
+              "item_name": "rcode.notimp",
+              "item_type": "integer",
+              "item_optional": false,
+              "item_default": 0,
+              "item_title": "rcode.notimp",
+              "item_description": "Number of queries resulted in RCODE = 4 (NotImp)"
+            },
+            {
+              "item_name": "rcode.refused",
+              "item_type": "integer",
+              "item_optional": false,
+              "item_default": 0,
+              "item_title": "rcode.refused",
+              "item_description": "Number of queries resulted in RCODE = 5 (Refused)"
+            },
+            {
+              "item_name": "rcode.yxdomain",
+              "item_type": "integer",
+              "item_optional": false,
+              "item_default": 0,
+              "item_title": "rcode.yxdomain",
+              "item_description": "Number of queries resulted in RCODE = 6 (YXDomain)"
+            },
+            {
+              "item_name": "rcode.yxrrset",
+              "item_type": "integer",
+              "item_optional": false,
+              "item_default": 0,
+              "item_title": "rcode.yxrrset",
+              "item_description": "Number of queries resulted in RCODE = 7 (YXRRSet)"
+            },
+            {
+              "item_name": "rcode.nxrrset",
+              "item_type": "integer",
+              "item_optional": false,
+              "item_default": 0,
+              "item_title": "rcode.nxrrset",
+              "item_description": "Number of queries resulted in RCODE = 8 (NXRRSet)"
+            },
+            {
+              "item_name": "rcode.notauth",
+              "item_type": "integer",
+              "item_optional": false,
+              "item_default": 0,
+              "item_title": "rcode.notauth",
+              "item_description": "Number of queries resulted in RCODE = 9 (NotAuth)"
+            },
+            {
+              "item_name": "rcode.notzone",
+              "item_type": "integer",
+              "item_optional": false,
+              "item_default": 0,
+              "item_title": "rcode.notzone",
+              "item_description": "Number of queries resulted in RCODE = 10 (NotZone)"
+            },
+            {
+              "item_name": "rcode.badsigvers",
+              "item_type": "integer",
+              "item_optional": false,
+              "item_default": 0,
+              "item_title": "rcode.badsigvers",
+              "item_description": "Number of queries resulted in RCODE = 16 (BADVERS, BADSIG)"
+            },
+            {
+              "item_name": "rcode.badkey",
+              "item_type": "integer",
+              "item_optional": false,
+              "item_default": 0,
+              "item_title": "rcode.badkey",
+              "item_description": "Number of queries resulted in RCODE = 17 (BADKEY)"
+            },
+            {
+              "item_name": "rcode.badtime",
+              "item_type": "integer",
+              "item_optional": false,
+              "item_default": 0,
+              "item_title": "rcode.badtime",
+              "item_description": "Number of queries resulted in RCODE = 18 (BADTIME)"
+            },
+            {
+              "item_name": "rcode.badmode",
+              "item_type": "integer",
+              "item_optional": false,
+              "item_default": 0,
+              "item_title": "rcode.badmode",
+              "item_description": "Number of queries resulted in RCODE = 19 (BADMODE)"
+            },
+            {
+              "item_name": "rcode.badname",
+              "item_type": "integer",
+              "item_optional": false,
+              "item_default": 0,
+              "item_title": "rcode.badname",
+              "item_description": "Number of queries resulted in RCODE = 20 (BADNAME)"
+            },
+            {
+              "item_name": "rcode.badalg",
+              "item_type": "integer",
+              "item_optional": false,
+              "item_default": 0,
+              "item_title": "rcode.badalg",
+              "item_description": "Number of queries resulted in RCODE = 21 (BADALG)"
+            },
+            {
+              "item_name": "rcode.badtrunc",
+              "item_type": "integer",
+              "item_optional": false,
+              "item_default": 0,
+              "item_title": "rcode.badtrunc",
+              "item_description": "Number of queries resulted in RCODE = 22 (BADTRUNC)"
+            },
+            {
+              "item_name": "rcode.other",
+              "item_type": "integer",
+              "item_optional": false,
+              "item_default": 0,
+              "item_title": "rcode.other",
+              "item_description": "Number of queries resulted in other RCODEs"
+            }
+          ]
+	}
       }
     ]
   }
diff --git a/src/bin/auth/auth_srv.cc b/src/bin/auth/auth_srv.cc
index 82a98a4..dd0047a 100644
--- a/src/bin/auth/auth_srv.cc
+++ b/src/bin/auth/auth_srv.cc
@@ -82,6 +82,8 @@ using namespace isc::xfr;
 using namespace isc::asiolink;
 using namespace isc::asiodns;
 using namespace isc::server_common::portconfig;
+using isc::auth::statistics::Counters;
+using isc::auth::statistics::QRAttributes;
 
 namespace {
 // A helper class for cleaning up message renderer.
@@ -257,7 +259,7 @@ public:
     AbstractSession* xfrin_session_;
 
     /// Query counters for statistics
-    AuthCounters counters_;
+    Counters counters_;
 
     /// Addresses we listen on
     AddressList listen_addresses_;
@@ -269,6 +271,9 @@ public:
     std::map<RRClass, boost::shared_ptr<ConfigurableClientList> >
         client_lists_;
 
+    /// Query / Response attributes
+    QRAttributes stats_attrs_;
+
     boost::shared_ptr<ConfigurableClientList> getClientList(const RRClass&
                                                             rrclass)
     {
@@ -281,10 +286,6 @@ public:
         }
     }
 
-    /// Bind the ModuleSpec object in config_session_ with
-    /// isc:config::ModuleSpec::validateStatistics.
-    void registerStatisticsValidator();
-
     /// Socket session forwarder for dynamic update requests
     BaseSocketSessionForwarder& ddns_base_forwarder_;
 
@@ -295,30 +296,23 @@ public:
 
     /// \brief Resume the server
     ///
-    /// This is a wrapper call for DNSServer::resume(done), if 'done' is true,
-    /// the Rcode set in the given Message is counted in the statistics
-    /// counter.
+    /// This is a wrapper call for DNSServer::resume(done). Query/Response
+    /// statistics counters are incremented in this method.
     ///
     /// This method is expected to be called by processMessage()
     ///
     /// \param server The DNSServer as passed to processMessage()
     /// \param message The response as constructed by processMessage()
-    /// \param done If true, the Rcode from the given message is counted,
-    ///             this value is then passed to server->resume(bool)
+    /// \param done If true, it indicates there is a response.
+    ///             this value will be passed to server->resume(bool)
     void resumeServer(isc::asiodns::DNSServer* server,
                       isc::dns::Message& message,
-                      bool done);
+                      const bool done);
 
 private:
     bool xfrout_connected_;
     AbstractXfroutClient& xfrout_client_;
 
-    /// Increment query counter
-    void incCounter(const int protocol);
-
-    // validateStatistics
-    bool validateStatistics(isc::data::ConstElementPtr data) const;
-
     auth::Query query_;
 };
 
@@ -486,7 +480,6 @@ AuthSrv::setXfrinSession(AbstractSession* xfrin_session) {
 void
 AuthSrv::setConfigSession(ModuleCCSession* config_session) {
     impl_->config_session_ = config_session;
-    impl_->registerStatisticsValidator();
 }
 
 ModuleCCSession*
@@ -500,6 +493,12 @@ AuthSrv::processMessage(const IOMessage& io_message, Message& message,
 {
     InputBuffer request_buffer(io_message.getData(), io_message.getDataSize());
 
+    // statistics: check transport carrying the message (IP, transport)
+    impl_->stats_attrs_.setQueryIPVersion(
+        io_message.getRemoteEndpoint().getFamily());
+    impl_->stats_attrs_.setQueryTransportProtocol(
+        io_message.getRemoteEndpoint().getProtocol());
+
     // First, check the header part.  If we fail even for the base header,
     // just drop the message.
     try {
@@ -554,6 +553,10 @@ AuthSrv::processMessage(const IOMessage& io_message, Message& message,
                                            **impl_->keyring_));
         tsig_error = tsig_context->verify(tsig_record, io_message.getData(),
                                           io_message.getDataSize());
+        // statistics: check TSIG attributes
+        // SIG(0) is currently not implemented in Auth
+        impl_->stats_attrs_.setQuerySig(true, false,
+                                       tsig_error != TSIGError::NOERROR());
     }
 
     if (tsig_error != TSIGError::NOERROR()) {
@@ -566,9 +569,20 @@ AuthSrv::processMessage(const IOMessage& io_message, Message& message,
     const Opcode opcode = message.getOpcode();
     bool send_answer = true;
     try {
-        // update per opcode statistics counter.  This can only be reliable
-        // after TSIG check succeeds.
-        impl_->counters_.inc(message.getOpcode());
+        // statistics: check EDNS
+        //     note: This can only be reliable after TSIG check succeeds.
+        {
+            ConstEDNSPtr edns = message.getEDNS();
+            if (edns != NULL) {
+                impl_->stats_attrs_.setQueryEDNS(true,
+                                                 edns->getVersion() != 0);
+                impl_->stats_attrs_.setQueryDO(edns->getDNSSECAwareness());
+            }
+        }
+
+        // statistics: check OpCode
+        //     note: This can only be reliable after TSIG check succeeds.
+        impl_->stats_attrs_.setQueryOpCode(opcode.getCode());
 
         if (opcode == Opcode::NOTIFY()) {
             send_answer = impl_->processNotify(io_message, message, buffer,
@@ -627,9 +641,6 @@ AuthSrvImpl::processNormalQuery(const IOMessage& io_message, Message& message,
     message.setHeaderFlag(Message::HEADERFLAG_AA);
     message.setRcode(Rcode::NOERROR());
 
-    // Increment query counter.
-    incCounter(io_message.getSocket().getProtocol());
-
     if (remote_edns) {
         EDNSPtr local_edns = EDNSPtr(new EDNS());
         local_edns->setDNSSECAwareness(dnssec_ok);
@@ -674,9 +685,6 @@ AuthSrvImpl::processXfrQuery(const IOMessage& io_message, Message& message,
                              OutputBuffer& buffer,
                              auto_ptr<TSIGContext> tsig_context)
 {
-    // Increment query counter.
-    incCounter(io_message.getSocket().getProtocol());
-
     if (io_message.getSocket().getProtocol() == IPPROTO_UDP) {
         LOG_DEBUG(auth_logger, DBG_AUTH_DETAIL, AUTH_AXFR_UDP);
         makeErrorMessage(renderer_, message, buffer, Rcode::FORMERR(),
@@ -809,39 +817,15 @@ AuthSrvImpl::processUpdate(const IOMessage& io_message) {
 }
 
 void
-AuthSrvImpl::incCounter(const int protocol) {
-    // Increment query counter.
-    if (protocol == IPPROTO_UDP) {
-        counters_.inc(AuthCounters::SERVER_UDP_QUERY);
-    } else if (protocol == IPPROTO_TCP) {
-        counters_.inc(AuthCounters::SERVER_TCP_QUERY);
-    } else {
-        // unknown protocol
-        isc_throw(Unexpected, "Unknown protocol: " << protocol);
-    }
-}
-
-void
-AuthSrvImpl::registerStatisticsValidator() {
-    counters_.registerStatisticsValidator(
-        boost::bind(&AuthSrvImpl::validateStatistics, this, _1));
-}
-
-bool
-AuthSrvImpl::validateStatistics(isc::data::ConstElementPtr data) const {
-    if (config_session_ == NULL) {
-        return (false);
-    }
-    return (
-        config_session_->getModuleSpec().validateStatistics(
-            data, true));
-}
-
-void
-AuthSrvImpl::resumeServer(DNSServer* server, Message& message, bool done) {
+AuthSrvImpl::resumeServer(DNSServer* server, Message& message,
+                          const bool done) {
     if (done) {
-        counters_.inc(message.getRcode());
+        stats_attrs_.answerWasSent();
+        // isTruncated from MessageRenderer
+        stats_attrs_.setResponseTruncated(renderer_.isTruncated());
     }
+    counters_.inc(stats_attrs_, message);
+    stats_attrs_.reset();
     server->resume(done);
 }
 
@@ -861,22 +845,7 @@ AuthSrv::updateConfig(ConstElementPtr new_config) {
 }
 
 ConstElementPtr AuthSrv::getStatistics() const {
-    return (impl_->counters_.getStatistics());
-}
-
-uint64_t
-AuthSrv::getCounter(const AuthCounters::ServerCounterType type) const {
-    return (impl_->counters_.getCounter(type));
-}
-
-uint64_t
-AuthSrv::getCounter(const Opcode opcode) const {
-    return (impl_->counters_.getCounter(opcode));
-}
-
-uint64_t
-AuthSrv::getCounter(const Rcode rcode) const {
-    return (impl_->counters_.getCounter(rcode));
+    return (impl_->counters_.get());
 }
 
 const AddressList&
diff --git a/src/bin/auth/auth_srv.h b/src/bin/auth/auth_srv.h
index e2ffd71..a3d8402 100644
--- a/src/bin/auth/auth_srv.h
+++ b/src/bin/auth/auth_srv.h
@@ -205,55 +205,11 @@ public:
     /// \brief Returns statistics data
     ///
     /// This function can throw an exception from
-    /// AuthCounters::getStatistics().
+    /// Counters::getStatistics().
     ///
     /// \return JSON format statistics data.
     isc::data::ConstElementPtr getStatistics() const;
 
-    /// \brief Get the value of counter in the AuthCounters.
-    ///
-    /// This function calls AuthCounters::getStatistics() and
-    /// returns its return value.
-    ///
-    /// This function never throws an exception as far as
-    /// AuthCounters::getStatistics() doesn't throw.
-    ///
-    /// Note: Currently this function is for testing purpose only.
-    ///
-    /// \param type Type of a counter to get the value of
-    ///
-    /// \return the value of the counter.
-
-    uint64_t getCounter(const AuthCounters::ServerCounterType type) const;
-
-    /// \brief Get the value of per Opcode counter in the Auth Counters.
-    ///
-    /// This function calls AuthCounters::getCounter(isc::dns::Opcode) and
-    /// returns its return value.
-    ///
-    /// \note This is a tentative interface as an attempt of experimentally
-    /// supporting more statistics counters.  This should eventually be more
-    /// generalized.  In any case, this method is mainly for testing.
-    ///
-    /// \throw None
-    /// \param opcode The opcode of the counter to get the value of
-    /// \return the value of the counter.
-    uint64_t getCounter(const isc::dns::Opcode opcode) const;
-
-    /// \brief Get the value of per Rcode counter in the Auth Counters.
-    ///
-    /// This function calls AuthCounters::getCounter(isc::dns::Rcode) and
-    /// returns its return value.
-    ///
-    /// \note This is a tentative interface as an attempt of experimentally
-    /// supporting more statistics counters.  This should eventually be more
-    /// generalized.  In any case, this method is mainly for testing.
-    ///
-    /// \throw None
-    /// \param rcode The rcode of the counter to get the value of
-    /// \return the value of the counter.
-    uint64_t getCounter(const isc::dns::Rcode rcode) const;
-
     /**
      * \brief Set and get the addresses we listen on.
      */
diff --git a/src/bin/auth/benchmarks/Makefile.am b/src/bin/auth/benchmarks/Makefile.am
index 948e718..35e3179 100644
--- a/src/bin/auth/benchmarks/Makefile.am
+++ b/src/bin/auth/benchmarks/Makefile.am
@@ -15,7 +15,7 @@ query_bench_SOURCES = query_bench.cc
 query_bench_SOURCES += ../query.h  ../query.cc
 query_bench_SOURCES += ../auth_srv.h ../auth_srv.cc
 query_bench_SOURCES += ../auth_config.h ../auth_config.cc
-query_bench_SOURCES += ../statistics.h ../statistics.cc
+query_bench_SOURCES += ../statistics.h ../statistics.cc ../statistics_items.h
 query_bench_SOURCES += ../auth_log.h ../auth_log.cc
 
 nodist_query_bench_SOURCES = ../auth_messages.h ../auth_messages.cc
@@ -33,6 +33,5 @@ query_bench_LDADD += $(top_builddir)/src/lib/nsas/libb10-nsas.la
 query_bench_LDADD += $(top_builddir)/src/lib/asiolink/libb10-asiolink.la
 query_bench_LDADD += $(top_builddir)/src/lib/server_common/libb10-server-common.la
 query_bench_LDADD += $(top_builddir)/src/lib/asiodns/libb10-asiodns.la
-query_bench_LDADD += $(top_builddir)/src/lib/statistics/libb10-statistics.la
 query_bench_LDADD += $(SQLITE_LIBS)
 
diff --git a/src/bin/auth/statistics.cc b/src/bin/auth/statistics.cc
index 2d5f336..89c9d08 100644
--- a/src/bin/auth/statistics.cc
+++ b/src/bin/auth/statistics.cc
@@ -13,16 +13,15 @@
 // PERFORMANCE OF THIS SOFTWARE.
 
 #include <auth/statistics.h>
+#include <auth/statistics_items.h>
 #include <auth/auth_log.h>
 
 #include <dns/opcode.h>
+#include <dns/rcode.h>
 
 #include <cc/data.h>
 #include <cc/session.h>
 
-#include <statistics/counter.h>
-#include <statistics/counter_dict.h>
-
 #include <algorithm>
 #include <cctype>
 #include <cassert>
@@ -30,181 +29,215 @@
 #include <sstream>
 #include <iostream>
 
-#include <boost/noncopyable.hpp>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <netdb.h>
 
 using namespace isc::dns;
 using namespace isc::auth;
 using namespace isc::statistics;
 
-// TODO: We need a namespace ("auth_server"?) to hold
-// AuthSrv and AuthCounters.
-
-// TODO: Make use of wrappers like isc::dns::Opcode
-// for counter item type.
-
-class AuthCountersImpl : boost::noncopyable {
-public:
-    AuthCountersImpl();
-    ~AuthCountersImpl();
-    void inc(const AuthCounters::ServerCounterType type);
-    void inc(const Opcode opcode) {
-        opcode_counter_.inc(opcode.getCode());
-    }
-    void inc(const Rcode rcode) {
-        rcode_counter_.inc(rcode.getCode());
-    }
-    void inc(const std::string& zone,
-             const AuthCounters::PerZoneCounterType type);
-    isc::data::ConstElementPtr getStatistics() const;
-    void registerStatisticsValidator
-    (AuthCounters::validator_type validator);
-    // Currently for testing purpose only
-    uint64_t getCounter(const AuthCounters::ServerCounterType type) const;
-    uint64_t getCounter(const Opcode opcode) const {
-        return (opcode_counter_.get(opcode.getCode()));
-    }
-    uint64_t getCounter(const Rcode rcode) const {
-        return (rcode_counter_.get(rcode.getCode()));
-    }
-private:
-    Counter server_counter_;
-    Counter opcode_counter_;
-    static const size_t NUM_OPCODES = 16;
-    Counter rcode_counter_;
-    static const size_t NUM_RCODES = 17;
-    CounterDictionary per_zone_counter_;
-    AuthCounters::validator_type validator_;
-};
-
-AuthCountersImpl::AuthCountersImpl() :
-    // initialize counter
-    // size of server_counter_: AuthCounters::SERVER_COUNTER_TYPES
-    // size of per_zone_counter_: AuthCounters::PER_ZONE_COUNTER_TYPES
-    server_counter_(AuthCounters::SERVER_COUNTER_TYPES),
-    opcode_counter_(NUM_OPCODES), rcode_counter_(NUM_RCODES),
-    per_zone_counter_(AuthCounters::PER_ZONE_COUNTER_TYPES)
+namespace {
+
+void
+fillNodes(const Counter& counter, const char* const nodename[],
+          const size_t size,
+          isc::auth::statistics::Counters::ItemTreeType& trees)
 {
-    per_zone_counter_.addElement("_SERVER_");
+    using namespace isc::data;
+
+    for (size_t i = 0; i < size; ++i) {
+        trees->set (nodename[i],
+                    Element::create(static_cast<long int>(counter.get(i)))
+                    );
+    }
 }
 
-AuthCountersImpl::~AuthCountersImpl()
+} // anonymous namespace
+
+namespace isc {
+namespace auth {
+namespace statistics {
+
+Counters::Counters() :
+    // size of server_qr_counter_, zone_qr_counters_: QR_COUNTER_TYPES
+    // size of server_socket_counter_: SOCKET_COUNTER_TYPES
+    server_qr_counter_(QR_COUNTER_TYPES),
+    socket_counter_(SOCKET_COUNTER_TYPES),
+    zone_qr_counters_(QR_COUNTER_TYPES)
 {}
 
-void
-AuthCountersImpl::inc(const AuthCounters::ServerCounterType type) {
-    server_counter_.inc(type);
-}
+Counters::~Counters()
+{}
 
 void
-AuthCountersImpl::inc(const std::string& zone,
-                      const AuthCounters::PerZoneCounterType type)
-{
-    per_zone_counter_[zone].inc(type);
-}
+Counters::incRequest(const QRAttributes& qrattrs, const Message& response) {
+    // protocols carrying request
+    if (qrattrs.req_ip_version_ == AF_INET) {
+        server_qr_counter_.inc(QR_REQUEST_IPV4);
+    } else if (qrattrs.req_ip_version_ == AF_INET6) {
+        server_qr_counter_.inc(QR_REQUEST_IPV6);
+    }
+    if (qrattrs.req_transport_protocol_ == IPPROTO_UDP) {
+        server_qr_counter_.inc(QR_REQUEST_UDP);
+    } else if (qrattrs.req_transport_protocol_ == IPPROTO_TCP) {
+        server_qr_counter_.inc(QR_REQUEST_TCP);
+    }
 
-isc::data::ConstElementPtr
-AuthCountersImpl::getStatistics() const {
-    std::stringstream statistics_string;
-    statistics_string << "{ \"queries.udp\": "
-                      << server_counter_.get(AuthCounters::SERVER_UDP_QUERY)
-                      << ", \"queries.tcp\": "
-                      << server_counter_.get(AuthCounters::SERVER_TCP_QUERY);
-    // Insert non 0 Opcode counters.
-    for (int i = 0; i < NUM_OPCODES; ++i) {
-        const Counter::Type counter = opcode_counter_.get(i);
-        if (counter != 0) {
-            // The counter item name should be derived lower-cased textual
-            // representation of the code.
-            std::string opcode_txt = Opcode(i).toText();
-            std::transform(opcode_txt.begin(), opcode_txt.end(),
-                           opcode_txt.begin(), ::tolower);
-            statistics_string << ", \"opcode." << opcode_txt << "\": "
-                              << counter;
-        }
+    // query TSIG
+    if (qrattrs.req_is_tsig_) {
+        server_qr_counter_.inc(QR_REQUEST_TSIG);
     }
-    // Insert non 0 Rcode counters.
-    for (int i = 0; i < NUM_RCODES; ++i) {
-        const Counter::Type counter = rcode_counter_.get(i);
-        if (counter != 0) {
-            // The counter item name should be derived lower-cased textual
-            // representation of the code.
-            std::string rcode_txt = Rcode(i).toText();
-            std::transform(rcode_txt.begin(), rcode_txt.end(),
-                           rcode_txt.begin(), ::tolower);
-            statistics_string << ", \"rcode." << rcode_txt << "\": "
-                              << counter;
-        }
+    if (qrattrs.req_is_sig0_) {
+        server_qr_counter_.inc(QR_REQUEST_SIG0);
+    }
+    if (qrattrs.req_is_badsig_) {
+        server_qr_counter_.inc(QR_REQUEST_BADSIG);
+        // If signature validation is failed, no other query attributes are
+        // reliable. Skip processing of the rest of query counters.
+        return;
     }
-    statistics_string << "}";
 
-    isc::data::ConstElementPtr statistics_element =
-        isc::data::Element::fromJSON(statistics_string);
-    // validate the statistics data before send
-    if (validator_) {
-        if (!validator_(statistics_element)) {
-            LOG_ERROR(auth_logger, AUTH_INVALID_STATISTICS_DATA);
-            return (isc::data::ElementPtr());
+    // query EDNS
+    if (qrattrs.req_is_edns_0_) {
+        server_qr_counter_.inc(QR_REQUEST_EDNS0);
+    }
+    if (qrattrs.req_is_edns_badver_) {
+        server_qr_counter_.inc(QR_REQUEST_BADEDNSVER);
+    }
+
+    // query DNSSEC
+    if (qrattrs.req_is_dnssec_ok_) {
+        server_qr_counter_.inc(QR_REQUEST_DNSSEC_OK);
+    }
+
+    // QTYPE
+    unsigned int qtype_type = QR_QTYPE_OTHER;
+    const QuestionIterator qiter = response.beginQuestion();
+    if (qiter != response.endQuestion()) {
+        // get the first and only question section
+        const QuestionPtr qptr = *qiter;
+        if (qptr != NULL) {
+            // get the qtype code
+            const unsigned int qtype = qptr->getType().getCode();
+            if (qtype < 258) {
+                // qtype 0..257
+                qtype_type = QRQTypeToQRCounterType[qtype];
+            } else if (qtype < 32768) {
+                // qtype 258..32767
+                qtype_type = QR_QTYPE_OTHER;
+            } else if (qtype < 32770) {
+                // qtype 32768..32769
+                qtype_type = QR_QTYPE_TA + (qtype - 32768);
+            } else {
+                // qtype 32770..65535
+                qtype_type = QR_QTYPE_OTHER;
+            }
         }
     }
-    return (statistics_element);
+    server_qr_counter_.inc(qtype_type);
+    // OPCODE
+    server_qr_counter_.inc(QROpCodeToQRCounterType[qrattrs.req_opcode_]);
 }
 
 void
-AuthCountersImpl::registerStatisticsValidator
-    (AuthCounters::validator_type validator)
-{
-    validator_ = validator;
-}
+Counters::incResponse(const QRAttributes& qrattrs, const Message& response) {
+    // responded
+    server_qr_counter_.inc(QR_RESPONSE);
 
-// Currently for testing purpose only
-uint64_t
-AuthCountersImpl::getCounter(const AuthCounters::ServerCounterType type) const {
-    return (server_counter_.get(type));
-}
+    // response truncated
+    if (qrattrs.res_is_truncated_) {
+        server_qr_counter_.inc(QR_RESPONSE_TRUNCATED);
+    }
 
-AuthCounters::AuthCounters() : impl_(new AuthCountersImpl())
-{}
+    // response EDNS
+    ConstEDNSPtr response_edns = response.getEDNS();
+    if (response_edns != NULL && response_edns->getVersion() == 0) {
+        server_qr_counter_.inc(QR_RESPONSE_EDNS0);
+    }
 
-AuthCounters::~AuthCounters() {}
+    // response TSIG
+    if (qrattrs.req_is_tsig_) {
+        // assume response is TSIG signed if request is TSIG signed
+        server_qr_counter_.inc(QR_RESPONSE_TSIG);
+    }
 
-void
-AuthCounters::inc(const AuthCounters::ServerCounterType type) {
-    impl_->inc(type);
-}
+    // response SIG(0) is currently not implemented
+
+    // RCODE
+    const unsigned int rcode = response.getRcode().getCode();
+    unsigned int rcode_type = QR_RCODE_OTHER;
+    if (rcode < 23) {
+        // rcode 0..22
+        rcode_type = QRRCodeToQRCounterType[rcode];
+    } else {
+        // opcode larger than 22 is reserved or unassigned
+        rcode_type = QR_RCODE_OTHER;
+    }
+    server_qr_counter_.inc(rcode_type);
+
+    // compound attributes
+    const unsigned int answer_rrs =
+        response.getRRCount(Message::SECTION_ANSWER);
+    const bool is_aa_set = response.getHeaderFlag(Message::HEADERFLAG_AA);
+
+    if (is_aa_set) {
+        // QryAuthAns
+        server_qr_counter_.inc(QR_QRYAUTHANS);
+    } else {
+        // QryNoAuthAns
+        server_qr_counter_.inc(QR_QRYNOAUTHANS);
+    }
 
-void
-AuthCounters::inc(const Opcode opcode) {
-    impl_->inc(opcode);
+    if (rcode == Rcode::NOERROR_CODE) {
+        if (answer_rrs > 0) {
+            // QrySuccess
+            server_qr_counter_.inc(QR_QRYSUCCESS);
+        } else {
+            if (is_aa_set) {
+                // QryNxrrset
+                server_qr_counter_.inc(QR_QRYNXRRSET);
+            } else {
+                // QryReferral
+                server_qr_counter_.inc(QR_QRYREFERRAL);
+            }
+        }
+    } else if (rcode == Rcode::REFUSED_CODE) {
+        // AuthRej
+        server_qr_counter_.inc(QR_QRYREJECT);
+    }
 }
 
 void
-AuthCounters::inc(const Rcode rcode) {
-    impl_->inc(rcode);
-}
+Counters::inc(const QRAttributes& qrattrs, const Message& response) {
+    // increment request counters
+    incRequest(qrattrs, response);
 
-isc::data::ConstElementPtr
-AuthCounters::getStatistics() const {
-    return (impl_->getStatistics());
+    if (qrattrs.answer_sent_) {
+        // increment response counters if answer was sent
+        incResponse(qrattrs, response);
+    }
 }
 
-uint64_t
-AuthCounters::getCounter(const AuthCounters::ServerCounterType type) const {
-    return (impl_->getCounter(type));
-}
+Counters::ItemTreeType
+Counters::get() const {
+    using namespace isc::data;
 
-uint64_t
-AuthCounters::getCounter(const Opcode opcode) const {
-    return (impl_->getCounter(opcode));
-}
+    Counters::ItemTreeType item_tree = Element::createMap();
 
-uint64_t
-AuthCounters::getCounter(const Rcode rcode) const {
-    return (impl_->getCounter(rcode));
-}
+    Counters::ItemTreeType zones = Element::createMap();
+    item_tree->set("zones", zones);
 
-void
-AuthCounters::registerStatisticsValidator
-    (AuthCounters::validator_type validator) const
-{
-    return (impl_->registerStatisticsValidator(validator));
+    Counters::ItemTreeType server = Element::createMap();
+    fillNodes(server_qr_counter_, QRCounterItemName, QR_COUNTER_TYPES,
+              server);
+    zones->set("_SERVER_", server);
+
+    return (item_tree);
 }
+
+} // namespace statistics
+} // namespace auth
+} // namespace isc
diff --git a/src/bin/auth/statistics.h b/src/bin/auth/statistics.h
index 0ca8da4..7de4813 100644
--- a/src/bin/auth/statistics.h
+++ b/src/bin/auth/statistics.h
@@ -15,19 +15,172 @@
 #ifndef __STATISTICS_H
 #define __STATISTICS_H 1
 
-#include <dns/opcode.h>
-#include <dns/rcode.h>
 #include <cc/session.h>
 #include <cc/data.h>
 
+#include <dns/message.h>
+
+#include <statistics/counter.h>
+#include <statistics/counter_dict.h>
+
+#include <boost/noncopyable.hpp>
+
+#include <string>
+
 #include <stdint.h>
-#include <boost/scoped_ptr.hpp>
 
-class AuthCountersImpl;
+namespace isc {
+namespace auth {
+namespace statistics {
+
+class QRAttributes {
+/// \brief Query/Response attributes for statistics.
+///
+/// This class holds some attributes related to a query/response
+/// for statistics data collection.
+///
+/// This class does not have getter methods since it exposes private members
+/// to \c Counters directly.
+friend class Counters;
+private:
+    // request attributes
+    int req_ip_version_;            // IP version
+    int req_transport_protocol_;    // Transport layer protocol
+    int req_opcode_;                // OpCode
+    bool req_is_edns_0_;            // EDNS ver.0
+    bool req_is_edns_badver_;       // other EDNS version
+    bool req_is_dnssec_ok_;         // DO bit
+    bool req_is_tsig_;              // signed with valid TSIG
+    bool req_is_sig0_;              // signed with valid SIG(0)
+    bool req_is_badsig_;            // signed but bad signature
+    // zone origin
+    std::string zone_origin_;       // zone origin
+    // response attributes
+    bool answer_sent_;              // DNS message has sent
+    bool res_is_truncated_;         // DNS message is truncated
+public:
+    /// The constructor.
+    ///
+    /// This constructor is mostly exception free. But it may still throw
+    /// a standard exception if memory allocation fails inside the method.
+    ///
+    inline QRAttributes();
+    /// The destructor.
+    ///
+    /// This method never throws an exception.
+    ///
+    inline ~QRAttributes();
+    /// \brief Set query opcode.
+    /// \throw None
+    inline void setQueryOpCode(const int opcode);
+    /// \brief Set IP version carrying a query.
+    /// \throw None
+    inline void setQueryIPVersion(const int ip_version);
+    /// \brief Set transport protocol carrying a query.
+    /// \throw None
+    inline void setQueryTransportProtocol(const int transport_protocol);
+    /// \brief Set query EDNS attributes.
+    /// \throw None
+    inline void setQueryEDNS(const bool is_edns_0, const bool is_edns_badver);
+    /// \brief Set query DO bit.
+    /// \throw None
+    inline void setQueryDO(const bool is_dnssec_ok);
+    /// \brief Set query TSIG attributes.
+    /// \throw None
+    inline void setQuerySig(const bool is_tsig, const bool is_sig0,
+                            const bool is_badsig);
+    /// \brief Set zone origin.
+    /// \throw None
+    inline void setOrigin(const std::string& origin);
+    /// \brief Set if the answer has sent.
+    /// \throw None
+    inline void answerWasSent();
+    /// \brief Set if the response is truncated.
+    /// \throw None
+    inline void setResponseTruncated(const bool is_truncated);
+    /// \brief Reset attributes.
+    /// \throw None
+    inline void reset();
+};
+
+inline QRAttributes::QRAttributes() :
+    req_ip_version_(0), req_transport_protocol_(0),
+    req_opcode_(0),
+    req_is_edns_0_(false), req_is_edns_badver_(false),
+    req_is_dnssec_ok_(false),
+    req_is_tsig_(false), req_is_sig0_(false), req_is_badsig_(false),
+    zone_origin_(),
+    answer_sent_(false),
+    res_is_truncated_(false)
+{}
+
+inline QRAttributes::~QRAttributes()
+{}
+
+inline void
+QRAttributes::setQueryIPVersion(const int ip_version) {
+    req_ip_version_ = ip_version;
+}
+
+inline void
+QRAttributes::setQueryTransportProtocol(const int transport_protocol) {
+    req_transport_protocol_ = transport_protocol;
+}
+
+inline void
+QRAttributes::setQueryOpCode(const int opcode) {
+    req_opcode_ = opcode;
+}
+
+inline void
+QRAttributes::setQueryEDNS(const bool is_edns_0, const bool is_edns_badver) {
+    req_is_edns_0_ = is_edns_0;
+    req_is_edns_badver_ = is_edns_badver;
+}
+
+inline void
+QRAttributes::setQueryDO(const bool is_dnssec_ok) {
+    req_is_dnssec_ok_ = is_dnssec_ok;
+}
+
+inline void
+QRAttributes::setQuerySig(const bool is_tsig, const bool is_sig0,
+                          const bool is_badsig)
+{
+    req_is_tsig_ = is_tsig;
+    req_is_sig0_ = is_sig0;
+    req_is_badsig_ = is_badsig;
+}
+
+inline void
+QRAttributes::answerWasSent() {
+    answer_sent_ = true;
+}
+
+inline void
+QRAttributes::setResponseTruncated(const bool is_truncated) {
+    res_is_truncated_ = is_truncated;
+}
+
+inline void
+QRAttributes::reset() {
+    req_ip_version_ = 0;
+    req_transport_protocol_ = 0;
+    req_opcode_ = 0;
+    req_is_edns_0_ = false;
+    req_is_edns_badver_ = false;
+    req_is_dnssec_ok_ = false;
+    req_is_tsig_ = false;
+    req_is_sig0_ = false;
+    req_is_badsig_ = false;
+    zone_origin_.clear();
+    answer_sent_ = false;
+    res_is_truncated_ = false;
+}
 
 /// \brief Set of query counters.
 ///
-/// \c AuthCounters is set of query counters class. It holds query counters
+/// \c Counters is set of query counters class. It holds query counters
 /// and provides an interface to increment the counter of specified type
 /// (e.g. UDP query, TCP query).
 ///
@@ -35,9 +188,7 @@ class AuthCountersImpl;
 /// statistics module.
 ///
 /// This class is designed to be a part of \c AuthSrv.
-/// Call \c inc() to increment a counter for specific type of query in
-/// the query processing function. use \c enum \c CounterType to specify
-/// the type of query.
+/// Call \c inc() to increment a counter for the query.
 /// Call \c getStatistics() to answer statistics information to statistics
 /// module with statistics_session, when the command \c getstats is received.
 ///
@@ -50,134 +201,73 @@ class AuthCountersImpl;
 /// construction overhead of this approach should be acceptable.
 ///
 /// \todo Hold counters for each query types (Notify, Axfr, Ixfr, Normal)
-/// \todo Consider overhead of \c AuthCounters::inc()
-class AuthCounters {
+/// \todo Consider overhead of \c Counters::inc()
+class Counters : boost::noncopyable {
 private:
-    boost::scoped_ptr<AuthCountersImpl> impl_;
+    // counter for query/response
+    isc::statistics::Counter server_qr_counter_;
+    // counter for socket
+    isc::statistics::Counter socket_counter_;
+    // set of counters for zones
+    isc::statistics::CounterDictionary zone_qr_counters_;
+    void incRequest(const QRAttributes& qrattrs,
+                    const isc::dns::Message& response);
+    void incResponse(const QRAttributes& qrattrs,
+                     const isc::dns::Message& response);
 public:
-    // Enum for the type of counter
-    enum ServerCounterType {
-        SERVER_UDP_QUERY,       ///< SERVER_UDP_QUERY: counter for UDP queries
-        SERVER_TCP_QUERY,       ///< SERVER_TCP_QUERY: counter for TCP queries
-        SERVER_COUNTER_TYPES    ///< The number of defined counters
-    };
-    enum PerZoneCounterType {
-        ZONE_UDP_QUERY,         ///< ZONE_UDP_QUERY: counter for UDP queries
-        ZONE_TCP_QUERY,         ///< ZONE_TCP_QUERY: counter for TCP queries
-        PER_ZONE_COUNTER_TYPES  ///< The number of defined counters
-    };
+    /// \brief A type of statistics item tree in isc::data::MapElement.
+    ///        {
+    ///          zone_name => {
+    ///                         item_name => item_value,
+    ///                         item_name => item_value, ...
+    ///                       },
+    ///          ...
+    ///        }
+    ///        item_name is a string seperated by '.'.
+    ///        item_value is an integer.
+    ///
+    typedef isc::data::ElementPtr ItemTreeType;
+
     /// The constructor.
     ///
     /// This constructor is mostly exception free. But it may still throw
     /// a standard exception if memory allocation fails inside the method.
     ///
-    AuthCounters();
+    Counters();
     /// The destructor.
     ///
     /// This method never throws an exception.
     ///
-    ~AuthCounters();
-
-    /// \brief Increment the counter specified by the parameter.
-    ///
-    /// \param type Type of a counter to increment.
-    ///
-    /// \throw std::out_of_range \a type is unknown.
-    ///
-    /// usage: counter.inc(AuthCounters::SERVER_UDP_QUERY);
-    /// 
-    void inc(const ServerCounterType type);
+    ~Counters();
 
-    /// \brief Increment the counter of a per opcode counter.
-    ///
-    /// \note This is a tentative interface.  See \c getCounter().
+    /// \brief Increment counters according to the parameters.
     ///
-    /// \param opcode The opcode of the counter to increment.
-    ///
-    /// \throw None
-    void inc(const isc::dns::Opcode opcode);
-
-    /// \brief Increment the counter of a per rcode counter.
+    /// This constructor is mostly exception free. But it may still throw
+    /// a standard exception if memory allocation fails inside the method.
     ///
-    /// \note This is a tentative interface.  See \c getCounter().
+    /// \param qrattrs Query/Response attributes.
+    /// \param response DNS response message.
     ///
-    /// \param rcode The rcode of the counter to increment.
+    /// \throw std::bad_alloc Internal resource allocation fails
     ///
-    /// \throw None
-    void inc(const isc::dns::Rcode rcode);
+    void inc(const QRAttributes& qrattrs, const isc::dns::Message& response);
 
-    /// \brief Answers statistics counters to statistics module.
+    /// \brief Get statistics counters.
     ///
-    /// This method is mostly exception free (error conditions are
-    /// represented via the return value). But it may still throw
+    /// This method is mostly exception free. But it may still throw
     /// a standard exception if memory allocation fails inside the method.
     ///
     /// \return statistics data
     ///
-    isc::data::ConstElementPtr getStatistics() const;
-
-    /// \brief Get the value of a counter in the AuthCounters.
-    ///
-    /// This function returns a value of the counter specified by \a type.
-    /// This method never throws an exception.
-    ///
-    /// Note: Currently this function is for testing purpose only.
-    ///
-    /// \param type Type of a counter to get the value of
+    /// \throw std::bad_alloc Internal resource allocation fails
     ///
-    /// \return the value of the counter specified by \a type.
-    uint64_t getCounter(const AuthCounters::ServerCounterType type) const;
-
-    /// \brief Get the value of a per opcode counter.
-    ///
-    /// This method returns the value of the per opcode counter for the
-    /// specified \c opcode.
-    ///
-    /// \note This is a tentative interface as an attempt of experimentally
-    /// supporting more statistics counters.  This should eventually be more
-    /// generalized.  In any case, this method is mainly for testing.
-    ///
-    /// \throw None
-    /// \param opcode The opcode of the counter to get the value of
-    /// \return the value of the counter.
-    uint64_t getCounter(const isc::dns::Opcode opcode) const;
-
-    /// \brief Get the value of a per rcode counter.
-    ///
-    /// This method returns the value of the per rcode counter for the
-    /// specified \c rcode.
-    ///
-    /// \note As mentioned in getCounter(const isc::dns::Opcode opcode),
-    /// This is a tentative interface as an attempt of experimentally
-    /// supporting more statistics counters.  This should eventually be more
-    /// generalized.  In any case, this method is mainly for testing.
-    ///
-    /// \throw None
-    /// \param rcode The rcode of the counter to get the value of
-    /// \return the value of the counter.
-    uint64_t getCounter(const isc::dns::Rcode rcode) const;
-
-    /// \brief A type of validation function for the specification in
-    /// isc::config::ModuleSpec.
-    ///
-    /// This type might be useful for not only statistics
-    /// specificatoin but also for config_data specification and for
-    /// commnad.
-    ///
-    typedef boost::function<bool(const isc::data::ConstElementPtr&)>
-    validator_type;
-
-    /// \brief Register a function type of the statistics validation
-    /// function for AuthCounters.
-    ///
-    /// This method never throws an exception.
-    ///
-    /// \param validator A function type of the validation of
-    /// statistics specification.
-    ///
-    void registerStatisticsValidator(AuthCounters::validator_type validator) const;
+    ItemTreeType get() const;
 };
 
+} // namespace statistics
+} // namespace auth
+} // namespace isc
+
 #endif // __STATISTICS_H
 
 // Local Variables:
diff --git a/src/bin/auth/statistics_items.h b/src/bin/auth/statistics_items.h
new file mode 100644
index 0000000..9404576
--- /dev/null
+++ b/src/bin/auth/statistics_items.h
@@ -0,0 +1,682 @@
+// Copyright (C) 2012  Internet Systems Consortium, Inc. ("ISC")
+//
+// Permission to use, copy, modify, and/or distribute this software for any
+// purpose with or without fee is hereby granted, provided that the above
+// copyright notice and this permission notice appear in all copies.
+//
+// THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+// AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+// PERFORMANCE OF THIS SOFTWARE.
+
+#ifndef __STATISTICS_ITEMS_H
+#define __STATISTICS_ITEMS_H 1
+
+/// This file defines a set of statistics items in Auth module for internal
+/// use. This file is intended to be included in statistics.cc.
+
+namespace {
+
+// enum for socket statistics
+enum SocketCounterType {
+    // Socket statistics
+    SOCKET_IPV4_UDP_BINDFAIL,        ///< IPv4 UDP sockets bind failures
+    SOCKET_IPV4_UDP_CLOSE,           ///< IPv4 UDP sockets closed
+    SOCKET_IPV4_UDP_CONN,            ///< IPv4 UDP connections established successfully
+    SOCKET_IPV4_UDP_CONNFAIL,        ///< IPv4 UDP sockets connection failures
+    SOCKET_IPV4_UDP_OPEN,            ///< IPv4 UDP sockets opened successfully
+    SOCKET_IPV4_UDP_OPENFAIL,        ///< IPv4 UDP sockets open failures
+    SOCKET_IPV4_UDP_RECVERR,         ///< IPv4 UDP sockets receive errors
+    SOCKET_IPV4_UDP_SENDERR,         ///< IPv4 UDP sockets send errors
+    SOCKET_IPV4_TCP_ACCEPT,          ///< IPv4 TCP incoming connections successfully accepted
+    SOCKET_IPV4_TCP_ACCEPTFAIL,      ///< IPv4 TCP incoming accept failures
+    SOCKET_IPV4_TCP_BINDFAIL,        ///< IPv4 TCP sockets bind failures
+    SOCKET_IPV4_TCP_CLOSE,           ///< IPv4 TCP sockets closed
+    SOCKET_IPV4_TCP_CONN,            ///< IPv4 TCP connections established successfully
+    SOCKET_IPV4_TCP_CONNFAIL,        ///< IPv4 TCP sockets connection failures
+    SOCKET_IPV4_TCP_OPEN,            ///< IPv4 TCP sockets opened successfully
+    SOCKET_IPV4_TCP_OPENFAIL,        ///< IPv4 TCP sockets open failures
+    SOCKET_IPV4_TCP_RECVERR,         ///< IPv4 TCP sockets receive errors
+    SOCKET_IPV4_TCP_SENDERR,         ///< IPv4 TCP sockets send errors
+    SOCKET_IPV6_UDP_BINDFAIL,        ///< IPv6 UDP sockets bind failures
+    SOCKET_IPV6_UDP_CLOSE,           ///< IPv6 UDP sockets closed
+    SOCKET_IPV6_UDP_CONN,            ///< IPv6 UDP connections established successfully
+    SOCKET_IPV6_UDP_CONNFAIL,        ///< IPv6 UDP sockets connection failures
+    SOCKET_IPV6_UDP_OPEN,            ///< IPv6 UDP sockets opened successfully
+    SOCKET_IPV6_UDP_OPENFAIL,        ///< IPv6 UDP sockets open failures
+    SOCKET_IPV6_UDP_RECVERR,         ///< IPv6 UDP sockets receive errors
+    SOCKET_IPV6_UDP_SENDERR,         ///< IPv6 UDP sockets send errors
+    SOCKET_IPV6_TCP_ACCEPT,          ///< IPv6 TCP incoming connections successfully accepted
+    SOCKET_IPV6_TCP_ACCEPTFAIL,      ///< IPv6 TCP incoming accept failures
+    SOCKET_IPV6_TCP_BINDFAIL,        ///< IPv6 TCP sockets bind failures
+    SOCKET_IPV6_TCP_CLOSE,           ///< IPv6 TCP sockets closed
+    SOCKET_IPV6_TCP_CONN,            ///< IPv6 TCP connections established successfully
+    SOCKET_IPV6_TCP_CONNFAIL,        ///< IPv6 TCP sockets connection failures
+    SOCKET_IPV6_TCP_OPEN,            ///< IPv6 TCP sockets opened successfully
+    SOCKET_IPV6_TCP_OPENFAIL,        ///< IPv6 TCP sockets open failures
+    SOCKET_IPV6_TCP_RECVERR,         ///< IPv6 TCP sockets receive errors
+    SOCKET_IPV6_TCP_SENDERR,         ///< IPv6 TCP sockets send errors
+    SOCKET_UNIXDOMAIN_ACCEPT,        ///< Unix Domain sockets incoming connections successfully accepted
+    SOCKET_UNIXDOMAIN_ACCEPTFAIL,    ///< Unix Domain sockets incoming accept failures
+    SOCKET_UNIXDOMAIN_BINDFAIL,      ///< Unix Domain sockets bind failures
+    SOCKET_UNIXDOMAIN_CLOSE,         ///< Unix Domain sockets closed
+    SOCKET_UNIXDOMAIN_CONN,          ///< Unix Domain connections established successfully
+    SOCKET_UNIXDOMAIN_CONNFAIL,      ///< Unix Domain sockets connection failures
+    SOCKET_UNIXDOMAIN_OPEN,          ///< Unix Domain sockets opened successfully
+    SOCKET_UNIXDOMAIN_OPENFAIL,      ///< Unix Domain sockets open failures
+    SOCKET_UNIXDOMAIN_RECVERR,       ///< Unix Domain sockets receive errors
+    SOCKET_UNIXDOMAIN_SENDERR,       ///< Unix Domain sockets send errors
+    SOCKET_COUNTER_TYPES             ///< The number of defined counters
+};
+// item names for socket statistics
+const char* const SocketCounterItemName[SOCKET_COUNTER_TYPES] = {
+    "ipv4.udp.bindfail",
+    "ipv4.udp.close",
+    "ipv4.udp.conn",
+    "ipv4.udp.connfail",
+    "ipv4.udp.open",
+    "ipv4.udp.openfail",
+    "ipv4.udp.recverr",
+    "ipv4.udp.senderr",
+    "ipv4.tcp.accept",
+    "ipv4.tcp.acceptfail",
+    "ipv4.tcp.bindfail",
+    "ipv4.tcp.close",
+    "ipv4.tcp.conn",
+    "ipv4.tcp.connfail",
+    "ipv4.tcp.open",
+    "ipv4.tcp.openfail",
+    "ipv4.tcp.recverr",
+    "ipv4.tcp.senderr",
+    "ipv6.udp.bindfail",
+    "ipv6.udp.close",
+    "ipv6.udp.conn",
+    "ipv6.udp.connfail",
+    "ipv6.udp.open",
+    "ipv6.udp.openfail",
+    "ipv6.udp.recverr",
+    "ipv6.udp.senderr",
+    "ipv6.tcp.accept",
+    "ipv6.tcp.acceptfail",
+    "ipv6.tcp.bindfail",
+    "ipv6.tcp.close",
+    "ipv6.tcp.conn",
+    "ipv6.tcp.connfail",
+    "ipv6.tcp.open",
+    "ipv6.tcp.openfail",
+    "ipv6.tcp.recverr",
+    "ipv6.tcp.senderr",
+    "unixdomain.accept",
+    "unixdomain.acceptfail",
+    "unixdomain.bindfail",
+    "unixdomain.close",
+    "unixdomain.conn",
+    "unixdomain.connfail",
+    "unixdomain.open",
+    "unixdomain.openfail",
+    "unixdomain.recverr",
+    "unixdomain.senderr"
+};
+
+// enum for query/response counters
+enum QRCounterType {
+    // Request Attributes
+    QR_REQUEST_IPV4,        ///< Number of IPv4 requests received
+    QR_REQUEST_IPV6,        ///< Number of IPv6 requests received
+    QR_REQUEST_EDNS0,       ///< Number of requests with EDNS(0) received
+    QR_REQUEST_BADEDNSVER,  ///< Number of requests with unsupported EDNS version received
+    QR_REQUEST_TSIG,        ///< Number of requests with TSIG received
+    QR_REQUEST_SIG0,        ///< Number of requests with SIG(0) received; not implemented in BIND 10
+    QR_REQUEST_BADSIG,      ///< Number of requests with invalid TSIG or SIG(0) signature received
+    QR_REQUEST_UDP,         ///< Number of UDP requests received
+    QR_REQUEST_TCP,         ///< Number of TCP requests received
+    QR_REQUEST_DNSSEC_OK,   ///< Number of requests with DO bit
+    // Request Opcodes
+    QR_OPCODE_QUERY,        ///< Number of Opcode=QUERY requests received
+    QR_OPCODE_IQUERY,       ///< Number of Opcode=IQUERY requests received
+    QR_OPCODE_STATUS,       ///< Number of Opcode=STATUS requests received
+    QR_OPCODE_NOTIFY,       ///< Number of Opcode=NOTIFY requests received
+    QR_OPCODE_UPDATE,       ///< Number of Opcode=UPDATE requests received
+    QR_OPCODE_OTHER,        ///< Number of requests in other OpCode received
+    // Query Types
+    QR_QTYPE_A,             ///< Number of QTYPE = A queries received
+    QR_QTYPE_NS,            ///< Number of QTYPE = NS queries received
+    QR_QTYPE_MD,            ///< Number of QTYPE = MD queries received
+    QR_QTYPE_MF,            ///< Number of QTYPE = MF queries received
+    QR_QTYPE_CNAME,         ///< Number of QTYPE = CNAME queries received
+    QR_QTYPE_SOA,           ///< Number of QTYPE = SOA queries received
+    QR_QTYPE_MB,            ///< Number of QTYPE = MB queries received
+    QR_QTYPE_MG,            ///< Number of QTYPE = MG queries received
+    QR_QTYPE_MR,            ///< Number of QTYPE = MR queries received
+    QR_QTYPE_NULL,          ///< Number of QTYPE = NULL queries received
+    QR_QTYPE_WKS,           ///< Number of QTYPE = WKS queries received
+    QR_QTYPE_PTR,           ///< Number of QTYPE = PTR queries received
+    QR_QTYPE_HINFO,         ///< Number of QTYPE = HINFO queries received
+    QR_QTYPE_MINFO,         ///< Number of QTYPE = MINFO queries received
+    QR_QTYPE_MX,            ///< Number of QTYPE = MX queries received
+    QR_QTYPE_TXT,           ///< Number of QTYPE = TXT queries received
+    QR_QTYPE_RP,            ///< Number of QTYPE = RP queries received
+    QR_QTYPE_AFSDB,         ///< Number of QTYPE = AFSDB queries received
+    QR_QTYPE_X25,           ///< Number of QTYPE = X25 queries received
+    QR_QTYPE_ISDN,          ///< Number of QTYPE = ISDN queries received
+    QR_QTYPE_RT,            ///< Number of QTYPE = RT queries received
+    QR_QTYPE_NSAP,          ///< Number of QTYPE = NSAP queries received
+    QR_QTYPE_NSAP_PTR,      ///< Number of QTYPE = NSAP-PTR queries received
+    QR_QTYPE_SIG,           ///< Number of QTYPE = SIG queries received
+    QR_QTYPE_KEY,           ///< Number of QTYPE = KEY queries received
+    QR_QTYPE_PX,            ///< Number of QTYPE = PX queries received
+    QR_QTYPE_GPOS,          ///< Number of QTYPE = GPOS queries received
+    QR_QTYPE_AAAA,          ///< Number of QTYPE = AAAA queries received
+    QR_QTYPE_LOC,           ///< Number of QTYPE = LOC queries received
+    QR_QTYPE_NXT,           ///< Number of QTYPE = NXT queries received
+    QR_QTYPE_EID,           ///< Number of QTYPE = EID queries received
+    QR_QTYPE_NIMLOC,        ///< Number of QTYPE = NIMLOC queries received
+    QR_QTYPE_SRV,           ///< Number of QTYPE = SRV queries received
+    QR_QTYPE_ATMA,          ///< Number of QTYPE = ATMA queries received
+    QR_QTYPE_NAPTR,         ///< Number of QTYPE = NAPTR queries received
+    QR_QTYPE_KX,            ///< Number of QTYPE = KX queries received
+    QR_QTYPE_CERT,          ///< Number of QTYPE = CERT queries received
+    QR_QTYPE_A6,            ///< Number of QTYPE = A6 queries received
+    QR_QTYPE_DNAME,         ///< Number of QTYPE = DNAME queries received
+    QR_QTYPE_SINK,          ///< Number of QTYPE = SINK queries received
+    QR_QTYPE_OPT,           ///< Number of QTYPE = OPT queries received
+    QR_QTYPE_APL,           ///< Number of QTYPE = APL queries received
+    QR_QTYPE_DS,            ///< Number of QTYPE = DS queries received
+    QR_QTYPE_SSHFP,         ///< Number of QTYPE = SSHFP queries received
+    QR_QTYPE_IPSECKEY,      ///< Number of QTYPE = IPSECKEY queries received
+    QR_QTYPE_RRSIG,         ///< Number of QTYPE = RRSIG queries received
+    QR_QTYPE_NSEC,          ///< Number of QTYPE = NSEC queries received
+    QR_QTYPE_DNSKEY,        ///< Number of QTYPE = DNSKEY queries received
+    QR_QTYPE_DHCID,         ///< Number of QTYPE = DHCID queries received
+    QR_QTYPE_NSEC3,         ///< Number of QTYPE = NSEC3 queries received
+    QR_QTYPE_NSEC3PARAM,    ///< Number of QTYPE = NSEC3PARAM queries received
+    QR_QTYPE_HIP,           ///< Number of QTYPE = HIP queries received
+    QR_QTYPE_NINFO,         ///< Number of QTYPE = NINFO queries received
+    QR_QTYPE_RKEY,          ///< Number of QTYPE = RKEY queries received
+    QR_QTYPE_TALINK,        ///< Number of QTYPE = TALINK queries received
+    QR_QTYPE_SPF,           ///< Number of QTYPE = SPF queries received
+    QR_QTYPE_UINFO,         ///< Number of QTYPE = UINFO queries received
+    QR_QTYPE_UID,           ///< Number of QTYPE = UID queries received
+    QR_QTYPE_GID,           ///< Number of QTYPE = GID queries received
+    QR_QTYPE_UNSPEC,        ///< Number of QTYPE = UNSPEC queries received
+    QR_QTYPE_TKEY,          ///< Number of QTYPE = TKEY queries received
+    QR_QTYPE_TSIG,          ///< Number of QTYPE = TSIG queries received
+    QR_QTYPE_IXFR,          ///< Number of QTYPE = IXFR queries received
+    QR_QTYPE_AXFR,          ///< Number of QTYPE = AXFR queries received
+    QR_QTYPE_MAILB,         ///< Number of QTYPE = MAILB queries received
+    QR_QTYPE_MAILA,         ///< Number of QTYPE = MAILA queries received
+    QR_QTYPE_URI,           ///< Number of QTYPE = URI queries received
+    QR_QTYPE_CAA,           ///< Number of QTYPE = CAA queries received
+    QR_QTYPE_TA,            ///< Number of QTYPE = TA queries received
+    QR_QTYPE_DLV,           ///< Number of QTYPE = DLV queries received
+    QR_QTYPE_OTHER,         ///< Number of queries in other QTYPE received
+    // Respose Attributes
+    QR_RESPONSE,            ///< Number of responses sent
+    QR_RESPONSE_TRUNCATED,  ///< Number of truncated responses sent
+    QR_RESPONSE_EDNS0,      ///< Number of responses with EDNS0; not implemented in BIND 10
+    QR_RESPONSE_TSIG,       ///< Number of responses with TSIG
+    QR_RESPONSE_SIG0,       ///< Number of responses with SIG(0); not implemented in BIND 10
+    QR_QRYSUCCESS,          ///< Number of queries resulted in rcode = NOERROR and answer RR >= 1
+    QR_QRYAUTHANS,          ///< Number of queries resulted in authoritative answer
+    QR_QRYNOAUTHANS,        ///< Number of queries resulted in non-authoritative answer
+    QR_QRYREFERRAL,         ///< Number of queries resulted in referral answer
+    QR_QRYNXRRSET,          ///< Number of queries resulted in NOERROR but answer RR == 0
+    QR_QRYREJECT,           ///< Number of queries rejected
+    // Response Rcodes
+    QR_RCODE_NOERROR,       ///< Number of queries resulted in RCODE = 0 (NoError)
+    QR_RCODE_FORMERR,       ///< Number of queries resulted in RCODE = 1 (FormErr)
+    QR_RCODE_SERVFAIL,      ///< Number of queries resulted in RCODE = 2 (ServFail)
+    QR_RCODE_NXDOMAIN,      ///< Number of queries resulted in RCODE = 3 (NXDomain)
+    QR_RCODE_NOTIMP,        ///< Number of queries resulted in RCODE = 4 (NotImp)
+    QR_RCODE_REFUSED,       ///< Number of queries resulted in RCODE = 5 (Refused)
+    QR_RCODE_YXDOMAIN,      ///< Number of queries resulted in RCODE = 6 (YXDomain)
+    QR_RCODE_YXRRSET,       ///< Number of queries resulted in RCODE = 7 (YXRRSet)
+    QR_RCODE_NXRRSET,       ///< Number of queries resulted in RCODE = 8 (NXRRSet)
+    QR_RCODE_NOTAUTH,       ///< Number of queries resulted in RCODE = 9 (NotAuth)
+    QR_RCODE_NOTZONE,       ///< Number of queries resulted in RCODE = 10 (NotZone)
+    QR_RCODE_BADSIGVERS,    ///< Number of queries resulted in RCODE = 16 (BADVERS, BADSIG)
+    QR_RCODE_BADKEY,        ///< Number of queries resulted in RCODE = 17 (BADKEY)
+    QR_RCODE_BADTIME,       ///< Number of queries resulted in RCODE = 18 (BADTIME)
+    QR_RCODE_BADMODE,       ///< Number of queries resulted in RCODE = 19 (BADMODE)
+    QR_RCODE_BADNAME,       ///< Number of queries resulted in RCODE = 20 (BADNAME)
+    QR_RCODE_BADALG,        ///< Number of queries resulted in RCODE = 21 (BADALG)
+    QR_RCODE_BADTRUNC,      ///< Number of queries resulted in RCODE = 22 (BADTRUNC)
+    QR_RCODE_OTHER,         ///< Number of queries resulted in other RCODEs
+    // End of counter types
+    QR_COUNTER_TYPES  ///< The number of defined counters
+};
+// item names for query/response counters
+const char* const QRCounterItemName[QR_COUNTER_TYPES] = {
+    "request.v4",
+    "request.v6",
+    "request.edns0",
+    "request.badednsver",
+    "request.tsig",
+    "request.sig0",
+    "request.badsig",
+    "request.udp",
+    "request.tcp",
+    "request.dnssec_ok",
+    "opcode.query",
+    "opcode.iquery",
+    "opcode.status",
+    "opcode.notify",
+    "opcode.update",
+    "opcode.other",
+    "qtype.a",
+    "qtype.ns",
+    "qtype.md",
+    "qtype.mf",
+    "qtype.cname",
+    "qtype.soa",
+    "qtype.mb",
+    "qtype.mg",
+    "qtype.mr",
+    "qtype.null",
+    "qtype.wks",
+    "qtype.ptr",
+    "qtype.hinfo",
+    "qtype.minfo",
+    "qtype.mx",
+    "qtype.txt",
+    "qtype.rp",
+    "qtype.afsdb",
+    "qtype.x25",
+    "qtype.isdn",
+    "qtype.rt",
+    "qtype.nsap",
+    "qtype.nsap-ptr",
+    "qtype.sig",
+    "qtype.key",
+    "qtype.px",
+    "qtype.gpos",
+    "qtype.aaaa",
+    "qtype.loc",
+    "qtype.nxt",
+    "qtype.eid",
+    "qtype.nimloc",
+    "qtype.srv",
+    "qtype.atma",
+    "qtype.naptr",
+    "qtype.kx",
+    "qtype.cert",
+    "qtype.a6",
+    "qtype.dname",
+    "qtype.sink",
+    "qtype.opt",
+    "qtype.apl",
+    "qtype.ds",
+    "qtype.sshfp",
+    "qtype.ipseckey",
+    "qtype.rrsig",
+    "qtype.nsec",
+    "qtype.dnskey",
+    "qtype.dhcid",
+    "qtype.nsec3",
+    "qtype.nsec3param",
+    "qtype.hip",
+    "qtype.ninfo",
+    "qtype.rkey",
+    "qtype.talink",
+    "qtype.spf",
+    "qtype.uinfo",
+    "qtype.uid",
+    "qtype.gid",
+    "qtype.unspec",
+    "qtype.tkey",
+    "qtype.tsig",
+    "qtype.ixfr",
+    "qtype.axfr",
+    "qtype.mailb",
+    "qtype.maila",
+    "qtype.uri",
+    "qtype.caa",
+    "qtype.ta",
+    "qtype.dlv",
+    "qtype.other",
+    "response",
+    "response.truncated",
+    "response.edns0",
+    "response.tsig",
+    "response.sig0",
+    "qrysuccess",
+    "qryauthans",
+    "qrynoauthans",
+    "qryreferral",
+    "qrynxrrset",
+    "authqryrej",
+    "rcode.noerror",
+    "rcode.formerr",
+    "rcode.servfail",
+    "rcode.nxdomain",
+    "rcode.notimp",
+    "rcode.refused",
+    "rcode.yxdomain",
+    "rcode.yxrrset",
+    "rcode.nxrrset",
+    "rcode.notauth",
+    "rcode.notzone",
+    "rcode.badsigvers",
+    "rcode.badkey",
+    "rcode.badtime",
+    "rcode.badmode",
+    "rcode.badname",
+    "rcode.badalg",
+    "rcode.badtrunc",
+    "rcode.other"
+};
+
+const int QROpCodeToQRCounterType[16] = {
+    QR_OPCODE_QUERY,
+    QR_OPCODE_IQUERY,
+    QR_OPCODE_STATUS,
+    QR_OPCODE_OTHER,
+    QR_OPCODE_NOTIFY,
+    QR_OPCODE_UPDATE,
+    QR_OPCODE_OTHER,
+    QR_OPCODE_OTHER,
+    QR_OPCODE_OTHER,
+    QR_OPCODE_OTHER,
+    QR_OPCODE_OTHER,
+    QR_OPCODE_OTHER,
+    QR_OPCODE_OTHER,
+    QR_OPCODE_OTHER,
+    QR_OPCODE_OTHER,
+    QR_OPCODE_OTHER
+};
+const int QRQTypeToQRCounterType[258] = {
+    QR_QTYPE_OTHER,
+    QR_QTYPE_A,
+    QR_QTYPE_NS,
+    QR_QTYPE_MD,
+    QR_QTYPE_MF,
+    QR_QTYPE_CNAME,
+    QR_QTYPE_SOA,
+    QR_QTYPE_MB,
+    QR_QTYPE_MG,
+    QR_QTYPE_MR,
+    QR_QTYPE_NULL,
+    QR_QTYPE_WKS,
+    QR_QTYPE_PTR,
+    QR_QTYPE_HINFO,
+    QR_QTYPE_MINFO,
+    QR_QTYPE_MX,
+    QR_QTYPE_TXT,
+    QR_QTYPE_RP,
+    QR_QTYPE_AFSDB,
+    QR_QTYPE_X25,
+    QR_QTYPE_ISDN,
+    QR_QTYPE_RT,
+    QR_QTYPE_NSAP,
+    QR_QTYPE_NSAP_PTR,
+    QR_QTYPE_SIG,
+    QR_QTYPE_KEY,
+    QR_QTYPE_PX,
+    QR_QTYPE_GPOS,
+    QR_QTYPE_AAAA,
+    QR_QTYPE_LOC,
+    QR_QTYPE_NXT,
+    QR_QTYPE_EID,
+    QR_QTYPE_NIMLOC,
+    QR_QTYPE_SRV,
+    QR_QTYPE_ATMA,
+    QR_QTYPE_NAPTR,
+    QR_QTYPE_KX,
+    QR_QTYPE_CERT,
+    QR_QTYPE_A6,
+    QR_QTYPE_DNAME,
+    QR_QTYPE_SINK,
+    QR_QTYPE_OPT,
+    QR_QTYPE_APL,
+    QR_QTYPE_DS,
+    QR_QTYPE_SSHFP,
+    QR_QTYPE_IPSECKEY,
+    QR_QTYPE_RRSIG,
+    QR_QTYPE_NSEC,
+    QR_QTYPE_DNSKEY,
+    QR_QTYPE_DHCID,
+    QR_QTYPE_NSEC3,
+    QR_QTYPE_NSEC3PARAM,
+    QR_QTYPE_OTHER,
+    QR_QTYPE_OTHER,
+    QR_QTYPE_OTHER,
+    QR_QTYPE_HIP,
+    QR_QTYPE_NINFO,
+    QR_QTYPE_RKEY,
+    QR_QTYPE_TALINK,
+    QR_QTYPE_OTHER,
+    QR_QTYPE_OTHER,
+    QR_QTYPE_OTHER,
+    QR_QTYPE_OTHER,
+    QR_QTYPE_OTHER,
+    QR_QTYPE_OTHER,
+    QR_QTYPE_OTHER,
+    QR_QTYPE_OTHER,
+    QR_QTYPE_OTHER,
+    QR_QTYPE_OTHER,
+    QR_QTYPE_OTHER,
+    QR_QTYPE_OTHER,
+    QR_QTYPE_OTHER,
+    QR_QTYPE_OTHER,
+    QR_QTYPE_OTHER,
+    QR_QTYPE_OTHER,
+    QR_QTYPE_OTHER,
+    QR_QTYPE_OTHER,
+    QR_QTYPE_OTHER,
+    QR_QTYPE_OTHER,
+    QR_QTYPE_OTHER,
+    QR_QTYPE_OTHER,
+    QR_QTYPE_OTHER,
+    QR_QTYPE_OTHER,
+    QR_QTYPE_OTHER,
+    QR_QTYPE_OTHER,
+    QR_QTYPE_OTHER,
+    QR_QTYPE_OTHER,
+    QR_QTYPE_OTHER,
+    QR_QTYPE_OTHER,
+    QR_QTYPE_OTHER,
+    QR_QTYPE_OTHER,
+    QR_QTYPE_OTHER,
+    QR_QTYPE_OTHER,
+    QR_QTYPE_OTHER,
+    QR_QTYPE_OTHER,
+    QR_QTYPE_OTHER,
+    QR_QTYPE_OTHER,
+    QR_QTYPE_OTHER,
+    QR_QTYPE_OTHER,
+    QR_QTYPE_SPF,
+    QR_QTYPE_UINFO,
+    QR_QTYPE_UID,
+    QR_QTYPE_GID,
+    QR_QTYPE_UNSPEC,
+    QR_QTYPE_OTHER,
+    QR_QTYPE_OTHER,
+    QR_QTYPE_OTHER,
+    QR_QTYPE_OTHER,
+    QR_QTYPE_OTHER,
+    QR_QTYPE_OTHER,
+    QR_QTYPE_OTHER,
+    QR_QTYPE_OTHER,
+    QR_QTYPE_OTHER,
+    QR_QTYPE_OTHER,
+    QR_QTYPE_OTHER,
+    QR_QTYPE_OTHER,
+    QR_QTYPE_OTHER,
+    QR_QTYPE_OTHER,
+    QR_QTYPE_OTHER,
+    QR_QTYPE_OTHER,
+    QR_QTYPE_OTHER,
+    QR_QTYPE_OTHER,
+    QR_QTYPE_OTHER,
+    QR_QTYPE_OTHER,
+    QR_QTYPE_OTHER,
+    QR_QTYPE_OTHER,
+    QR_QTYPE_OTHER,
+    QR_QTYPE_OTHER,
+    QR_QTYPE_OTHER,
+    QR_QTYPE_OTHER,
+    QR_QTYPE_OTHER,
+    QR_QTYPE_OTHER,
+    QR_QTYPE_OTHER,
+    QR_QTYPE_OTHER,
+    QR_QTYPE_OTHER,
+    QR_QTYPE_OTHER,
+    QR_QTYPE_OTHER,
+    QR_QTYPE_OTHER,
+    QR_QTYPE_OTHER,
+    QR_QTYPE_OTHER,
+    QR_QTYPE_OTHER,
+    QR_QTYPE_OTHER,
+    QR_QTYPE_OTHER,
+    QR_QTYPE_OTHER,
+    QR_QTYPE_OTHER,
+    QR_QTYPE_OTHER,
+    QR_QTYPE_OTHER,
+    QR_QTYPE_OTHER,
+    QR_QTYPE_OTHER,
+    QR_QTYPE_OTHER,
+    QR_QTYPE_OTHER,
+    QR_QTYPE_OTHER,
+    QR_QTYPE_OTHER,
+    QR_QTYPE_OTHER,
+    QR_QTYPE_OTHER,
+    QR_QTYPE_OTHER,
+    QR_QTYPE_OTHER,
+    QR_QTYPE_OTHER,
+    QR_QTYPE_OTHER,
+    QR_QTYPE_OTHER,
+    QR_QTYPE_OTHER,
+    QR_QTYPE_OTHER,
+    QR_QTYPE_OTHER,
+    QR_QTYPE_OTHER,
+    QR_QTYPE_OTHER,
+    QR_QTYPE_OTHER,
+    QR_QTYPE_OTHER,
+    QR_QTYPE_OTHER,
+    QR_QTYPE_OTHER,
+    QR_QTYPE_OTHER,
+    QR_QTYPE_OTHER,
+    QR_QTYPE_OTHER,
+    QR_QTYPE_OTHER,
+    QR_QTYPE_OTHER,
+    QR_QTYPE_OTHER,
+    QR_QTYPE_OTHER,
+    QR_QTYPE_OTHER,
+    QR_QTYPE_OTHER,
+    QR_QTYPE_OTHER,
+    QR_QTYPE_OTHER,
+    QR_QTYPE_OTHER,
+    QR_QTYPE_OTHER,
+    QR_QTYPE_OTHER,
+    QR_QTYPE_OTHER,
+    QR_QTYPE_OTHER,
+    QR_QTYPE_OTHER,
+    QR_QTYPE_OTHER,
+    QR_QTYPE_OTHER,
+    QR_QTYPE_OTHER,
+    QR_QTYPE_OTHER,
+    QR_QTYPE_OTHER,
+    QR_QTYPE_OTHER,
+    QR_QTYPE_OTHER,
+    QR_QTYPE_OTHER,
+    QR_QTYPE_OTHER,
+    QR_QTYPE_OTHER,
+    QR_QTYPE_OTHER,
+    QR_QTYPE_OTHER,
+    QR_QTYPE_OTHER,
+    QR_QTYPE_OTHER,
+    QR_QTYPE_OTHER,
+    QR_QTYPE_OTHER,
+    QR_QTYPE_OTHER,
+    QR_QTYPE_OTHER,
+    QR_QTYPE_OTHER,
+    QR_QTYPE_OTHER,
+    QR_QTYPE_OTHER,
+    QR_QTYPE_OTHER,
+    QR_QTYPE_OTHER,
+    QR_QTYPE_OTHER,
+    QR_QTYPE_OTHER,
+    QR_QTYPE_OTHER,
+    QR_QTYPE_OTHER,
+    QR_QTYPE_OTHER,
+    QR_QTYPE_OTHER,
+    QR_QTYPE_OTHER,
+    QR_QTYPE_OTHER,
+    QR_QTYPE_OTHER,
+    QR_QTYPE_OTHER,
+    QR_QTYPE_OTHER,
+    QR_QTYPE_OTHER,
+    QR_QTYPE_OTHER,
+    QR_QTYPE_OTHER,
+    QR_QTYPE_OTHER,
+    QR_QTYPE_OTHER,
+    QR_QTYPE_OTHER,
+    QR_QTYPE_OTHER,
+    QR_QTYPE_OTHER,
+    QR_QTYPE_OTHER,
+    QR_QTYPE_OTHER,
+    QR_QTYPE_OTHER,
+    QR_QTYPE_OTHER,
+    QR_QTYPE_OTHER,
+    QR_QTYPE_OTHER,
+    QR_QTYPE_OTHER,
+    QR_QTYPE_OTHER,
+    QR_QTYPE_OTHER,
+    QR_QTYPE_OTHER,
+    QR_QTYPE_OTHER,
+    QR_QTYPE_OTHER,
+    QR_QTYPE_OTHER,
+    QR_QTYPE_OTHER,
+    QR_QTYPE_OTHER,
+    QR_QTYPE_OTHER,
+    QR_QTYPE_OTHER,
+    QR_QTYPE_OTHER,
+    QR_QTYPE_OTHER,
+    QR_QTYPE_OTHER,
+    QR_QTYPE_OTHER,
+    QR_QTYPE_TKEY,
+    QR_QTYPE_TSIG,
+    QR_QTYPE_IXFR,
+    QR_QTYPE_AXFR,
+    QR_QTYPE_MAILB,
+    QR_QTYPE_MAILA,
+    QR_QTYPE_OTHER,
+    QR_QTYPE_URI,
+    QR_QTYPE_CAA
+};
+const int QRRCodeToQRCounterType[23] = {
+    QR_RCODE_NOERROR,
+    QR_RCODE_FORMERR,
+    QR_RCODE_SERVFAIL,
+    QR_RCODE_NXDOMAIN,
+    QR_RCODE_NOTIMP,
+    QR_RCODE_REFUSED,
+    QR_RCODE_YXDOMAIN,
+    QR_RCODE_YXRRSET,
+    QR_RCODE_NXRRSET,
+    QR_RCODE_NOTAUTH,
+    QR_RCODE_NOTZONE,
+    QR_RCODE_OTHER,
+    QR_RCODE_OTHER,
+    QR_RCODE_OTHER,
+    QR_RCODE_OTHER,
+    QR_RCODE_OTHER,
+    QR_RCODE_BADSIGVERS,
+    QR_RCODE_BADKEY,
+    QR_RCODE_BADTIME,
+    QR_RCODE_BADMODE,
+    QR_RCODE_BADNAME,
+    QR_RCODE_BADALG,
+    QR_RCODE_BADTRUNC
+};
+
+} // anonymous namespace
+
+#endif // __STATISTICS_ITEMS_H
+
+// Local Variables:
+// mode: c++
+// End:
diff --git a/src/bin/auth/tests/Makefile.am b/src/bin/auth/tests/Makefile.am
index 75e4a27..482a4f7 100644
--- a/src/bin/auth/tests/Makefile.am
+++ b/src/bin/auth/tests/Makefile.am
@@ -41,7 +41,7 @@ run_unittests_SOURCES += ../query.h ../query.cc
 run_unittests_SOURCES += ../auth_config.h ../auth_config.cc
 run_unittests_SOURCES += ../command.h ../command.cc
 run_unittests_SOURCES += ../common.h ../common.cc
-run_unittests_SOURCES += ../statistics.h ../statistics.cc
+run_unittests_SOURCES += ../statistics.h ../statistics.cc ../statistics_items.h
 run_unittests_SOURCES += datasrc_util.h datasrc_util.cc
 run_unittests_SOURCES += auth_srv_unittest.cc
 run_unittests_SOURCES += config_unittest.cc
@@ -71,7 +71,6 @@ run_unittests_LDADD += $(top_builddir)/src/lib/log/libb10-log.la
 run_unittests_LDADD += $(top_builddir)/src/lib/server_common/libb10-server-common.la
 run_unittests_LDADD += $(top_builddir)/src/lib/nsas/libb10-nsas.la
 run_unittests_LDADD += $(top_builddir)/src/lib/util/unittests/libutil_unittests.la
-run_unittests_LDADD += $(top_builddir)/src/lib/statistics/libb10-statistics.la
 run_unittests_LDADD += $(top_builddir)/src/lib/config/tests/libfake_session.la
 run_unittests_LDADD += $(GTEST_LDADD)
 run_unittests_LDADD += $(SQLITE_LIBS)
diff --git a/src/bin/auth/tests/auth_srv_unittest.cc b/src/bin/auth/tests/auth_srv_unittest.cc
index e7b4ca7..fe2f012 100644
--- a/src/bin/auth/tests/auth_srv_unittest.cc
+++ b/src/bin/auth/tests/auth_srv_unittest.cc
@@ -36,6 +36,7 @@
 #include <auth/command.h>
 #include <auth/common.h>
 #include <auth/statistics.h>
+#include <auth/statistics_items.h>
 #include <auth/datasrc_configurator.h>
 
 #include <util/unittests/mock_socketsession.h>
@@ -74,6 +75,7 @@ using namespace isc::testutils;
 using namespace isc::server_common::portconfig;
 using isc::UnitTestUtil;
 using boost::scoped_ptr;
+using isc::auth::statistics::Counters;
 
 namespace {
 const char* const CONFIG_TESTDB =
@@ -118,29 +120,58 @@ protected:
 
     // Helper for checking Rcode statistic counters;
     // Checks for one specific Rcode statistics counter value
-    void checkRcodeCounter(const Rcode& rcode, int expected_value) const {
-        EXPECT_EQ(expected_value, server.getCounter(rcode)) <<
-                  "Expected Rcode count for " << rcode.toText() <<
-                  " " << expected_value << ", was: " <<
-                  server.getCounter(rcode);
+    void checkRcodeCounter(const std::string& rcode_name, const int rcode_value,
+                           const int expected_value) const
+    {
+            EXPECT_EQ(expected_value, rcode_value) <<
+                      "Expected Rcode count for " << rcode_name <<
+                      " " << expected_value << ", was: " <<
+                      rcode_value;
     }
 
     // Checks whether all Rcode counters are set to zero
     void checkAllRcodeCountersZero() const {
-        for (int i = 0; i < 17; i++) {
-            checkRcodeCounter(Rcode(i), 0);
+        const std::map<std::string, ConstElementPtr>
+            stats_map(server.getStatistics()->mapValue());
+
+        const std::string rcode_prefix("rcode.");
+        for (std::map<std::string, ConstElementPtr>::const_iterator
+                 i = stats_map.begin(), e = stats_map.end();
+             i != e;
+             ++i)
+        {
+            if (i->first.compare(0, rcode_prefix.size(), rcode_prefix) == 0) {
+                checkRcodeCounter(i->first, i->second->intValue(), 0);
+            }
         }
     }
 
     // Checks whether all Rcode counters are set to zero except the given
     // rcode (it is checked to be set to 'value')
     void checkAllRcodeCountersZeroExcept(const Rcode& rcode, int value) const {
-        for (int i = 0; i < 17; i++) {
-            const Rcode rc(i);
-            if (rc == rcode) {
-                checkRcodeCounter(Rcode(i), value);
-            } else {
-                checkRcodeCounter(Rcode(i), 0);
+        std::string target_rcode_name = rcode.toText();
+        std::transform(target_rcode_name.begin(), target_rcode_name.end(),
+                       target_rcode_name.begin(), ::tolower);
+        // rcode 16 is registered as both BADVERS and BADSIG
+        if (target_rcode_name == "badvers") {
+            target_rcode_name = "badsigvers";
+        }
+
+        const std::map<std::string, ConstElementPtr>
+            stats_map(server.getStatistics()->mapValue());
+
+        const std::string rcode_prefix("rcode.");
+        for (std::map<std::string, ConstElementPtr>::const_iterator
+                 i = stats_map.begin(), e = stats_map.end();
+             i != e;
+             ++i)
+        {
+            if (i->first.compare(0, rcode_prefix.size(), rcode_prefix) == 0) {
+                if (i->first.compare(rcode_prefix + target_rcode_name) == 0) {
+                    checkRcodeCounter(i->first, i->second->intValue(), value);
+                } else {
+                    checkRcodeCounter(i->first, i->second->intValue(), 0);
+                }
             }
         }
     }
@@ -217,6 +248,15 @@ createBuiltinVersionResponse(const qid_t qid, vector<uint8_t>& data) {
                 renderer.getLength());
 }
 
+void
+expectCounterItem(ConstElementPtr stats,
+                  const std::string& item, const int expected) {
+    ConstElementPtr value(Element::create(0));
+    ASSERT_TRUE(stats->find(item, value)) << "    Item: " << item;
+    value = stats->find(item);
+    EXPECT_EQ(expected, value->intValue()) << "    Item: " << item;
+}
+
 // We did not configure any client lists. Therefore it should be REFUSED
 TEST_F(AuthSrvTest, noClientList) {
     UnitTestUtil::createRequestMessage(request_message, Opcode::QUERY(),
@@ -400,7 +440,8 @@ TEST_F(AuthSrvTest, TSIGCheckFirst) {
         "It should be unsigned with this error";
     // TSIG should have failed, and so the per opcode counter shouldn't be
     // incremented.
-    EXPECT_EQ(0, server.getCounter(Opcode::RESERVED14()));
+    ConstElementPtr stats = server.getStatistics();
+    expectCounterItem(stats->get("zones")->get("_SERVER_"), "opcode.other", 0);
 
     checkAllRcodeCountersZeroExcept(Rcode::NOTAUTH(), 1);
 }
@@ -1028,8 +1069,13 @@ TEST_F(AuthSrvTest,
 
 // Submit UDP normal query and check query counter
 TEST_F(AuthSrvTest, queryCounterUDPNormal) {
-    // The counter should be initialized to 0.
-    EXPECT_EQ(0, server.getCounter(AuthCounters::SERVER_UDP_QUERY));
+    // The counters should be initialized to 0.
+    ConstElementPtr stats_init = server.getStatistics()->
+        get("zones")->get("_SERVER_");
+    expectCounterItem(stats_init, "request.udp", 0);
+    expectCounterItem(stats_init, "request.tcp", 0);
+    expectCounterItem(stats_init, "opcode.query", 0);
+    expectCounterItem(stats_init, "rcode.refused", 0);
     // Create UDP message and process.
     UnitTestUtil::createRequestMessage(request_message, Opcode::QUERY(),
                                        default_qid, Name("example.com"),
@@ -1037,18 +1083,27 @@ TEST_F(AuthSrvTest, queryCounterUDPNormal) {
     createRequestPacket(request_message, IPPROTO_UDP);
     server.processMessage(*io_message, *parse_message, *response_obuffer,
                           &dnsserv);
-    // After processing UDP query, the counter should be 1.
-    EXPECT_EQ(1, server.getCounter(AuthCounters::SERVER_UDP_QUERY));
-    // The counter for opcode Query should also be one
-    EXPECT_EQ(1, server.getCounter(Opcode::QUERY()));
-    // The counter for REFUSED responses should also be one, the rest zero
-    checkAllRcodeCountersZeroExcept(Rcode::REFUSED(), 1);
+    // After processing the UDP query, these counters should be incremented:
+    //   request.tcp, opcode.query, qtype.ns, rcode.refused, response
+    // and these counters should not be incremented:
+    //   request.tcp
+    ConstElementPtr stats_after = server.getStatistics()->
+        get("zones")->get("_SERVER_");
+    expectCounterItem(stats_after, "request.udp", 1);
+    expectCounterItem(stats_after, "request.tcp", 0);
+    expectCounterItem(stats_after, "opcode.query", 1);
+    expectCounterItem(stats_after, "rcode.refused", 1);
 }
 
 // Submit TCP normal query and check query counter
 TEST_F(AuthSrvTest, queryCounterTCPNormal) {
-    // The counter should be initialized to 0.
-    EXPECT_EQ(0, server.getCounter(AuthCounters::SERVER_TCP_QUERY));
+    // The counters should be initialized to 0.
+    ConstElementPtr stats_init = server.getStatistics()->
+        get("zones")->get("_SERVER_");
+    expectCounterItem(stats_init, "request.udp", 0);
+    expectCounterItem(stats_init, "request.tcp", 0);
+    expectCounterItem(stats_init, "opcode.query", 0);
+    expectCounterItem(stats_init, "rcode.refused", 0);
     // Create TCP message and process.
     UnitTestUtil::createRequestMessage(request_message, Opcode::QUERY(),
                                        default_qid, Name("example.com"),
@@ -1056,18 +1111,26 @@ TEST_F(AuthSrvTest, queryCounterTCPNormal) {
     createRequestPacket(request_message, IPPROTO_TCP);
     server.processMessage(*io_message, *parse_message, *response_obuffer,
                           &dnsserv);
-    // After processing TCP query, the counter should be 1.
-    EXPECT_EQ(1, server.getCounter(AuthCounters::SERVER_TCP_QUERY));
-    // The counter for SUCCESS responses should also be one
-    EXPECT_EQ(1, server.getCounter(Opcode::QUERY()));
-    // The counter for REFUSED responses should also be one, the rest zero
-    checkAllRcodeCountersZeroExcept(Rcode::REFUSED(), 1);
+    // After processing the TCP query, these counters should be incremented:
+    //   request.tcp, opcode.query, qtype.ns, rcode.refused, response
+    // and these counters should not be incremented:
+    //   request.udp
+    ConstElementPtr stats_after = server.getStatistics()->
+        get("zones")->get("_SERVER_");
+    expectCounterItem(stats_after, "request.udp", 0);
+    expectCounterItem(stats_after, "request.tcp", 1);
+    expectCounterItem(stats_after, "opcode.query", 1);
+    expectCounterItem(stats_after, "rcode.refused", 1);
 }
 
 // Submit TCP AXFR query and check query counter
 TEST_F(AuthSrvTest, queryCounterTCPAXFR) {
-    // The counter should be initialized to 0.
-    EXPECT_EQ(0, server.getCounter(AuthCounters::SERVER_TCP_QUERY));
+    // The counters should be initialized to 0.
+    ConstElementPtr stats_init = server.getStatistics()->
+        get("zones")->get("_SERVER_");
+    expectCounterItem(stats_init, "request.udp", 0);
+    expectCounterItem(stats_init, "request.tcp", 0);
+    expectCounterItem(stats_init, "opcode.query", 0);
     UnitTestUtil::createRequestMessage(request_message, opcode, default_qid,
                          Name("example.com"), RRClass::IN(), RRType::AXFR());
     createRequestPacket(request_message, IPPROTO_TCP);
@@ -1076,16 +1139,26 @@ TEST_F(AuthSrvTest, queryCounterTCPAXFR) {
     server.processMessage(*io_message, *parse_message, *response_obuffer,
                           &dnsserv);
     EXPECT_FALSE(dnsserv.hasAnswer());
-    // After processing TCP AXFR query, the counter should be 1.
-    EXPECT_EQ(1, server.getCounter(AuthCounters::SERVER_TCP_QUERY));
-    // No rcodes should be incremented
-    checkAllRcodeCountersZero();
+    // After processing the TCP AXFR query, these counters should be
+    // incremented:
+    //   request.tcp, opcode.query, qtype.axfr
+    // and these counters should not be incremented:
+    //   request.udp, response
+    ConstElementPtr stats_after = server.getStatistics()->
+        get("zones")->get("_SERVER_");
+    expectCounterItem(stats_after, "request.udp", 0);
+    expectCounterItem(stats_after, "request.tcp", 1);
+    expectCounterItem(stats_after, "opcode.query", 1);
 }
 
 // Submit TCP IXFR query and check query counter
 TEST_F(AuthSrvTest, queryCounterTCPIXFR) {
-    // The counter should be initialized to 0.
-    EXPECT_EQ(0, server.getCounter(AuthCounters::SERVER_TCP_QUERY));
+    // The counters should be initialized to 0.
+    ConstElementPtr stats_init = server.getStatistics()->
+        get("zones")->get("_SERVER_");
+    expectCounterItem(stats_init, "request.udp", 0);
+    expectCounterItem(stats_init, "request.tcp", 0);
+    expectCounterItem(stats_init, "opcode.query", 0);
     UnitTestUtil::createRequestMessage(request_message, opcode, default_qid,
                          Name("example.com"), RRClass::IN(), RRType::IXFR());
     createRequestPacket(request_message, IPPROTO_TCP);
@@ -1094,14 +1167,26 @@ TEST_F(AuthSrvTest, queryCounterTCPIXFR) {
     server.processMessage(*io_message, *parse_message, *response_obuffer,
                           &dnsserv);
     EXPECT_FALSE(dnsserv.hasAnswer());
-    // After processing TCP IXFR query, the counter should be 1.
-    EXPECT_EQ(1, server.getCounter(AuthCounters::SERVER_TCP_QUERY));
+    // After processing the TCP IXFR query, these counters should be
+    // incremented:
+    //   request.tcp, opcode.query, qtype.ixfr
+    // and these counters should not be incremented:
+    //   request.udp, response
+    ConstElementPtr stats_after = server.getStatistics()->
+        get("zones")->get("_SERVER_");
+    expectCounterItem(stats_after, "request.udp", 0);
+    expectCounterItem(stats_after, "request.tcp", 1);
+    expectCounterItem(stats_after, "opcode.query", 1);
 }
 
 TEST_F(AuthSrvTest, queryCounterOpcodes) {
-    for (int i = 0; i < 16; ++i) {
+    // Check for 0..2, 3(=other), 4..5
+    // The counter should be initialized to 0.
+    for (int i = 0; i < 6; ++i) {
         // The counter should be initialized to 0.
-        EXPECT_EQ(0, server.getCounter(Opcode(i)));
+        expectCounterItem(server.getStatistics()->
+                              get("zones")->get("_SERVER_"),
+                          QRCounterItemName[QROpCodeToQRCounterType[i]], 0);
 
         // For each possible opcode, create a request message and send it
         UnitTestUtil::createRequestMessage(request_message, Opcode(i),
@@ -1119,7 +1204,42 @@ TEST_F(AuthSrvTest, queryCounterOpcodes) {
         }
 
         // Confirm the counter.
-        EXPECT_EQ(i + 1, server.getCounter(Opcode(i)));
+        expectCounterItem(server.getStatistics()->
+                              get("zones")->get("_SERVER_"),
+                          QRCounterItemName[QROpCodeToQRCounterType[i]],
+                          i + 1);
+    }
+    // Check for 6..15
+    // they are treated as the 'other' opcode
+    // the 'other' opcode counter is 4 at this point
+    int expected = 4;
+    for (int i = 6; i < 16; ++i) {
+        // The counter should be initialized to 0.
+        expectCounterItem(server.getStatistics()->
+                              get("zones")->get("_SERVER_"),
+                          QRCounterItemName[QROpCodeToQRCounterType[i]],
+                          expected);
+
+        // For each possible opcode, create a request message and send it
+        UnitTestUtil::createRequestMessage(request_message, Opcode(i),
+                                           default_qid, Name("example.com"),
+                                           RRClass::IN(), RRType::NS());
+        createRequestPacket(request_message, IPPROTO_UDP);
+
+        // "send" the request once
+        parse_message->clear(Message::PARSE);
+        server.processMessage(*io_message, *parse_message,
+                              *response_obuffer,
+                              &dnsserv);
+
+        // the 'other' opcode counter should be incremented
+        ++expected;
+
+        // Confirm the counter.
+        expectCounterItem(server.getStatistics()->
+                              get("zones")->get("_SERVER_"),
+                          QRCounterItemName[QROpCodeToQRCounterType[i]],
+                          expected);
     }
 }
 
diff --git a/src/bin/auth/tests/statistics_unittest.cc b/src/bin/auth/tests/statistics_unittest.cc
index d2f5a5a..907e02d 100644
--- a/src/bin/auth/tests/statistics_unittest.cc
+++ b/src/bin/auth/tests/statistics_unittest.cc
@@ -27,345 +27,125 @@
 #include <cc/session.h>
 
 #include <auth/statistics.h>
+#include <auth/statistics_items.h>
 
 #include <dns/tests/unittest_util.h>
 
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <netdb.h>
+
 using namespace std;
 using namespace isc::cc;
 using namespace isc::dns;
 using namespace isc::data;
+using isc::auth::statistics::Counters;
+using isc::auth::statistics::QRAttributes;
 
 namespace {
 
-class AuthCountersTest : public ::testing::Test {
-private:
-    class MockSession : public AbstractSession {
-    public:
-        MockSession() :
-            // by default we return a simple "success" message.
-            msg_(Element::fromJSON("{\"result\": [0, \"SUCCESS\"]}")),
-            throw_session_error_(false), throw_session_timeout_(false)
-        {}
-        virtual void establish(const char* socket_file);
-        virtual void disconnect();
-        virtual int group_sendmsg(ConstElementPtr msg, string group,
-                                  string instance, string to);
-        virtual bool group_recvmsg(ConstElementPtr& envelope,
-                                   ConstElementPtr& msg,
-                                   bool nonblock, int seq);
-        virtual void subscribe(string group, string instance);
-        virtual void unsubscribe(string group, string instance);
-        virtual void startRead(boost::function<void()> read_callback);
-        virtual int reply(ConstElementPtr envelope, ConstElementPtr newmsg);
-        virtual bool hasQueuedMsgs() const;
-        virtual void setTimeout(size_t) {}
-        virtual size_t getTimeout() const { return (0); };
-
-        void setThrowSessionError(bool flag);
-        void setThrowSessionTimeout(bool flag);
-
-        void setMessage(ConstElementPtr msg) { msg_ = msg; }
-
-        ConstElementPtr sent_msg;
-        string msg_destination;
-    private:
-        ConstElementPtr msg_;
-        bool throw_session_error_;
-        bool throw_session_timeout_;
-    };
-
+class CountersTest : public ::testing::Test {
 protected:
-    AuthCountersTest() : counters() {
-    }
-    ~AuthCountersTest() {
-    }
-    AuthCounters counters;
-    // no need to be inherited from the original class here.
-    class MockModuleSpec {
-    public:
-        bool validateStatistics(ConstElementPtr, const bool valid) const
-            { return (valid); }
-    };
-    MockModuleSpec module_spec_;
+    CountersTest() : counters() {}
+    ~CountersTest() {}
+    Counters counters;
 };
 
-void
-AuthCountersTest::MockSession::establish(const char*) {}
-
-void
-AuthCountersTest::MockSession::disconnect() {}
-
-void
-AuthCountersTest::MockSession::subscribe(string, string)
-{}
-
-void
-AuthCountersTest::MockSession::unsubscribe(string, string)
-{}
-
-void
-AuthCountersTest::MockSession::startRead(boost::function<void()>)
-{}
-
-int
-AuthCountersTest::MockSession::reply(ConstElementPtr, ConstElementPtr) {
-    return (-1);
-}
-
-bool
-AuthCountersTest::MockSession::hasQueuedMsgs() const {
-    return (false);
-}
-
-int
-AuthCountersTest::MockSession::group_sendmsg(ConstElementPtr msg,
-                                              string group, string, string)
-{
-    if (throw_session_error_) {
-        isc_throw(SessionError, "Session Error");
-    }
-    sent_msg = msg;
-    msg_destination = group;
-    return (0);
-}
-
 bool
-AuthCountersTest::MockSession::group_recvmsg(ConstElementPtr&,
-                                              ConstElementPtr& msg, bool, int)
-{
-    if (throw_session_timeout_) {
-        isc_throw(SessionTimeout, "Session Timeout");
-    }
-    msg = msg_;
-    return (true);
-}
-
-void
-AuthCountersTest::MockSession::setThrowSessionError(bool flag) {
-    throw_session_error_ = flag;
-}
-
-void
-AuthCountersTest::MockSession::setThrowSessionTimeout(bool flag) {
-    throw_session_timeout_ = flag;
-}
-
-TEST_F(AuthCountersTest, incrementUDPCounter) {
-    // The counter should be initialized to 0.
-    EXPECT_EQ(0, counters.getCounter(AuthCounters::SERVER_UDP_QUERY));
-    EXPECT_NO_THROW(counters.inc(AuthCounters::SERVER_UDP_QUERY));
-    // After increment, the counter should be 1.
-    EXPECT_EQ(1, counters.getCounter(AuthCounters::SERVER_UDP_QUERY));
-}
-
-TEST_F(AuthCountersTest, incrementTCPCounter) {
-    // The counter should be initialized to 0.
-    EXPECT_EQ(0, counters.getCounter(AuthCounters::SERVER_TCP_QUERY));
-    EXPECT_NO_THROW(counters.inc(AuthCounters::SERVER_TCP_QUERY));
-    // After increment, the counter should be 1.
-    EXPECT_EQ(1, counters.getCounter(AuthCounters::SERVER_TCP_QUERY));
-}
-
-TEST_F(AuthCountersTest, incrementInvalidCounter) {
-    // Expect to throw an isc::OutOfRange
-    EXPECT_THROW(counters.inc(AuthCounters::SERVER_COUNTER_TYPES),
-                 isc::OutOfRange);
-}
-
-TEST_F(AuthCountersTest, incrementOpcodeCounter) {
-    // The counter should be initialized to 0.  If we increment it by 1
-    // the counter should be 1.
-    for (int i = 0; i < 16; ++i) {
-        EXPECT_EQ(0, counters.getCounter(Opcode(i)));
-        counters.inc(Opcode(i));
-        EXPECT_EQ(1, counters.getCounter(Opcode(i)));
-    }
-}
-
-TEST_F(AuthCountersTest, incrementRcodeCounter) {
-    // The counter should be initialized to 0.  If we increment it by 1
-    // the counter should be 1.
-    for (int i = 0; i < 17; ++i) {
-        EXPECT_EQ(0, counters.getCounter(Rcode(i)));
-        counters.inc(Rcode(i));
-        EXPECT_EQ(1, counters.getCounter(Rcode(i)));
-    }
-}
-
-void
-opcodeDataCheck(ConstElementPtr data, const int expected[16]) {
-    const char* item_names[] = {
-        "query", "iquery", "status", "reserved3", "notify", "update",
-        "reserved6", "reserved7", "reserved8", "reserved9", "reserved10",
-        "reserved11", "reserved12", "reserved13", "reserved14", "reserved15",
-        NULL
-    };
-    int i;
-    for (i = 0; i < 16; ++i) {
-        ASSERT_NE(static_cast<const char*>(NULL), item_names[i]);
-        const string item_name = "opcode." + string(item_names[i]);
-        if (expected[i] == 0) {
-            EXPECT_FALSE(data->get(item_name));
-        } else {
-            EXPECT_EQ(expected[i], data->get(item_name)->intValue());
-        }
-    }
-    // We should have examined all names
-    ASSERT_EQ(static_cast<const char*>(NULL), item_names[i]);
-}
-
-void
-rcodeDataCheck(ConstElementPtr data, const int expected[17]) {
-    const char* item_names[] = {
-        "noerror", "formerr", "servfail", "nxdomain", "notimp", "refused",
-        "yxdomain", "yxrrset", "nxrrset", "notauth", "notzone", "reserved11",
-        "reserved12", "reserved13", "reserved14", "reserved15", "badvers",
-        NULL
-    };
-    int i;
-    for (i = 0; i < 17; ++i) {
-        ASSERT_NE(static_cast<const char*>(NULL), item_names[i]);
-        const string item_name = "rcode." + string(item_names[i]);
-        if (expected[i] == 0) {
-            EXPECT_FALSE(data->get(item_name));
-        } else {
-            EXPECT_EQ(expected[i], data->get(item_name)->intValue());
-        }
-    }
-    // We should have examined all names
-    ASSERT_EQ(static_cast<const char*>(NULL), item_names[i]);
-}
-
-TEST_F(AuthCountersTest, getStatisticsWithoutValidator) {
-    // Get statistics data.
-    // Validate if it answers correct data.
-
-    // Counters should be initialized to 0.
-    EXPECT_EQ(0, counters.getCounter(AuthCounters::SERVER_UDP_QUERY));
-    EXPECT_EQ(0, counters.getCounter(AuthCounters::SERVER_TCP_QUERY));
-
-    // UDP query counter is set to 2.
-    counters.inc(AuthCounters::SERVER_UDP_QUERY);
-    counters.inc(AuthCounters::SERVER_UDP_QUERY);
-    // TCP query counter is set to 1.
-    counters.inc(AuthCounters::SERVER_TCP_QUERY);
-    ConstElementPtr statistics_data = counters.getStatistics();
-
-    // UDP query counter is 2 and TCP query counter is 1.
-    EXPECT_EQ(2, statistics_data->get("queries.udp")->intValue());
-    EXPECT_EQ(1, statistics_data->get("queries.tcp")->intValue());
-
-    // By default opcode counters are all 0 and omitted
-    const int opcode_results[16] = { 0, 0, 0, 0, 0, 0, 0, 0,
-                                     0, 0, 0, 0, 0, 0, 0, 0 };
-    opcodeDataCheck(statistics_data, opcode_results);
-    // By default rcode counters are all 0 and omitted
-    const int rcode_results[17] = { 0, 0, 0, 0, 0, 0, 0, 0, 0,
-                                    0, 0, 0, 0, 0, 0, 0, 0 };
-    rcodeDataCheck(statistics_data, rcode_results);
-}
-
-void
-updateOpcodeCounters(AuthCounters &counters, const int expected[16]) {
-    for (int i = 0; i < 16; ++i) {
-        for (int j = 0; j < expected[i]; ++j) {
-            counters.inc(Opcode(i));
+checkCountersAllZeroExcept(const isc::data::ConstElementPtr counters,
+                           const std::set<std::string>& except_for) {
+    std::map<std::string, ConstElementPtr> stats_map = counters->mapValue();
+
+    for (std::map<std::string, ConstElementPtr>::const_iterator
+            i = stats_map.begin(), e = stats_map.end();
+            i != e;
+            ++i)
+    {
+        int expect = 0;
+        if (except_for.count(i->first) != 0) {
+            expect = 1;
         }
+        EXPECT_EQ(expect, i->second->intValue()) << "Expected counter "
+            << i->first << " = " << expect << ", actual: "
+            << i->second->intValue();
     }
-}
 
-void
-updateRcodeCounters(AuthCounters &counters, const int expected[17]) {
-    for (int i = 0; i < 17; ++i) {
-        for (int j = 0; j < expected[i]; ++j) {
-            counters.inc(Rcode(i));
-        }
+    return false;
+}
+
+TEST_F(CountersTest, incrementNormalQuery) {
+    Message response(Message::RENDER);
+    QRAttributes qrattrs;
+    std::set<std::string> expect_nonzero;
+
+    expect_nonzero.clear();
+    checkCountersAllZeroExcept(counters.get()->get("zones")->get("_SERVER_"),
+                               expect_nonzero);
+
+    qrattrs.setQueryIPVersion(AF_INET6);
+    qrattrs.setQueryTransportProtocol(IPPROTO_UDP);
+    qrattrs.setQueryOpCode(Opcode::QUERY_CODE);
+    qrattrs.setQueryEDNS(true, false);
+    qrattrs.setQueryDO(true);
+    qrattrs.answerWasSent();
+
+    response.setRcode(Rcode::REFUSED());
+    response.addQuestion(Question(Name("example.com"),
+                                  RRClass::IN(), RRType::AAAA()));
+
+    counters.inc(qrattrs, response);
+
+    expect_nonzero.clear();
+    expect_nonzero.insert("opcode.query");
+    expect_nonzero.insert("qtype.aaaa");
+    expect_nonzero.insert("request.v6");
+    expect_nonzero.insert("request.udp");
+    expect_nonzero.insert("request.edns0");
+    expect_nonzero.insert("request.dnssec_ok");
+    expect_nonzero.insert("response");
+    expect_nonzero.insert("qrynoauthans");
+    expect_nonzero.insert("rcode.refused");
+    expect_nonzero.insert("authqryrej");
+    checkCountersAllZeroExcept(counters.get()->get("zones")->get("_SERVER_"),
+                               expect_nonzero);
+}
+
+TEST_F(CountersTest, getStatistics) {
+    std::map<std::string, ConstElementPtr> stats_map =
+        counters.get()->get("zones")->get("_SERVER_")->mapValue();
+    for (std::map<std::string, ConstElementPtr>::const_iterator
+            i = stats_map.begin(), e = stats_map.end();
+            i != e;
+            ++i)
+    {
+        // item type check
+        EXPECT_NO_THROW(i->second->intValue())
+            << "Item " << i->first << " is not IntElement";
     }
 }
 
-TEST_F(AuthCountersTest, getStatisticsWithOpcodeCounters) {
-    // Increment some of the opcode counters.  Then they should appear in the
-    // submitted data; others shouldn't
-    const int opcode_results[16] = { 1, 2, 3, 0, 4, 5, 0, 0,
-                                     0, 0, 0, 0, 0, 0, 0, 0 };
-    updateOpcodeCounters(counters, opcode_results);
-    ConstElementPtr statistics_data = counters.getStatistics();
-    opcodeDataCheck(statistics_data, opcode_results);
-}
-
-TEST_F(AuthCountersTest, getStatisticsWithAllOpcodeCounters) {
-    // Increment all opcode counters.  Then they should appear in the
-    // submitted data.
-    const int opcode_results[16] = { 1, 1, 1, 1, 1, 1, 1, 1,
-                                     1, 1, 1, 1, 1, 1, 1, 1 };
-    updateOpcodeCounters(counters, opcode_results);
-    ConstElementPtr statistics_data = counters.getStatistics();
-    opcodeDataCheck(statistics_data, opcode_results);
-}
-
-TEST_F(AuthCountersTest, getStatisticsWithRcodeCounters) {
-    // Increment some of the rcode counters.  Then they should appear in the
-    // submitted data; others shouldn't
-    const int rcode_results[17] = { 1, 2, 3, 4, 5, 6, 7, 8, 9,
-                                    10, 0, 0, 0, 0, 0, 0, 11 };
-    updateRcodeCounters(counters, rcode_results);
-    ConstElementPtr statistics_data = counters.getStatistics();
-    rcodeDataCheck(statistics_data, rcode_results);
+TEST(StatisticsItemsTest, QRItemNamesCheck) {
+    // check the number of elements in the array
+    EXPECT_EQ(sizeof(QRCounterItemName) / sizeof(QRCounterItemName[0]),
+              QR_COUNTER_TYPES);
+    // check the name of the first enum element
+    EXPECT_EQ(QRCounterItemName[QR_REQUEST_IPV4], "request.v4");
+    // check the name of the last enum element
+    EXPECT_EQ(QRCounterItemName[QR_RCODE_OTHER], "rcode.other");
 }
 
-TEST_F(AuthCountersTest, getStatisticsWithAllRcodeCounters) {
-    // Increment all rcode counters.  Then they should appear in the
-    // submitted data.
-    const int rcode_results[17] = { 1, 1, 1, 1, 1, 1, 1, 1, 1,
-                                     1, 1, 1, 1, 1, 1, 1, 1 };
-    updateOpcodeCounters(counters, rcode_results);
-    ConstElementPtr statistics_data = counters.getStatistics();
-    opcodeDataCheck(statistics_data, rcode_results);
+TEST(StatisticsItemsTest, SocketItemNamesCheck) {
+    // check the number of elements in the array
+    EXPECT_EQ(sizeof(SocketCounterItemName) / sizeof(SocketCounterItemName[0]),
+              SOCKET_COUNTER_TYPES);
+    // check the name of the first enum element
+    EXPECT_EQ(SocketCounterItemName[SOCKET_IPV4_UDP_BINDFAIL],
+              "ipv4.udp.bindfail");
+    // check the name of the last enum element
+    EXPECT_EQ(SocketCounterItemName[SOCKET_UNIXDOMAIN_SENDERR],
+              "unixdomain.senderr");
 }
 
-TEST_F(AuthCountersTest, getStatisticsWithValidator) {
-
-    //a validator for the unittest
-    AuthCounters::validator_type validator;
-    ConstElementPtr el;
-
-    // Get statistics data with correct statistics validator.
-    validator = boost::bind(
-        &AuthCountersTest::MockModuleSpec::validateStatistics,
-        &module_spec_, _1, true);
-
-    EXPECT_TRUE(validator(el));
-
-    // register validator to AuthCounters
-    counters.registerStatisticsValidator(validator);
-
-    // Counters should be initialized to 0.
-    EXPECT_EQ(0, counters.getCounter(AuthCounters::SERVER_UDP_QUERY));
-    EXPECT_EQ(0, counters.getCounter(AuthCounters::SERVER_TCP_QUERY));
-
-    // UDP query counter is set to 2.
-    counters.inc(AuthCounters::SERVER_UDP_QUERY);
-    counters.inc(AuthCounters::SERVER_UDP_QUERY);
-    // TCP query counter is set to 1.
-    counters.inc(AuthCounters::SERVER_TCP_QUERY);
-
-    // checks the value returned by getStatistics
-    ConstElementPtr statistics_data = counters.getStatistics();
-
-    // UDP query counter is 2 and TCP query counter is 1.
-    EXPECT_EQ(2, statistics_data->get("queries.udp")->intValue());
-    EXPECT_EQ(1, statistics_data->get("queries.tcp")->intValue());
-
-    // Get statistics data with incorrect statistics validator.
-    validator = boost::bind(
-        &AuthCountersTest::MockModuleSpec::validateStatistics,
-        &module_spec_, _1, false);
-
-    EXPECT_FALSE(validator(el));
-
-    counters.registerStatisticsValidator(validator);
-
-    // checks the value returned by getStatistics
-    EXPECT_FALSE(counters.getStatistics());
-}
 }
diff --git a/src/lib/statistics/Makefile.am b/src/lib/statistics/Makefile.am
index 206b527..e3543a2 100644
--- a/src/lib/statistics/Makefile.am
+++ b/src/lib/statistics/Makefile.am
@@ -1,4 +1,4 @@
-SUBDIRS = . tests
+SUBDIRS = tests
 
 AM_CPPFLAGS = -I$(top_srcdir)/src/lib -I$(top_builddir)/src/lib
 AM_CPPFLAGS += $(BOOST_INCLUDES) $(MULTITHREADING_FLAG)
@@ -17,8 +17,4 @@ if USE_CLANGPP
 AM_CXXFLAGS += -Wno-unused-parameter
 endif
 
-lib_LTLIBRARIES = libb10-statistics.la
-libb10_statistics_la_SOURCES  = counter.h counter.cc
-libb10_statistics_la_SOURCES  += counter_dict.h counter_dict.cc
-
 CLEANFILES = *.gcno *.gcda
diff --git a/src/lib/statistics/counter.cc b/src/lib/statistics/counter.cc
deleted file mode 100644
index 53dc58e..0000000
--- a/src/lib/statistics/counter.cc
+++ /dev/null
@@ -1,82 +0,0 @@
-// Copyright (C) 2011  Internet Systems Consortium, Inc. ("ISC")
-//
-// Permission to use, copy, modify, and/or distribute this software for any
-// purpose with or without fee is hereby granted, provided that the above
-// copyright notice and this permission notice appear in all copies.
-//
-// THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
-// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
-// AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
-// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
-// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
-// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
-// PERFORMANCE OF THIS SOFTWARE.
-
-#include <vector>
-
-#include <boost/noncopyable.hpp>
-
-#include <statistics/counter.h>
-
-namespace {
-const unsigned int InitialValue = 0;
-} // namespace
-
-namespace isc {
-namespace statistics {
-
-class CounterImpl : boost::noncopyable {
-    private:
-        std::vector<Counter::Value> counters_;
-    public:
-        CounterImpl(const size_t nelements);
-        ~CounterImpl();
-        void inc(const Counter::Type&);
-        const Counter::Value& get(const Counter::Type&) const;
-};
-
-CounterImpl::CounterImpl(const size_t items) :
-    counters_(items, InitialValue)
-{
-    if (items == 0) {
-        isc_throw(isc::InvalidParameter, "Items must not be 0");
-    }
-}
-
-CounterImpl::~CounterImpl() {}
-
-void
-CounterImpl::inc(const Counter::Type& type) {
-    if(type >= counters_.size()) {
-        isc_throw(isc::OutOfRange, "Counter type is out of range");
-    }
-    ++counters_.at(type);
-    return;
-}
-
-const Counter::Value&
-CounterImpl::get(const Counter::Type& type) const {
-    if(type >= counters_.size()) {
-        isc_throw(isc::OutOfRange, "Counter type is out of range");
-    }
-    return (counters_.at(type));
-}
-
-Counter::Counter(const size_t items) : impl_(new CounterImpl(items))
-{}
-
-Counter::~Counter() {}
-
-void
-Counter::inc(const Type& type) {
-    impl_->inc(type);
-    return;
-}
-
-const Counter::Value&
-Counter::get(const Type& type) const {
-    return (impl_->get(type));
-}
-
-}   // namespace statistics
-}   // namespace isc
diff --git a/src/lib/statistics/counter.h b/src/lib/statistics/counter.h
index 9e467ce..ed5c276 100644
--- a/src/lib/statistics/counter.h
+++ b/src/lib/statistics/counter.h
@@ -15,24 +15,29 @@
 #ifndef __COUNTER_H
 #define __COUNTER_H 1
 
+#include <exceptions/exceptions.h>
+
 #include <boost/noncopyable.hpp>
 #include <boost/scoped_ptr.hpp>
 
-#include <exceptions/exceptions.h>
+#include <vector>
+
+namespace {
+const unsigned int InitialValue = 0;
+} // anonymous namespace
 
 namespace isc {
 namespace statistics {
 
-// forward declaration for pImpl idiom
-class CounterImpl;
-
 class Counter : boost::noncopyable {
-private:
-    boost::scoped_ptr<CounterImpl> impl_;
 public:
     typedef unsigned int Type;
     typedef unsigned int Value;
 
+private:
+    std::vector<Counter::Value> counters_;
+
+public:
     /// The constructor.
     ///
     /// This constructor is mostly exception free. But it may still throw
@@ -41,29 +46,56 @@ public:
     /// \param items A number of counter items to hold (greater than 0)
     ///
     /// \throw isc::InvalidParameter \a items is 0
-    Counter(const size_t items);
+    explicit inline Counter(const size_t items);
 
     /// The destructor.
     ///
     /// This method never throws an exception.
-    ~Counter();
+    inline ~Counter();
 
     /// \brief Increment a counter item specified with \a type.
     ///
     /// \param type %Counter item to increment
     ///
     /// \throw isc::OutOfRange \a type is invalid
-    void inc(const Type& type);
+    inline void inc(const Counter::Type);
 
     /// \brief Get the value of a counter item specified with \a type.
     ///
     /// \param type %Counter item to get the value of
     ///
     /// \throw isc::OutOfRange \a type is invalid
-    const Value& get(const Type& type) const;
+    inline const Counter::Value& get(const Counter::Type) const;
 };
 
+inline Counter::Counter(const size_t items) :
+    counters_(items, InitialValue)
+{
+    if (items == 0) {
+        isc_throw(isc::InvalidParameter, "Items must not be 0");
+    }
+}
+
+inline Counter::~Counter() {}
+
+inline void
+Counter::inc(const Counter::Type type) {
+    if(type >= counters_.size()) {
+        isc_throw(isc::OutOfRange, "Counter type is out of range");
+    }
+    ++counters_.at(type);
+    return;
+}
+
+inline const Counter::Value&
+Counter::get(const Counter::Type type) const {
+    if(type >= counters_.size()) {
+        isc_throw(isc::OutOfRange, "Counter type is out of range");
+    }
+    return (counters_.at(type));
+}
+
 }   // namespace statistics
 }   // namespace isc
 
-#endif
+#endif // __COUNTER_H
diff --git a/src/lib/statistics/counter_dict.cc b/src/lib/statistics/counter_dict.cc
deleted file mode 100644
index 55353b2..0000000
--- a/src/lib/statistics/counter_dict.cc
+++ /dev/null
@@ -1,265 +0,0 @@
-// Copyright (C) 2011  Internet Systems Consortium, Inc. ("ISC")
-//
-// Permission to use, copy, modify, and/or distribute this software for any
-// purpose with or without fee is hereby granted, provided that the above
-// copyright notice and this permission notice appear in all copies.
-//
-// THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
-// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
-// AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
-// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
-// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
-// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
-// PERFORMANCE OF THIS SOFTWARE.
-
-#include <cassert>
-#include <stdexcept>
-#include <iterator>
-#include <map>
-#include <boost/noncopyable.hpp>
-#include <boost/shared_ptr.hpp>
-
-#include <statistics/counter_dict.h>
-
-namespace {
-typedef boost::shared_ptr<isc::statistics::Counter> CounterPtr;
-typedef std::map<std::string, CounterPtr> DictionaryMap;
-}
-
-namespace isc {
-namespace statistics {
-
-// Implementation detail class for CounterDictionary::ConstIterator
-class CounterDictionaryConstIteratorImpl;
-
-class CounterDictionaryImpl : boost::noncopyable {
-private:
-    DictionaryMap dictionary_;
-    std::vector<std::string> elements_;
-    const size_t items_;
-    // Default constructor is forbidden; number of counter items must be
-    // specified at the construction of this class.
-    CounterDictionaryImpl();
-public:
-    CounterDictionaryImpl(const size_t items);
-    ~CounterDictionaryImpl();
-    void addElement(const std::string& name);
-    void deleteElement(const std::string& name);
-    Counter& getElement(const std::string& name);
-public:
-    CounterDictionaryConstIteratorImpl begin() const;
-    CounterDictionaryConstIteratorImpl end() const;
-};
-
-// Constructor with number of items
-CounterDictionaryImpl::CounterDictionaryImpl(const size_t items) :
-    items_(items)
-{
-    // The number of items must not be 0
-    if (items == 0) {
-        isc_throw(isc::InvalidParameter, "Items must not be 0");
-    }
-}
-
-// Destructor
-CounterDictionaryImpl::~CounterDictionaryImpl() {}
-
-void
-CounterDictionaryImpl::addElement(const std::string& name) {
-    // throw if the element already exists
-    if (dictionary_.count(name) != 0) {
-        isc_throw(isc::InvalidParameter,
-                  "Element " << name << " already exists");
-    }
-    assert(items_ != 0);
-    // Create a new Counter and add to the map
-    dictionary_.insert(
-        DictionaryMap::value_type(name, CounterPtr(new Counter(items_))));
-}
-
-void
-CounterDictionaryImpl::deleteElement(const std::string& name) {
-    size_t result = dictionary_.erase(name);
-    if (result != 1) {
-        // If an element with specified name does not exist, throw
-        // isc::OutOfRange.
-        isc_throw(isc::OutOfRange, "Element " << name << " does not exist");
-    }
-}
-
-Counter&
-CounterDictionaryImpl::getElement(const std::string& name) {
-    DictionaryMap::const_iterator i = dictionary_.find(name);
-    if (i != dictionary_.end()) {
-        // the key was found. return the element.
-        return (*(i->second));
-    } else {
-        // If an element with specified name does not exist, throw
-        // isc::OutOfRange.
-        isc_throw(isc::OutOfRange, "Element " << name << " does not exist");
-    }
-}
-
-// Constructor
-// Initialize impl_
-CounterDictionary::CounterDictionary(const size_t items) :
-    impl_(new CounterDictionaryImpl(items))
-{}
-
-// Destructor
-// impl_ will be freed automatically with scoped_ptr
-CounterDictionary::~CounterDictionary() {}
-
-void
-CounterDictionary::addElement(const std::string& name) {
-    impl_->addElement(name);
-}
-
-void
-CounterDictionary::deleteElement(const std::string& name) {
-    impl_->deleteElement(name);
-}
-
-Counter&
-CounterDictionary::getElement(const std::string& name) const {
-    return (impl_->getElement(name));
-}
-
-Counter&
-CounterDictionary::operator[](const std::string& name) const {
-    return (impl_->getElement(name));
-}
-
-// Implementation detail class for CounterDictionary::ConstIterator
-class CounterDictionaryConstIteratorImpl {
-    public:
-        CounterDictionaryConstIteratorImpl();
-        ~CounterDictionaryConstIteratorImpl();
-        CounterDictionaryConstIteratorImpl(
-            const CounterDictionaryConstIteratorImpl &other);
-        CounterDictionaryConstIteratorImpl &operator=(
-            const CounterDictionaryConstIteratorImpl &source);
-        CounterDictionaryConstIteratorImpl(
-            DictionaryMap::const_iterator iterator);
-    public:
-        void increment();
-        const CounterDictionary::ConstIterator::value_type&
-            dereference() const;
-        bool equal(const CounterDictionaryConstIteratorImpl& other) const;
-    private:
-        DictionaryMap::const_iterator iterator_;
-};
-
-CounterDictionaryConstIteratorImpl::CounterDictionaryConstIteratorImpl() {}
-
-CounterDictionaryConstIteratorImpl::~CounterDictionaryConstIteratorImpl() {}
-
-// Copy constructor: deep copy of iterator_
-CounterDictionaryConstIteratorImpl::CounterDictionaryConstIteratorImpl(
-    const CounterDictionaryConstIteratorImpl &other) :
-    iterator_(other.iterator_)
-{}
-
-// Assignment operator: deep copy of iterator_
-CounterDictionaryConstIteratorImpl &
-CounterDictionaryConstIteratorImpl::operator=(
-    const CounterDictionaryConstIteratorImpl &source)
-{
-    iterator_ = source.iterator_;
-    return (*this);
-}
-
-// Constructor from implementation detail DictionaryMap::const_iterator
-CounterDictionaryConstIteratorImpl::CounterDictionaryConstIteratorImpl(
-    DictionaryMap::const_iterator iterator) :
-    iterator_(iterator)
-{}
-
-CounterDictionaryConstIteratorImpl
-CounterDictionaryImpl::begin() const {
-    return (CounterDictionaryConstIteratorImpl(dictionary_.begin()));
-}
-
-CounterDictionaryConstIteratorImpl
-CounterDictionaryImpl::end() const {
-    return (CounterDictionaryConstIteratorImpl(dictionary_.end()));
-}
-
-void
-CounterDictionaryConstIteratorImpl::increment() {
-    ++iterator_;
-    return;
-}
-
-const CounterDictionary::ConstIterator::value_type&
-CounterDictionaryConstIteratorImpl::dereference() const {
-    return (iterator_->first);
-}
-
-bool
-CounterDictionaryConstIteratorImpl::equal(
-    const CounterDictionaryConstIteratorImpl& other) const
-{
-    return (iterator_ == other.iterator_);
-}
-
-CounterDictionary::ConstIterator
-CounterDictionary::begin() const {
-    return (CounterDictionary::ConstIterator(
-               CounterDictionaryConstIteratorImpl(impl_->begin())));
-}
-
-CounterDictionary::ConstIterator
-CounterDictionary::end() const {
-    return (CounterDictionary::ConstIterator(
-               CounterDictionaryConstIteratorImpl(impl_->end())));
-}
-
-CounterDictionary::ConstIterator::ConstIterator() :
-    impl_(new CounterDictionaryConstIteratorImpl())
-{}
-
-CounterDictionary::ConstIterator::~ConstIterator() {}
-
-// Copy constructor: deep copy of impl_
-CounterDictionary::ConstIterator::ConstIterator(
-    const CounterDictionary::ConstIterator& source) :
-    impl_(new CounterDictionaryConstIteratorImpl(*(source.impl_)))
-{}
-
-// Assignment operator: deep copy of impl_
-CounterDictionary::ConstIterator &
-CounterDictionary::ConstIterator::operator=(
-    const CounterDictionary::ConstIterator &source)
-{
-    *impl_ = *source.impl_;
-    return (*this);
-}
-
-// The constructor from implementation detail
-CounterDictionary::ConstIterator::ConstIterator(
-    const CounterDictionaryConstIteratorImpl& source) :
-    impl_(new CounterDictionaryConstIteratorImpl(source))
-{}
-
-const CounterDictionary::ConstIterator::value_type&
-CounterDictionary::ConstIterator::dereference() const
-{
-    return (impl_->dereference());
-}
-
-bool
-CounterDictionary::ConstIterator::equal(
-    CounterDictionary::ConstIterator const& other) const
-{
-    return (impl_->equal(*(other.impl_)));
-}
-
-void
-CounterDictionary::ConstIterator::increment() {
-    impl_->increment();
-    return;
-}
-
-}   // namespace statistics
-}   // namespace isc
diff --git a/src/lib/statistics/counter_dict.h b/src/lib/statistics/counter_dict.h
index e322119..3715fc2 100644
--- a/src/lib/statistics/counter_dict.h
+++ b/src/lib/statistics/counter_dict.h
@@ -15,67 +15,45 @@
 #ifndef __COUNTER_DICT_H
 #define __COUNTER_DICT_H 1
 
-#include <string>
-#include <vector>
-#include <utility>
+#include <statistics/counter.h>
+#include <exceptions/exceptions.h>
+
 #include <boost/noncopyable.hpp>
 #include <boost/scoped_ptr.hpp>
+#include <boost/shared_ptr.hpp>
 #include <boost/iterator/iterator_facade.hpp>
 
-#include <exceptions/exceptions.h>
-#include <statistics/counter.h>
+#include <cassert>
+#include <stdexcept>
+#include <string>
+#include <vector>
+#include <map>
+#include <iterator>
+#include <utility>
+
+namespace {
+typedef boost::shared_ptr<isc::statistics::Counter> CounterPtr;
+typedef std::map<std::string, CounterPtr> DictionaryMap;
+}
 
 namespace isc {
 namespace statistics {
 
-class CounterDictionaryImpl;
-class CounterDictionaryConstIteratorImpl;
-
 class CounterDictionary : boost::noncopyable {
 private:
-    boost::scoped_ptr<CounterDictionaryImpl> impl_;
+    DictionaryMap dictionary_;
+    std::vector<std::string> elements_;
+    const size_t items_;
     // Default constructor is forbidden; number of counter items must be
     // specified at the construction of this class.
     CounterDictionary();
 public:
-    /// The constructor.
-    /// This constructor is mostly exception free. But it may still throw
-    /// a standard exception if memory allocation fails inside the method.
-    ///
-    /// \param items A number of counter items to hold (greater than 0)
-    ///
-    /// \throw isc::InvalidParameter \a items is 0
-    CounterDictionary(const size_t items);
-
-    /// The destructor.
-    ///
-    /// This method never throws an exception.
-    ~CounterDictionary();
-
-    /// \brief Add an element
-    ///
-    /// \throw isc::InvalidParameter \a element already exists.
-    ///
-    /// \param name A name of the element to append
-    void addElement(const std::string& name);
-
-    /// \brief Delete
-    ///
-    /// \throw isc::OutOfRange \a element does not exist.
-    ///
-    /// \param name A name of the element to delete
-    void deleteElement(const std::string& name);
-
-    /// \brief Lookup
-    ///
-    /// \throw isc::OutOfRange \a element does not exist.
-    ///
-    /// \param name A name of the element to get the counters
-    Counter& getElement(const std::string &name) const;
-
-    /// Same as getElement()
-    Counter& operator[](const std::string &name) const;
-
+    explicit inline CounterDictionary(const size_t items);
+    inline ~CounterDictionary();
+    inline void addElement(const std::string& name);
+    inline void deleteElement(const std::string& name);
+    inline Counter& getElement(const std::string& name);
+    inline Counter& operator[](const std::string& name);
     /// \brief \c ConstIterator is a constant iterator that provides an
     /// interface for enumerating name of zones stored in CounterDictionary.
     ///
@@ -90,68 +68,134 @@ public:
                                 const std::string,
                                 boost::forward_traversal_tag>
     {
-        private:
-            boost::scoped_ptr<CounterDictionaryConstIteratorImpl> impl_;
         public:
             /// The constructor.
             ///
             /// This constructor is mostly exception free. But it may still
             /// throw a standard exception if memory allocation fails
             /// inside the method.
-            ConstIterator();
+            inline ConstIterator() {}
             /// The destructor.
             ///
             /// This method never throws an exception.
-            ~ConstIterator();
+            inline ~ConstIterator() {}
             /// The assignment operator.
             ///
             /// This method is mostly exception free. But it may still
             /// throw a standard exception if memory allocation fails
             /// inside the method.
-            ConstIterator& operator=(const ConstIterator &source);
+            inline ConstIterator& operator=(const ConstIterator& source) {
+                iterator_ = source.iterator_;
+                return (*this);
+            }
+
             /// The copy constructor.
             ///
             /// This constructor is mostly exception free. But it may still
             /// throw a standard exception if memory allocation fails
             /// inside the method.
-            ConstIterator(const ConstIterator& source);
-            /// The constructor from implementation detail.
-            ///
-            /// This method is used to create an instance of ConstIterator
-            /// by CounterDict::begin() and CounterDict::end().
-            ///
-            /// This constructor is mostly exception free. But it may still
-            /// throw a standard exception if memory allocation fails
-            /// inside the method.
-            ConstIterator(
-                const CounterDictionaryConstIteratorImpl& source);
+            inline ConstIterator(const ConstIterator& source) :
+                iterator_(source.iterator_)
+            {}
+            //
+            // Constructor from implementation detail DictionaryMap::const_iterator
+            inline ConstIterator(
+                DictionaryMap::const_iterator iterator) :
+                iterator_(iterator)
+            {}
+
         private:
             /// \brief An internal method to increment this iterator.
-            void increment();
+            inline void increment() {
+                ++iterator_;
+                return;
+            }
+
             /// \brief An internal method to check equality.
-            bool equal(const ConstIterator& other) const;
+            inline bool equal(const ConstIterator& other) const {
+                return (iterator_ == other.iterator_);
+            }
+
             /// \brief An internal method to dereference this iterator.
-            const value_type& dereference() const;
+            inline const value_type& dereference() const {
+                return (iterator_->first);
+            }
+
         private:
             friend class boost::iterator_core_access;
+            DictionaryMap::const_iterator iterator_;
     };
 
+    inline ConstIterator begin() const;
+    inline ConstIterator end() const;
+
     typedef ConstIterator const_iterator;
+};
 
-    /// \brief Return an iterator corresponding to the beginning of the
-    /// elements stored in CounterDictionary.
-    ///
-    /// This method is mostly exception free. But it may still throw a
-    /// standard exception if memory allocation fails inside the method.
-    const_iterator begin() const;
 
-    /// \brief Return an iterator corresponding to the end of the elements
-    /// stored in CounterDictionary.
-    ///
-    /// This method is mostly exception free. But it may still throw a
-    /// standard exception if memory allocation fails inside the method.
-    const_iterator end() const;
-};
+inline CounterDictionary::ConstIterator
+CounterDictionary::begin() const {
+    return (CounterDictionary::ConstIterator(dictionary_.begin()));
+}
+
+inline CounterDictionary::ConstIterator
+CounterDictionary::end() const {
+    return (CounterDictionary::ConstIterator(dictionary_.end()));
+}
+
+// Constructor with number of items
+inline CounterDictionary::CounterDictionary(const size_t items) :
+    items_(items)
+{
+    // The number of items must not be 0
+    if (items == 0) {
+        isc_throw(isc::InvalidParameter, "Items must not be 0");
+    }
+}
+
+// Destructor
+inline CounterDictionary::~CounterDictionary() {}
+
+inline void
+CounterDictionary::addElement(const std::string& name) {
+    // throw if the element already exists
+    if (dictionary_.count(name) != 0) {
+        isc_throw(isc::InvalidParameter,
+                  "Element " << name << " already exists");
+    }
+    assert(items_ != 0);
+    // Create a new Counter and add to the map
+    dictionary_.insert(
+        DictionaryMap::value_type(name, CounterPtr(new Counter(items_))));
+}
+
+inline void
+CounterDictionary::deleteElement(const std::string& name) {
+    size_t result = dictionary_.erase(name);
+    if (result != 1) {
+        // If an element with specified name does not exist, throw
+        // isc::OutOfRange.
+        isc_throw(isc::OutOfRange, "Element " << name << " does not exist");
+    }
+}
+
+inline Counter&
+CounterDictionary::getElement(const std::string& name) {
+    DictionaryMap::const_iterator i = dictionary_.find(name);
+    if (i != dictionary_.end()) {
+        // the key was found. return the element.
+        return (*(i->second));
+    } else {
+        // If an element with specified name does not exist, throw
+        // isc::OutOfRange.
+        isc_throw(isc::OutOfRange, "Element " << name << " does not exist");
+    }
+}
+
+inline Counter&
+CounterDictionary::operator[](const std::string& name) {
+    return (getElement(name));
+}
 
 }   // namespace statistics
 }   // namespace isc
diff --git a/src/lib/statistics/tests/Makefile.am b/src/lib/statistics/tests/Makefile.am
index 007c8b0..25a3db2 100644
--- a/src/lib/statistics/tests/Makefile.am
+++ b/src/lib/statistics/tests/Makefile.am
@@ -28,7 +28,6 @@ run_unittests_SOURCES += counter_dict_unittest.cc
 run_unittests_CPPFLAGS = $(AM_CPPFLAGS) $(GTEST_INCLUDES)
 
 run_unittests_LDADD  = $(GTEST_LDADD)
-run_unittests_LDADD += $(top_builddir)/src/lib/statistics/libb10-statistics.la
 run_unittests_LDADD += $(top_builddir)/src/lib/log/libb10-log.la
 run_unittests_LDADD += $(top_builddir)/src/lib/util/unittests/libutil_unittests.la
 run_unittests_LDADD += $(top_builddir)/src/lib/exceptions/libb10-exceptions.la
diff --git a/tests/system/bindctl/tests.sh b/tests/system/bindctl/tests.sh
index 9611c90..edb83c2 100755
--- a/tests/system/bindctl/tests.sh
+++ b/tests/system/bindctl/tests.sh
@@ -25,8 +25,8 @@ status=0
 n=0
 
 # TODO: consider consistency with statistics definition in auth.spec
-cnt_name1="\<queries\.tcp\>"
-cnt_name2="\<queries\.udp\>"
+cnt_name1="\<request\.tcp\>"
+cnt_name2="\<request\.udp\>"
 cnt_name3="\<opcode\.query\>"
 cnt_value1=0
 cnt_value2=0



More information about the bind10-changes mailing list