stat_cmds.dox 7.14 KB
Newer Older
Thomas Markwalder's avatar
Thomas Markwalder committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
// Copyright (C) 2018 Internet Systems Consortium, Inc. ("ISC")
//
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.

/**

@page libdhcp_stat_cmds Kea Stat Commands Hooks Library

@section libdhcp_stat_cmdsIntro Introduction

Welcome to Kea Stat Commands Hooks Library. This documentation is addressed to
developers who are interested in the internal operation of the Stat Commands
library. This file provides information needed to understand and perhaps extend
this library.

This documentation is stand-alone: you should have read and understood <a
19
href="http://oldkea.isc.org/docs/devel/">Kea Developer's Guide</a> and in
Thomas Markwalder's avatar
Thomas Markwalder committed
20 21 22 23
particular its section about hooks.

@section stat_cmds Stat Commands Overview

24 25 26 27 28 29 30 31 32 33 34 35 36
Stat Commands (or stat_cmds) is a Hook library that can be loaded by
either kea-dhcp4 and kea-dhcp6 servers to extend them with additional
statistics mechanisms.

The initial purpose of this library is provide supplemental commands for
obtaining accurate lease statistics in deployments that share lease storage
between multiple Kea DHCP servers. It is likely that additional statistics
related commands will be added to this library in future releases as use
cases for them arise.

The library is structured around command handlers. When the library is
loaded it registers handlers for new commands.  When a command
is issued (be it directly via control channel or indirectly via REST
Thomas Markwalder's avatar
Thomas Markwalder committed
37
interface from control agent), the code receives a JSON command with
38 39 40 41 42 43 44 45 46 47 48
parameters.  The command is routed the appropriate handler, its parameters
are parsed and command executed accordingly.  Lastly, a response is
constructed and shipped back to the client.

This lease statistics commands interact with both the isc::dhcp::StatsMgr
and the isc::dhcp::LeaseMgr instance.  At the time of writing this text
(May, 2018), Kea supports four types of lease managers: memfile, MySQL,
PostgreSQL or Cassandra. The lease statistics commands provided by this
library provide a unified interface supported by all four of these backends.

As with other hooks, this one keeps its code in a separate namespace which
Thomas Markwalder's avatar
Thomas Markwalder committed
49 50
corresponds to the file name of the library: isc::stat_cmds.

51
For background on the design and design choices please refer to: <a
52
href="http://oldkea.isc.org/wiki/SharedLeaseStorageStats">Shared Lease Stats Design</a>
53

Thomas Markwalder's avatar
Thomas Markwalder committed
54 55
@section stat_cmdsCode Stat Commands Code Overview

56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197
Library operation starts with Kea calling the load() function (file
stat_cmds_callouts.cc).  This function registers the command callout
functions for each of the libraries commands. For a list,
see @ref isc::stat_cmds::StatCmds class documentation.  This class uses
the Pimpl design pattern, and thus the actual implementation is hidden
in @ref isc::stat_cmds::LeaseStatCmdsImpl.

Unlike similar libraries, the Pimpl class is differentiated from the
the StatCmds class by the prefix "Lease" and it is instantiated in the outer
handler (e.g. @ref isc::stat_cmds::StatCmds::statLease4GetHandler) rather than
the StatCmds constructor.  This was done in the event that commands, unrelated
to lease statistics, are added to this library and that would be better served
by Pimpl derviations specific to them.

@subsection stat_cmdsLeaseStatCode Lease Stat Commands Code Overview

There are two shared lease statistic commands, "stat-lease4-get" and "stat-lease6-get".
Both of these support the same input parameters and have their own command handlers:

- @ref isc::stat_cmds::LeaseStatCmdsImpl::statLease4GetHandler (stat-lease4-get)
- @ref isc::stat_cmds::LeaseStatCmdsImpl::statLease6GetHandler (stat-lease6-get)

Briefly, the commands are intended to fetch the lease statistics per subnet
for the range of subnets described by the input parameters.  JSON text structure
of the commands is as follows:

DHCPv4 command:

@code
{
    "command": "stat-lease4-get",
    "arguments": {
        "subnet-id": x
        "subnet-range": {
            "first-subnet-id": x,
            "last-subnet-id": y
        }
    }
}

    where subnet-id and subnet-range are optional and mutually exclusive
@endcode

DHCPv6 command:

@code
{
    "command": "stat-lease6-get",
    "arguments": {
        "subnet-id": x
        "subnet-range": {
            "first-subnet-id": x,
            "last-subnet-id": y
        }
    }
}

    where subnet-id and subnet-range are optional and mutually exclusive
@endcode



Command handling
for both commands is symetrical consists of the following steps:

-# The input parameters (if any) are parsed.  Invalid values or
combinations if detected result in generating a CONTROL_RESULT_ERROR
response to the client.  (See @ref isc::stat_cmds::LeaseStatCmdsImpl::getParameters
and @ref isc::stat_cmds::LeaseStatCmdsImpl::Parameters)

-# The parameters are used to identify the range of configured subnets
to include in the response.  This is done by querying subnet configuration
housed by @ref isc::dhcp::CfgMgr. If the range contains no known subnets then a
CONTROL_RESULT_EMPTY response is sent back to the client.

-# The initial result-set response is constructed.  Essentially this is
an @ref isc::data::Element tree, which converted to JSON would appear as follows:

@code
    "result-set": {
        "timestamp": "2018-03-22 09:43:30.815371",
        "columns": ["<label-1>, <label-2>, ... ],
        "rows": []
    }
@endcode

-# The acutal lease statistics are then retrieved from @ref isc::dhcp::LeaseMgr instance
by invoking of the three functions based on the input parameters:

DHCPv4 functions:

- @ref isc::dhcp::LeaseMgr::startLeaseStatsQuery4
- @ref isc::dhcp::LeaseMgr::startSubnetLeaseStatsQuery4
- @ref isc::dhcp::LeaseMgr::startSubnetRangeLeaseStatsQuery4

DHCPv6 functions:

- @ref isc::dhcp::LeaseMgr::startLeaseStatsQuery6
- @ref isc::dhcp::LeaseMgr::startSubnetLeaseStatsQuery6
- @ref isc::dhcp::LeaseMgr::startSubnetRangeLeaseStatsQuery6

-# Iterate over the range of qualifying subnets adding a row of statistics for
each subnet to the result-set.  Each row combines the subnet total(s) from isc::dhcp::StatsMgr
with the type and state counts from the lease query results. For subnets with no query
data (i.e. no leases), their rows have non-zero values for totals only.

-# Finally, a CONTROL_RESULT_SUCCESS repsonse is generated containing the populated result-set.

A DHCPv4 response might look like this:

@code
        {
        "result-set\": {
           "columns\": [
                "subnet-id", "total-addreses",
                "assigned-addreses", "declined-addreses"
           ],
           "rows\": [
               [ 30, 256, 100, 2 ],
               [ 40,  16, 0, 0 ],
               [ 50, 256, 35, 0 ],
           ],
           timestamp\": \"2018-05-04 15:03:37.000000\" }
        }
@endcode

and DHCPv6 response might look like this:

@code
        {
        "result-set": {
           "columns": [
                "subnet-id", "total-nas", "assigned-nas",
                "declined-nas", "total-pds", "assigned-pds"
           ],
           "rows": [
               [ 30, 16, 6, 0, 65536, 400 ],
               [ 40, 16777216, 989837, 0, 0, 0 ]
           ],
           "timestamp": "2018-05-04 15:03:37.000000" }
        }
@endcode
Thomas Markwalder's avatar
Thomas Markwalder committed
198 199

*/