Statistics Lifecycle
====================
-It is useful to understand how the Statistics Manager module works.
-Since Kea 1.7.0 when the server starts operation, the manager contains
-all statistics related to runned type of DHCP server, initialized with
-default value. If the ``statistic-get-all`` command is executed at that point,
-a list with these statistics is returned. Once the server performs an operation
-that causes a statistic to change, the related statistic will be created or updated.
-In general, once a statistic is recorded even once, it is kept in the manager
-until explicitly removed, by ``statistic-remove`` or ``statistic-remove-all``
+In Kea 1.6.0 version and earlier, when the Kea server is started some
+of the statistics are initially not returned. For example, the ``pkt4-received``
+statistic is not initialized until the first DHCP packet is received.
+In the later Kea versions, this behavior has been changed and all of the
+statistics supported by the servers is initialized upon the servers' startup
+and should be returned in response to the commands such as
+``statistic-get-all``. The runtime statistics concerning DHCP packets
+processed is initially set to 0 and is not retained across the server
+restarts.
+
+In general, once a statistic is initialized it is held in the manager until
+explicitly removed, by ``statistic-remove`` or ``statistic-remove-all``
being called, or when the server is shut down.
Per-subnet statistics are explicitly removed when reconfiguration takes place.
-Statistics are considered runtime properties, so they are not retained
-after server restart.
-
Removing a statistic that is updated frequently makes little sense, as
it will be re-added when the server code next records that statistic.
The ``statistic-remove`` and ``statistic-remove-all`` commands are
There are several commands defined that can be used for accessing
(-get), resetting to zero or a neutral value (-reset), or removing a
statistic completely (-remove). We can change the statistics time based
-limit (-sample-age-set) and size based limit (-sample-count-set).
+limit (-sample-age-set) and size based limit (-sample-count-set) which
+control how long or how many samples of the given statistic are retained.
The difference between reset and remove is somewhat subtle.
The reset command sets the value of the statistic to zero or a neutral value,
so after this operation, the statistic will have a value of 0 (integer),
#include <boost/shared_ptr.hpp>
#include <iomanip>
+#include <set>
using namespace isc;
using namespace isc::asiolink;
hook_index_host4_identifier_ = HooksManager::registerHook("host4_identifier");
}
};
- /// Set of all statistics observed in DHCPv4 server
- std::set<std::string> dhcp4_statistics = {
- "pkt4-received",
- "pkt4-discover-received",
- "pkt4-offer-received",
- "pkt4-request-received",
- "pkt4-ack-received",
- "pkt4-nak-received",
- "pkt4-release-received",
- "pkt4-decline-received",
- "pkt4-inform-received",
- "pkt4-unknown-received",
- "pkt4-sent",
- "pkt4-offer-sent",
- "pkt4-ack-sent",
- "pkt4-nak-sent",
- "pkt4-parse-failed",
- "pkt4-receive-drop"
- };
+
+/// List of statistics which is initialized to 0 during the DHCPv4
+/// server startup.
+std::set<std::string> dhcp4_statistics = {
+ "pkt4-received",
+ "pkt4-discover-received",
+ "pkt4-offer-received",
+ "pkt4-request-received",
+ "pkt4-ack-received",
+ "pkt4-nak-received",
+ "pkt4-release-received",
+ "pkt4-decline-received",
+ "pkt4-inform-received",
+ "pkt4-unknown-received",
+ "pkt4-sent",
+ "pkt4-offer-sent",
+ "pkt4-ack-sent",
+ "pkt4-nak-sent",
+ "pkt4-parse-failed",
+ "pkt4-receive-drop"
+};
+
} // end of anonymous namespace
// Declare a Hooks object. As this is outside any function or method, it
isc_throw(BadValue, "query value must not be NULL when"
" creating an instance of the Dhcpv4Exchange");
}
-
// Create response message.
initResponse();
// Select subnet for the query message.
}
void Dhcpv4Srv::setPacketStatisticsDefaults() {
- std::set<std::string>::iterator it;
isc::stats::StatsMgr& stats_mgr = isc::stats::StatsMgr::instance();
// Iterate over set of observed statistics
- for (it = dhcp4_statistics.begin(); it != dhcp4_statistics.end(); ++it) {
+ for (auto it = dhcp4_statistics.begin(); it != dhcp4_statistics.end(); ++it) {
// Initialize them with default value 0
stats_mgr.setValue((*it), static_cast<int64_t>(0));
}
/// @brief Destructor. Used during DHCPv4 service shutdown.
virtual ~Dhcpv4Srv();
- /// @brief This function set to defaults all statistics starting with pkt4-.
- void setPacketStatisticsDefaults();
-
/// @brief Checks if the server is running in a test mode.
///
/// @return true if the server is running in the test mode,
/// server's response.
void processClientName(Dhcpv4Exchange& ex);
+ /// @brief This function sets statistics related to DHCPv4 packets processing
+ /// to their initial values.
+ ///
+ /// All of the statistics observed by the DHCPv4 server and with the names
+ /// like "pkt4-" are reset to 0. This function must be invoked in the class
+ /// constructor.
+ void setPacketStatisticsDefaults();
+
/// @brief this is a prefix added to the content of vendor-class option
///
/// If incoming packet has a vendor class option, its content is
sendUnixCommand("{ \"command\" : \"statistic-get-all\", "
" \"arguments\": {}}", response);
+ std::set<std::string> initial_stats = {
+ "pkt4-received",
+ "pkt4-discover-received",
+ "pkt4-offer-received",
+ "pkt4-request-received",
+ "pkt4-ack-received",
+ "pkt4-nak-received",
+ "pkt4-release-received",
+ "pkt4-decline-received",
+ "pkt4-inform-received",
+ "pkt4-unknown-received",
+ "pkt4-sent",
+ "pkt4-offer-sent",
+ "pkt4-ack-sent",
+ "pkt4-nak-sent",
+ "pkt4-parse-failed",
+ "pkt4-receive-drop"
+ };
+
// preparing the schema which check if all statistics are set to zero
- std::string stats_get_all = "{ \"arguments\": { "
- "\"pkt4-ack-received\": [ [ 0, \"" + isc::util::ptimeToText(StatsMgr::instance().getObservation("pkt4-ack-received")
- ->getInteger().second) + "\" ] ], "
- "\"pkt4-ack-sent\": [ [ 0, \"" + isc::util::ptimeToText(StatsMgr::instance().getObservation("pkt4-ack-sent")
- ->getInteger().second) + "\" ] ], "
- "\"pkt4-decline-received\": [ [ 0, \"" + isc::util::ptimeToText(StatsMgr::instance().getObservation("pkt4-decline-received")
- ->getInteger().second) + "\" ] ], "
- "\"pkt4-discover-received\": [ [ 0, \"" + isc::util::ptimeToText(StatsMgr::instance().getObservation("pkt4-discover-received")
- ->getInteger().second) + "\" ] ], "
- "\"pkt4-inform-received\": [ [ 0, \"" + isc::util::ptimeToText(StatsMgr::instance().getObservation("pkt4-inform-received")
- ->getInteger().second) + "\" ] ], "
- "\"pkt4-nak-received\": [ [ 0, \"" + isc::util::ptimeToText(StatsMgr::instance().getObservation("pkt4-nak-received")
- ->getInteger().second) + "\" ] ], "
- "\"pkt4-nak-sent\": [ [ 0, \"" + isc::util::ptimeToText(StatsMgr::instance().getObservation("pkt4-nak-sent")
- ->getInteger().second) + "\" ] ], "
- "\"pkt4-offer-received\": [ [ 0, \"" + isc::util::ptimeToText(StatsMgr::instance().getObservation("pkt4-offer-received")
- ->getInteger().second) + "\" ] ], "
- "\"pkt4-offer-sent\": [ [ 0, \"" + isc::util::ptimeToText(StatsMgr::instance().getObservation("pkt4-offer-sent")
- ->getInteger().second) + "\" ] ], "
- "\"pkt4-parse-failed\": [ [ 0, \"" + isc::util::ptimeToText(StatsMgr::instance().getObservation("pkt4-parse-failed")
- ->getInteger().second) + "\" ] ], "
- "\"pkt4-receive-drop\": [ [ 0, \"" + isc::util::ptimeToText(StatsMgr::instance().getObservation("pkt4-receive-drop")
- ->getInteger().second) + "\" ] ], "
- "\"pkt4-received\": [ [ 0, \"" + isc::util::ptimeToText(StatsMgr::instance().getObservation("pkt4-received")
- ->getInteger().second) + "\" ] ], "
- "\"pkt4-release-received\": [ [ 0, \"" + isc::util::ptimeToText(StatsMgr::instance().getObservation("pkt4-release-received")
- ->getInteger().second) + "\" ] ], "
- "\"pkt4-request-received\": [ [ 0, \"" + isc::util::ptimeToText(StatsMgr::instance().getObservation("pkt4-request-received")
- ->getInteger().second) + "\" ] ], "
- "\"pkt4-sent\": [ [ 0, \"" + isc::util::ptimeToText(StatsMgr::instance().getObservation("pkt4-sent")
- ->getInteger().second) + "\" ] ], "
- "\"pkt4-unknown-received\": [ [ 0, \"" + isc::util::ptimeToText(StatsMgr::instance().getObservation("pkt4-unknown-received")
- ->getInteger().second) + "\" ] ] }, "
- "\"result\": 0 }";
+ std::ostringstream s;
+ s << "{ \"arguments\": { ";
+ for (auto st = initial_stats.begin(); st != initial_stats.end();) {
+ s << "\"" << *st << "\": [ [ 0, \"";
+ s << isc::util::ptimeToText(StatsMgr::instance().getObservation(*st)->getInteger().second);
+ s << "\" ] ]";
+ if (++st != initial_stats.end()) {
+ s << ", ";
+ }
+ }
+ s << " }, \"result\": 0 }";
+
+ auto stats_get_all = s.str();
EXPECT_EQ(stats_get_all, response);
#include <iomanip>
#include <fstream>
#include <sstream>
+#include <set>
using namespace isc;
using namespace isc::asiolink;
return (option_status);
}
- /// Set of all statistics observed in DHCPv6 server
- std::set<std::string> dhcp6_statistics = {
- "pkt6-received",
- "pkt6-solicit-received",
- "pkt6-advertise-received",
- "pkt6-request-received",
- "pkt6-reply-received",
- "pkt6-renew-received",
- "pkt6-rebind-received",
- "pkt6-decline-received",
- "pkt6-release-received",
- "pkt6-infrequest-received",
- "pkt6-dhcpv4-query-received",
- "pkt6-dhcpv4-response-received",
- "pkt6-unknown-received",
- "pkt6-sent",
- "pkt6-advertise-sent",
- "pkt6-reply-sent",
- "pkt6-dhcpv4-response-sent",
- "pkt6-parse-failed",
- "pkt6-receive-drop"
- };
+/// List of statistics which is initialized to 0 during the DHCPv6
+/// server startup.
+std::set<std::string> dhcp6_statistics = {
+ "pkt6-received",
+ "pkt6-solicit-received",
+ "pkt6-advertise-received",
+ "pkt6-request-received",
+ "pkt6-reply-received",
+ "pkt6-renew-received",
+ "pkt6-rebind-received",
+ "pkt6-decline-received",
+ "pkt6-release-received",
+ "pkt6-infrequest-received",
+ "pkt6-dhcpv4-query-received",
+ "pkt6-dhcpv4-response-received",
+ "pkt6-unknown-received",
+ "pkt6-sent",
+ "pkt6-advertise-sent",
+ "pkt6-reply-sent",
+ "pkt6-dhcpv4-response-sent",
+ "pkt6-parse-failed",
+ "pkt6-receive-drop"
+};
+
}; // anonymous namespace
namespace isc {
}
void Dhcpv6Srv::setPacketStatisticsDefaults() {
- std::set<std::string>::iterator it;
isc::stats::StatsMgr& stats_mgr = isc::stats::StatsMgr::instance();
// Iterate over set of observed statistics
- for (it = dhcp6_statistics.begin(); it != dhcp6_statistics.end(); ++it) {
+ for (auto it = dhcp6_statistics.begin(); it != dhcp6_statistics.end(); ++it) {
// Initialize them with default value 0
stats_mgr.setValue((*it), static_cast<int64_t>(0));
}
/// @brief Destructor. Used during DHCPv6 service shutdown.
virtual ~Dhcpv6Srv();
- /// @brief This function set to defaults all statistics starting with pkt6-.
- void setPacketStatisticsDefaults();
-
/// @brief Checks if the server is running in unit test mode.
///
/// @return true if the server is running in unit test mode,
protected:
+ /// @brief This function sets statistics related to DHCPv6 packets processing
+ /// to their initial values.
+ ///
+ /// All of the statistics observed by the DHCPv6 server and with the names
+ /// like "pkt6-" are reset to 0. This function must be invoked in the class
+ /// constructor.
+ void setPacketStatisticsDefaults();
+
/// @brief Compare received server id with our server id
///
/// Checks if the server id carried in a query from a client matches
sendUnixCommand("{ \"command\" : \"statistic-get-all\", "
" \"arguments\": {}}", response);
- // preparing the schema which check if all statistics are set to zero
- std::string stats_get_all = "{ \"arguments\": { "
- "\"pkt6-advertise-received\": [ [ 0, \"" + isc::util::ptimeToText(StatsMgr::instance().getObservation("pkt6-advertise-received")
- ->getInteger().second) + "\" ] ], "
- "\"pkt6-advertise-sent\": [ [ 0, \"" + isc::util::ptimeToText(StatsMgr::instance().getObservation("pkt6-advertise-sent")
- ->getInteger().second) + "\" ] ], "
- "\"pkt6-decline-received\": [ [ 0, \"" + isc::util::ptimeToText(StatsMgr::instance().getObservation("pkt6-decline-received")
- ->getInteger().second) + "\" ] ], "
- "\"pkt6-dhcpv4-query-received\": [ [ 0, \"" + isc::util::ptimeToText(StatsMgr::instance().getObservation("pkt6-dhcpv4-query-received")
- ->getInteger().second) + "\" ] ], "
- "\"pkt6-dhcpv4-response-received\": [ [ 0, \"" + isc::util::ptimeToText(StatsMgr::instance().getObservation("pkt6-dhcpv4-response-received")
- ->getInteger().second) + "\" ] ], "
- "\"pkt6-dhcpv4-response-sent\": [ [ 0, \"" + isc::util::ptimeToText(StatsMgr::instance().getObservation("pkt6-dhcpv4-response-sent")
- ->getInteger().second) + "\" ] ], "
- "\"pkt6-infrequest-received\": [ [ 0, \"" + isc::util::ptimeToText(StatsMgr::instance().getObservation("pkt6-infrequest-received")
- ->getInteger().second) + "\" ] ], "
- "\"pkt6-parse-failed\": [ [ 0, \"" + isc::util::ptimeToText(StatsMgr::instance().getObservation("pkt6-parse-failed")
- ->getInteger().second) + "\" ] ], "
- "\"pkt6-rebind-received\": [ [ 0, \"" + isc::util::ptimeToText(StatsMgr::instance().getObservation("pkt6-rebind-received")
- ->getInteger().second) + "\" ] ], "
- "\"pkt6-receive-drop\": [ [ 0, \"" + isc::util::ptimeToText(StatsMgr::instance().getObservation("pkt6-receive-drop")
- ->getInteger().second) + "\" ] ], "
- "\"pkt6-received\": [ [ 0, \"" + isc::util::ptimeToText(StatsMgr::instance().getObservation("pkt6-received")
- ->getInteger().second) + "\" ] ], "
- "\"pkt6-release-received\": [ [ 0, \"" + isc::util::ptimeToText(StatsMgr::instance().getObservation("pkt6-release-received")
- ->getInteger().second) + "\" ] ], "
- "\"pkt6-renew-received\": [ [ 0, \"" + isc::util::ptimeToText(StatsMgr::instance().getObservation("pkt6-renew-received")
- ->getInteger().second) + "\" ] ], "
- "\"pkt6-reply-received\": [ [ 0, \"" + isc::util::ptimeToText(StatsMgr::instance().getObservation("pkt6-reply-received")
- ->getInteger().second) + "\" ] ], "
- "\"pkt6-reply-sent\": [ [ 0, \"" + isc::util::ptimeToText(StatsMgr::instance().getObservation("pkt6-reply-sent")
- ->getInteger().second) + "\" ] ], "
- "\"pkt6-request-received\": [ [ 0, \"" + isc::util::ptimeToText(StatsMgr::instance().getObservation("pkt6-request-received")
- ->getInteger().second) + "\" ] ], "
- "\"pkt6-sent\": [ [ 0, \"" + isc::util::ptimeToText(StatsMgr::instance().getObservation("pkt6-sent")
- ->getInteger().second) + "\" ] ], "
- "\"pkt6-solicit-received\": [ [ 0, \"" + isc::util::ptimeToText(StatsMgr::instance().getObservation("pkt6-solicit-received")
- ->getInteger().second) + "\" ] ], "
- "\"pkt6-unknown-received\": [ [ 0, \"" + isc::util::ptimeToText(StatsMgr::instance().getObservation("pkt6-unknown-received")
- ->getInteger().second) + "\" ] ] }, "
- "\"result\": 0 }";
+ std::set<std::string> initial_stats = {
+ "pkt6-received",
+ "pkt6-solicit-received",
+ "pkt6-advertise-received",
+ "pkt6-request-received",
+ "pkt6-reply-received",
+ "pkt6-renew-received",
+ "pkt6-rebind-received",
+ "pkt6-decline-received",
+ "pkt6-release-received",
+ "pkt6-infrequest-received",
+ "pkt6-dhcpv4-query-received",
+ "pkt6-dhcpv4-response-received",
+ "pkt6-unknown-received",
+ "pkt6-sent",
+ "pkt6-advertise-sent",
+ "pkt6-reply-sent",
+ "pkt6-dhcpv4-response-sent",
+ "pkt6-parse-failed",
+ "pkt6-receive-drop"
+ };
+
+ std::ostringstream s;
+ s << "{ \"arguments\": { ";
+ for (auto st = initial_stats.begin(); st != initial_stats.end();) {
+ s << "\"" << *st << "\": [ [ 0, \"";
+ s << isc::util::ptimeToText(StatsMgr::instance().getObservation(*st)->getInteger().second);
+ s << "\" ] ]";
+ if (++st != initial_stats.end()) {
+ s << ", ";
+ }
+ }
+ s << " }, \"result\": 0 }";
+
+ auto stats_get_all = s.str();
EXPECT_EQ(stats_get_all, response);
// And pretend it's packet is only 3 bytes long.
pkt->data_.resize(3);
- // Check that those statistics are set before the test.
- // All should be present because we initialize
- // all of them in server constructor. This piece of code is mainly reffered
- // to previous situation when Kea used lazy initialization of statistics.
+ // Check that the tested statistics is initially set to 0
ObservationPtr pkt6_rcvd = mgr.getObservation("pkt6-received");
ObservationPtr parse_fail = mgr.getObservation("pkt6-parse-failed");
ObservationPtr recv_drop = mgr.getObservation("pkt6-receive-drop");
// And pretend it's packet of a different type
pkt->data_[0] = pkt_type;
- // Check that those statistics are set before the test.
- // All should be present because we initialize
- // all of them in server constructor. This piece of code is mainly reffered
- // to previous situation when Kea used lazy initialization of statistics.
+ // Check that the tested statistics is initially set to 0
ObservationPtr pkt6_rcvd = mgr.getObservation("pkt6-received");
ObservationPtr tested_stat = mgr.getObservation(stat_name);
EXPECT_TRUE(pkt6_rcvd);
getCfgSubnets6()->getAll();
ASSERT_EQ(1, subnets->size());
- // Ok, let's check the statistics. All should be present because we initialize
- // all of them in server constructor. This piece of code is mainly reffered
- // to previous situation when Kea used lazy initialization of statistics.
+ // Check that the tested statistics is initially set to 0
using namespace isc::stats;
StatsMgr& mgr = StatsMgr::instance();
ObservationPtr pkt6_rcvd = mgr.getObservation("pkt6-received");
getCfgSubnets6()->getAll();
ASSERT_EQ(2, subnets->size());
- // Ok, let's check the statistics. All should be present because we initialize
- // all of them in server constructor. This piece of code is mainly reffered
- // to previous situation when Kea used lazy initialization of statistics.
+ // Check that the tested statistics is initially set to 0
using namespace isc::stats;
StatsMgr& mgr = StatsMgr::instance();
ObservationPtr pkt6_rcvd = mgr.getObservation("pkt6-received");