'\" t
.\" Title: b10-stats
.\" Author: [FIXME: author] [see http://docbook.sf.net/el/author]
-.\" Generator: DocBook XSL Stylesheets v1.75.2 <http://docbook.sf.net/>
+.\" Generator: DocBook XSL Stylesheets v1.77.1 <http://docbook.sf.net/>
.\" Date: June 20, 2012
.\" Manual: BIND10
.\" Source: BIND10
.\"
.TH "B10\-STATS" "8" "June 20, 2012" "BIND10" "BIND10"
.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
.\" * set default formatting
.\" -----------------------------------------------------------------
.\" disable hyphenation
with other modules like
\fBbind10\fR,
\fBb10\-auth\fR
-and so on\&. It waits for coming data from other modules, then other modules send data to stats module periodically\&. Other modules send stats data to stats module independently from implementation of stats module, so the frequency of sending data may not be constant\&. The stats module collects data and aggregates it\&.
+and so on\&.
+\fBb10\-stats\fR
+periodically requests statistics data to each module and receives\&. The interval time can be configured via
+\fBbindctl\fR\&.
+\fBb10\-stats\fR
+cannot accept any command from other modules for updating statistics data\&. The stats module collects data and aggregates it\&.
\fBb10\-stats\fR
invokes an internal command for
\fBbind10\fR
.RE
.SH "CONFIGURATION AND COMMANDS"
.PP
-The
+The configurable setting in
+stats\&.spec
+is:
+.PP
+\fIpoll\-interval\fR
+.RS 4
+is a timer interval in seconds for
\fBb10\-stats\fR
-command does not have any configurable settings\&.
+to polling each module for its statistics data\&. The default is 60 second\&. Polling can be disabled by setting to 0\&. The type of the value should be an unsigned integer\&. Setting to a negative integer is ignored\&.
+.RE
.PP
The configuration commands are:
.PP
-\fBset\fR
-will set new statistics data specified in arguments\&. Statistics data to be set and the module name which owns statistics data are required in argument\&. Pid of the module in argument is optional\&.
-.PP
-
\fBshow\fR
will send the statistics data in JSON format\&. By default, it outputs all the statistics data it has collected\&. An optional item name may be specified to receive individual output\&.
.PP
.PP
boot_time
.RS 4
-The date and time when this daemon was started in ISO 8601 format\&. This is a constant which can\'t be reset except by restarting
+The date and time when this daemon was started in ISO 8601 format\&. This is a constant which can\*(Aqt be reset except by restarting
\fBb10\-stats\fR\&.
.RE
.PP
.RS 4
This is the name used for the
\fBb10\-msgq\fR
-command\-control channel\&. (This is a constant which can\'t be reset except by restarting
+command\-control channel\&. (This is a constant which can\*(Aqt be reset except by restarting
\fBb10\-stats\fR\&.)
.RE
.PP
<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
"http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd"
- [<!ENTITY mdash "—">]>
+ [<!ENTITY mdash "—">]>
<!--
- Copyright (C) 2010-2012 Internet Systems Consortium, Inc. ("ISC")
-
<command>bind10</command> and communicates by using the
Command Channel by <command>b10-msgq</command> with other
modules like <command>bind10</command>, <command>b10-auth</command>
- and so on. It waits for coming data from other modules, then
- other modules send data to stats module periodically. Other
- modules send stats data to stats module independently from
- implementation of stats module, so the frequency of sending
- data may not be constant. The stats module collects data and
+ and so on. <command>b10-stats</command> periodically requests statistics
+ data to each module and receives. The interval time can be configured
+ via <command>bindctl</command>. <command>b10-stats</command> cannot
+ accept any command from other modules for updating statistics data. The
+ stats module collects data and
aggregates it. <command>b10-stats</command> invokes an internal
command for <command>bind10</command> after its initial
starting to make sure it collects statistics data from
<varlistentry>
<term><option>-v</option>, <option>--verbose</option></term>
<listitem>
- <para>
- This enables maximum debug logging.
- </para>
+ <para>
+ This enables maximum debug logging.
+ </para>
</listitem>
</varlistentry>
</variablelist>
<title>CONFIGURATION AND COMMANDS</title>
<para>
- The <command>b10-stats</command> command does not have any
- configurable settings.
+ The configurable setting in <filename>stats.spec</filename> is:
</para>
+ <variablelist>
+ <varlistentry>
+ <term><varname>poll-interval</varname></term>
+ <listitem>
+ <para>
+ is a timer interval in seconds for <command>b10-stats</command> to
+ polling each module for its statistics data. The default is 60
+ second. Polling can be disabled by setting to 0. The type of the
+ value should be an unsigned integer. Setting to a negative integer
+ is ignored.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+
<!-- TODO: formating -->
<para>
The configuration commands are:
</para>
- <para>
- <command>set</command> will set new statistics data specified in
- arguments. Statistics data to be set and the module name which owns
- statistics data are required in argument. Pid of the module in argument
- is optional.
- </para>
-
<para>
<command>show</command> will send the statistics data
in JSON format.
self.assertTrue('command_shutdown' in self.stats.callbacks)
self.assertTrue('command_show' in self.stats.callbacks)
self.assertTrue('command_showschema' in self.stats.callbacks)
- self.assertTrue('command_set' in self.stats.callbacks)
self.assertEqual(self.stats.config['poll-interval'], 60)
def test_init_undefcmd(self):
params={ 'owner' : 'Boss',
'name' : 'boot_time' }),
(0, {'Boss': {'boot_time': self.const_datetime}}))
- self.assertEqual(
- send_command(
- 'set', 'Stats',
- params={ 'owner' : 'Boss',
- 'data' : { 'boot_time' : self.const_datetime } }),
- (0, None))
self.assertEqual(
send_command(
'show', 'Stats',
isc.config.create_answer(
1, "module name is not specified"))
- def test_command_set(self):
- orig_get_datetime = stats.get_datetime
- stats.get_datetime = lambda : self.const_datetime
- (rcode, value) = isc.config.ccsession.parse_answer(
- self.stats.command_set(owner='Boss',
- data={ 'boot_time' : self.const_datetime }))
- stats.get_datetime = orig_get_datetime
- self.assertEqual(rcode, 0)
- self.assertTrue(value is None)
- self.assertEqual(self.stats.statistics_data['Boss']['boot_time'],
- self.const_datetime)
- self.assertEqual(self.stats.statistics_data['Stats']['last_update_time'],
- self.const_datetime)
- self.assertEqual(self.stats.command_set(owner='Stats',
- data={ 'lname' : 'foo@bar' }),
- isc.config.create_answer(0, None))
- self.stats.statistics_data['Stats'] = {}
- self.stats.mccs.specification = isc.config.module_spec.ModuleSpec(
- { "module_name": self.stats.module_name,
- "statistics": [] } )
- self.assertEqual(self.stats.command_set(owner='Stats',
- data={ 'lname' : '_foo_@_bar_' }),
- isc.config.create_answer(
- 1,
- "errors while setting statistics data: unknown item lname"))
- self.stats.statistics_data['Stats'] = {}
- self.stats.mccs.specification = isc.config.module_spec.ModuleSpec(
- { "module_name": self.stats.module_name } )
- self.assertEqual(self.stats.command_set(owner='Stats',
- data={ 'lname' : '_foo_@_bar_' }),
- isc.config.create_answer(
- 1,
- "errors while setting statistics data: No statistics specification"))
- self.stats.statistics_data['Stats'] = {}
- self.stats.mccs.specification = isc.config.module_spec.ModuleSpec(
- { "module_name": self.stats.module_name,
- "statistics": [
- {
- "item_name": "dummy",
- "item_type": "string",
- "item_optional": False,
- "item_default": "",
- "item_title": "Local Name",
- "item_description": "brabra"
- } ] } )
- self.assertRaises(stats.StatsError,
- self.stats.command_set, owner='Stats', data={ 'dummy' : '_xxxx_yyyy_zzz_' })
-
- def test_command_set_withpid(self):
- # one pid of Auth
- retval = isc.config.ccsession.parse_answer(
- self.stats.command_set(owner='Auth',
- pid=9997,
- data={ 'queries.tcp' : 1001,
- 'queries.perzone':
- [{ 'zonename': 'test1.example',
- 'queries.tcp': 1 },
- { 'zonename': 'test2.example',
- 'queries.tcp': 2,
- 'queries.udp': 3 }]}))
- self.assertEqual(retval, (0,None))
- self.assertTrue('Auth' in self.stats.statistics_data)
- self.assertTrue('queries.tcp' in self.stats.statistics_data['Auth'])
- self.assertEqual(self.stats.statistics_data['Auth']['queries.tcp'], 1001)
- self.assertEqual(self.stats.statistics_data['Auth']['queries.perzone'],
- [{ 'zonename': 'test1.example',
- 'queries.tcp': 1 },
- { 'zonename': 'test2.example',
- 'queries.tcp': 2,
- 'queries.udp': 3 }])
- self.assertTrue('Stats' in self.stats.statistics_data)
- self.assertTrue('last_update_time' in self.stats.statistics_data['Stats'])
- self.assertTrue('Auth' in self.stats.statistics_data_bypid)
- self.assertTrue(9997 in self.stats.statistics_data_bypid['Auth'])
- self.assertTrue('queries.tcp' in self.stats.statistics_data_bypid['Auth'][9997])
- self.assertTrue('queries.perzone' in self.stats.statistics_data_bypid['Auth'][9997])
- self.assertEqual(self.stats.statistics_data_bypid['Auth'][9997]['queries.tcp'], 1001)
- self.assertEqual(self.stats.statistics_data_bypid['Auth'][9997]['queries.perzone'],
- [{ 'zonename': 'test1.example',
- 'queries.tcp': 1 },
- { 'zonename': 'test2.example',
- 'queries.tcp': 2,
- 'queries.udp': 3 }])
- # check consolidation of statistics data even if there is
- # non-existent pid of Auth
- retval = isc.config.ccsession.parse_answer(
- self.stats.command_set(owner='Auth',
- pid=10000,
- data={ 'queries.tcp' : 2001,
- 'queries.perzone':
- [{ 'zonename': 'test1.example',
- 'queries.tcp': 101 },
- { 'zonename': 'test2.example',
- 'queries.tcp': 102,
- 'queries.udp': 103 }]}))
- self.assertEqual(retval, (0,None))
- self.assertTrue('Auth' in self.stats.statistics_data)
- self.assertTrue('queries.tcp' in self.stats.statistics_data['Auth'])
- self.assertEqual(self.stats.statistics_data['Auth']['queries.tcp'], 3002)
- self.assertEqual(self.stats.statistics_data['Auth']['queries.perzone'],
- [{ 'zonename': 'test1.example',
- 'queries.tcp': 102 },
- { 'zonename': 'test2.example',
- 'queries.tcp': 104,
- 'queries.udp': 106 }])
- self.assertTrue('Auth' in self.stats.statistics_data_bypid)
- self.assertTrue(9997 in self.stats.statistics_data_bypid['Auth'])
- self.assertTrue('queries.tcp' in self.stats.statistics_data_bypid['Auth'][9997])
- self.assertEqual(self.stats.statistics_data_bypid['Auth'][9997]['queries.tcp'], 1001)
- self.assertEqual(self.stats.statistics_data_bypid['Auth'][9997]['queries.perzone'],
- [{ 'zonename': 'test1.example',
- 'queries.tcp': 1 },
- { 'zonename': 'test2.example',
- 'queries.tcp': 2,
- 'queries.udp': 3 }])
- # another pid of Auth
- retval = isc.config.ccsession.parse_answer(
- self.stats.command_set(owner='Auth',
- pid=9996,
- data={ 'queries.tcp' : 1002,
- 'queries.udp' : 1003,
- 'queries.perzone':
- [{ 'zonename': 'test1.example',
- 'queries.tcp': 10,
- 'queries.udp': 11},
- { 'zonename': 'test2.example',
- 'queries.tcp': 12,
- 'queries.udp': 13 }]}))
- self.assertEqual(retval, (0,None))
- self.assertTrue('Auth' in self.stats.statistics_data)
- self.assertTrue('queries.tcp' in self.stats.statistics_data['Auth'])
- self.assertTrue('queries.udp' in self.stats.statistics_data['Auth'])
- self.assertTrue('queries.perzone' in self.stats.statistics_data['Auth'])
- self.assertEqual(self.stats.statistics_data['Auth']['queries.tcp'], 4004)
- self.assertEqual(self.stats.statistics_data['Auth']['queries.udp'], 1003)
- self.assertEqual(self.stats.statistics_data['Auth']['queries.perzone'],
- [{ 'zonename': 'test1.example',
- 'queries.tcp': 112,
- 'queries.udp': 11},
- { 'zonename': 'test2.example',
- 'queries.tcp': 116,
- 'queries.udp': 119 }])
- self.assertTrue('Auth' in self.stats.statistics_data_bypid)
- self.assertTrue(9997 in self.stats.statistics_data_bypid['Auth'])
- self.assertTrue(9996 in self.stats.statistics_data_bypid['Auth'])
- self.assertTrue('queries.tcp' in self.stats.statistics_data_bypid['Auth'][9997])
- self.assertTrue('queries.udp' in self.stats.statistics_data_bypid['Auth'][9996])
- self.assertTrue('queries.udp' in self.stats.statistics_data_bypid['Auth'][9996])
- self.assertTrue('queries.perzone' in self.stats.statistics_data_bypid['Auth'][9996])
- self.assertEqual(self.stats.statistics_data_bypid['Auth'][9997]['queries.tcp'], 1001)
- self.assertEqual(self.stats.statistics_data_bypid['Auth'][9997]['queries.perzone'],
- [{ 'zonename': 'test1.example',
- 'queries.tcp': 1 },
- { 'zonename': 'test2.example',
- 'queries.tcp': 2,
- 'queries.udp': 3 }])
- self.assertEqual(self.stats.statistics_data_bypid['Auth'][9996]['queries.tcp'], 1002)
- self.assertEqual(self.stats.statistics_data_bypid['Auth'][9996]['queries.udp'], 1003)
- self.assertEqual(self.stats.statistics_data_bypid['Auth'][9996]['queries.perzone'],
- [{ 'zonename': 'test1.example',
- 'queries.tcp': 10,
- 'queries.udp': 11},
- { 'zonename': 'test2.example',
- 'queries.tcp': 12,
- 'queries.udp': 13 }])
-
class TestOSEnv(unittest.TestCase):
def test_osenv(self):
"""