From: Franciszek Gorski Date: Thu, 5 Sep 2019 15:24:45 +0000 (+0200) Subject: [755-Kea-DHCP-servers-observations-should-be-reset] resolve threads X-Git-Tag: Kea-1.7.0~27 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=3e5d57870f73434cfd4f1a62024d1a0779345789;p=thirdparty%2Fkea.git [755-Kea-DHCP-servers-observations-should-be-reset] resolve threads --- diff --git a/doc/sphinx/arm/stats.rst b/doc/sphinx/arm/stats.rst index 23404cdc70..76c66f34a8 100644 --- a/doc/sphinx/arm/stats.rst +++ b/doc/sphinx/arm/stats.rst @@ -52,20 +52,21 @@ for a list of statistics-oriented commands. 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 @@ -86,7 +87,8 @@ Commands for Manipulating Statistics 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), diff --git a/src/bin/dhcp4/dhcp4_srv.cc b/src/bin/dhcp4/dhcp4_srv.cc index dc8a37f568..aa8ae547cc 100644 --- a/src/bin/dhcp4/dhcp4_srv.cc +++ b/src/bin/dhcp4/dhcp4_srv.cc @@ -69,6 +69,7 @@ #include #include +#include using namespace isc; using namespace isc::asiolink; @@ -107,25 +108,28 @@ struct Dhcp4Hooks { hook_index_host4_identifier_ = HooksManager::registerHook("host4_identifier"); } }; - /// Set of all statistics observed in DHCPv4 server - std::set 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 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 @@ -153,7 +157,6 @@ Dhcpv4Exchange::Dhcpv4Exchange(const AllocEnginePtr& alloc_engine, 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. @@ -505,11 +508,10 @@ Dhcpv4Srv::Dhcpv4Srv(uint16_t server_port, uint16_t client_port, } void Dhcpv4Srv::setPacketStatisticsDefaults() { - std::set::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(0)); } diff --git a/src/bin/dhcp4/dhcp4_srv.h b/src/bin/dhcp4/dhcp4_srv.h index a28fc6e1e6..490387a924 100644 --- a/src/bin/dhcp4/dhcp4_srv.h +++ b/src/bin/dhcp4/dhcp4_srv.h @@ -234,9 +234,6 @@ public: /// @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, @@ -655,6 +652,14 @@ protected: /// 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 diff --git a/src/bin/dhcp4/tests/ctrl_dhcp4_srv_unittest.cc b/src/bin/dhcp4/tests/ctrl_dhcp4_srv_unittest.cc index e6598b20ad..7aa0f28a3f 100644 --- a/src/bin/dhcp4/tests/ctrl_dhcp4_srv_unittest.cc +++ b/src/bin/dhcp4/tests/ctrl_dhcp4_srv_unittest.cc @@ -552,41 +552,39 @@ TEST_F(CtrlChannelDhcpv4SrvTest, controlChannelStats) { sendUnixCommand("{ \"command\" : \"statistic-get-all\", " " \"arguments\": {}}", response); + std::set 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); diff --git a/src/bin/dhcp6/dhcp6_srv.cc b/src/bin/dhcp6/dhcp6_srv.cc index 3da15808e7..453f65d7e2 100644 --- a/src/bin/dhcp6/dhcp6_srv.cc +++ b/src/bin/dhcp6/dhcp6_srv.cc @@ -78,6 +78,7 @@ #include #include #include +#include using namespace isc; using namespace isc::asiolink; @@ -172,28 +173,30 @@ createStatusCode(const Pkt6& pkt, const Option6IA& ia, const uint16_t status_cod return (option_status); } - /// Set of all statistics observed in DHCPv6 server - std::set 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 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 { @@ -246,11 +249,10 @@ Dhcpv6Srv::Dhcpv6Srv(uint16_t server_port, uint16_t client_port) } void Dhcpv6Srv::setPacketStatisticsDefaults() { - std::set::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(0)); } diff --git a/src/bin/dhcp6/dhcp6_srv.h b/src/bin/dhcp6/dhcp6_srv.h index 3e44bd0113..8f9f45b209 100644 --- a/src/bin/dhcp6/dhcp6_srv.h +++ b/src/bin/dhcp6/dhcp6_srv.h @@ -89,9 +89,6 @@ public: /// @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, @@ -204,6 +201,14 @@ public: 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 diff --git a/src/bin/dhcp6/tests/ctrl_dhcp6_srv_unittest.cc b/src/bin/dhcp6/tests/ctrl_dhcp6_srv_unittest.cc index 9fff87a2bc..d72888dcf3 100644 --- a/src/bin/dhcp6/tests/ctrl_dhcp6_srv_unittest.cc +++ b/src/bin/dhcp6/tests/ctrl_dhcp6_srv_unittest.cc @@ -1134,47 +1134,41 @@ TEST_F(CtrlChannelDhcpv6SrvTest, controlChannelStats) { 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 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); diff --git a/src/bin/dhcp6/tests/dhcp6_srv_unittest.cc b/src/bin/dhcp6/tests/dhcp6_srv_unittest.cc index 764d42b5d3..60c9df3233 100644 --- a/src/bin/dhcp6/tests/dhcp6_srv_unittest.cc +++ b/src/bin/dhcp6/tests/dhcp6_srv_unittest.cc @@ -2589,10 +2589,7 @@ TEST_F(Dhcpv6SrvTest, receiveParseFailedStat) { // 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"); diff --git a/src/bin/dhcp6/tests/dhcp6_test_utils.cc b/src/bin/dhcp6/tests/dhcp6_test_utils.cc index 106a7d366e..7210a288b1 100644 --- a/src/bin/dhcp6/tests/dhcp6_test_utils.cc +++ b/src/bin/dhcp6/tests/dhcp6_test_utils.cc @@ -770,10 +770,7 @@ Dhcpv6SrvTest::testReceiveStats(uint8_t pkt_type, const std::string& stat_name) // 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); diff --git a/src/bin/dhcp6/tests/infrequest_unittest.cc b/src/bin/dhcp6/tests/infrequest_unittest.cc index 42ab8da99a..4a3334611e 100644 --- a/src/bin/dhcp6/tests/infrequest_unittest.cc +++ b/src/bin/dhcp6/tests/infrequest_unittest.cc @@ -316,9 +316,7 @@ TEST_F(InfRequestTest, infRequestStats) { 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"); diff --git a/src/bin/dhcp6/tests/sarr_unittest.cc b/src/bin/dhcp6/tests/sarr_unittest.cc index a0dfab6f15..98a0c0ec3d 100644 --- a/src/bin/dhcp6/tests/sarr_unittest.cc +++ b/src/bin/dhcp6/tests/sarr_unittest.cc @@ -492,9 +492,7 @@ TEST_F(SARRTest, sarrStats) { 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");