From: Francis Dupont Date: Wed, 18 Aug 2021 18:15:18 +0000 (+0200) Subject: [#2040] Checkpoint: began D2 stats X-Git-Tag: Kea-2.0.0~157 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=d2015a065a7fc46403464f1051d02476b6299156;p=thirdparty%2Fkea.git [#2040] Checkpoint: began D2 stats --- diff --git a/src/bin/d2/d2_controller.cc b/src/bin/d2/d2_controller.cc index dc31b552b7..60f24eb473 100644 --- a/src/bin/d2/d2_controller.cc +++ b/src/bin/d2/d2_controller.cc @@ -11,11 +11,13 @@ #include #include #include +#include #include using namespace isc::config; using namespace isc::process; +using namespace isc::stats; namespace ph = std::placeholders; namespace isc { @@ -80,6 +82,19 @@ D2Controller::registerCommands() { CommandMgr::instance().registerCommand(VERSION_GET_COMMAND, std::bind(&D2Controller::versionGetHandler, this, ph::_1, ph::_2)); + + // Register statistic related commands. + CommandMgr::instance().registerCommand("statistic-get", + std::bind(&StatsMgr::statisticGetHandler, ph::_1, ph::_2)); + + CommandMgr::instance().registerCommand("statistic-get-all", + std::bind(&StatsMgr::statisticGetAllHandler, ph::_1, ph::_2)); + + CommandMgr::instance().registerCommand("statistic-reset", + std::bind(&StatsMgr::statisticResetHandler, ph::_1, ph::_2)); + + CommandMgr::instance().registerCommand("statistic-reset-all", + std::bind(&StatsMgr::statisticResetAllHandler, ph::_1, ph::_2)); } void @@ -96,6 +111,10 @@ D2Controller::deregisterCommands() { CommandMgr::instance().deregisterCommand(CONFIG_TEST_COMMAND); CommandMgr::instance().deregisterCommand(CONFIG_WRITE_COMMAND); CommandMgr::instance().deregisterCommand(SHUT_DOWN_COMMAND); + CommandMgr::instance().deregisterCommand("statistic-get"); + CommandMgr::instance().deregisterCommand("statistic-get-all"); + CommandMgr::instance().deregisterCommand("statistic-reset"); + CommandMgr::instance().deregisterCommand("statistic-reset-all"); CommandMgr::instance().deregisterCommand(STATUS_GET_COMMAND); CommandMgr::instance().deregisterCommand(VERSION_GET_COMMAND); @@ -104,8 +123,6 @@ D2Controller::deregisterCommands() { } } - - isc::data::ConstElementPtr D2Controller::parseFile(const std::string& file_name) { isc::data::ConstElementPtr elements; @@ -135,5 +152,5 @@ D2Controller::getVersionAddendum() { } -}; // end namespace isc::d2 -}; // end namespace isc +} // end namespace isc::d2 +} // end namespace isc diff --git a/src/bin/d2/d2_process.cc b/src/bin/d2/d2_process.cc index 973e98e248..a741a978c7 100644 --- a/src/bin/d2/d2_process.cc +++ b/src/bin/d2/d2_process.cc @@ -14,6 +14,7 @@ #include #include #include +#include using namespace isc::hooks; using namespace isc::process; @@ -62,6 +63,10 @@ D2Process::D2Process(const char* name, const asiolink::IOServicePtr& io_service) // Pass in IOService for DNS update transaction IO event processing. D2CfgMgrPtr tmp = getD2CfgMgr(); update_mgr_.reset(new D2UpdateMgr(queue_mgr_, tmp, getIoService())); + + // Instantiate stats manager. + isc::stats::StatsMgr& stats_mgr = isc::stats::StatsMgr::instance(); + stats_mgr.setMaxSampleCountDefault(0); }; void diff --git a/src/bin/d2/tests/d2_command_unittest.cc b/src/bin/d2/tests/d2_command_unittest.cc index 5192e7831b..8f956e79ab 100644 --- a/src/bin/d2/tests/d2_command_unittest.cc +++ b/src/bin/d2/tests/d2_command_unittest.cc @@ -540,6 +540,10 @@ TEST_F(CtrlChannelD2Test, commandsRegistration) { EXPECT_TRUE(command_list.find("\"config-write\"") != string::npos); EXPECT_TRUE(command_list.find("\"shutdown\"") != string::npos); EXPECT_TRUE(command_list.find("\"status-get\"") != string::npos); + EXPECT_TRUE(command_list.find("\"statistic-get\"") != string::npos); + EXPECT_TRUE(command_list.find("\"statistic-get-all\"") != string::npos); + EXPECT_TRUE(command_list.find("\"statistic-reset\"") != string::npos); + EXPECT_TRUE(command_list.find("\"statistic-reset-all\"") != string::npos); EXPECT_TRUE(command_list.find("\"version-get\"") != string::npos); // Ok, and now delete the server. It should deregister its commands. @@ -628,6 +632,11 @@ TEST_F(CtrlChannelD2Test, listCommands) { checkListCommands(rsp, "config-test"); checkListCommands(rsp, "config-write"); checkListCommands(rsp, "list-commands"); + checkListCommands(rsp, "statistic-get"); + checkListCommands(rsp, "statistic-get-all"); + checkListCommands(rsp, "statistic-reset"); + checkListCommands(rsp, "statistic-reset-all"); + checkListCommands(rsp, "status-get"); checkListCommands(rsp, "shutdown"); checkListCommands(rsp, "version-get"); } diff --git a/src/lib/d2srv/Makefile.am b/src/lib/d2srv/Makefile.am index 78de1a20a2..af8a226565 100644 --- a/src/lib/d2srv/Makefile.am +++ b/src/lib/d2srv/Makefile.am @@ -16,6 +16,7 @@ libkea_d2srv_la_SOURCES += d2_config.cc d2_config.h libkea_d2srv_la_SOURCES += d2_log.cc d2_log.h libkea_d2srv_la_SOURCES += d2_messages.cc d2_messages.h libkea_d2srv_la_SOURCES += d2_simple_parser.cc d2_simple_parser.h +libkea_d2srv_la_SOURCES += d2_tsig_key.cc d2_tsig_key.h EXTRA_DIST += d2_messages.mes libkea_d2srv_la_CXXFLAGS = $(AM_CXXFLAGS) @@ -25,6 +26,7 @@ libkea_d2srv_la_LIBADD = libkea_d2srv_la_LIBADD += $(top_builddir)/src/lib/process/libkea-process.la libkea_d2srv_la_LIBADD += $(top_builddir)/src/lib/cfgrpt/libcfgrpt.la libkea_d2srv_la_LIBADD += $(top_builddir)/src/lib/dhcp_ddns/libkea-dhcp_ddns.la +libkea_d2srv_la_LIBADD += $(top_builddir)/src/lib/stats/libkea-stats.la libkea_d2srv_la_LIBADD += $(top_builddir)/src/lib/config/libkea-cfgclient.la libkea_d2srv_la_LIBADD += $(top_builddir)/src/lib/http/libkea-http.la libkea_d2srv_la_LIBADD += $(top_builddir)/src/lib/dhcp/libkea-dhcp++.la diff --git a/src/lib/d2srv/d2_tsig_key.cc b/src/lib/d2srv/d2_tsig_key.cc new file mode 100644 index 0000000000..229f7c06b0 --- /dev/null +++ b/src/lib/d2srv/d2_tsig_key.cc @@ -0,0 +1,70 @@ +// Copyright (C) 2021 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/. + +/// Defines the logger used by the top-level component of kea-dhcp-ddns. + +#include + +#include +#include + +using namespace isc::dns; +using namespace isc::stats; +using namespace std; + +namespace isc { +namespace d2 { + +set +D2TsigKey::keyStats = { + "sent", + "signed", +// "unsigned", + "success", + "timeout", + "error" +}; + +set +D2TsigKey::globalStats = { + "sent", + "signed", + "unsigned", + "success", + "timeout", + "error" +}; + +D2TsigKey::D2TsigKey(const std::string& key_name) : TSIGKey(key_name) { + StatsMgr& stats_mgr = StatsMgr::instance(); + const string& kname = getKeyName().toText(); + for (const auto& name : keyStats) { + const string& sname = StatsMgr::generateName("key", kname, name); + stats_mgr.setValue(sname, static_cast(0)); + } +} + +D2TsigKey::~D2TsigKey() { + StatsMgr& stats_mgr = StatsMgr::instance(); + const string& kname = getKeyName().toText(); + for (const auto& name : keyStats) { + string sname = StatsMgr::generateName("key", kname, name); + stats_mgr.del(sname); + } +} + +void +D2TsigKey::resetStats() { + StatsMgr& stats_mgr = StatsMgr::instance(); + const string& kname = getKeyName().toText(); + for (const auto& name : keyStats) { + string sname = StatsMgr::generateName("key", kname, name); + stats_mgr.reset(sname); + } +} + +} // namespace d2 +} // namespace isc diff --git a/src/lib/d2srv/d2_tsig_key.h b/src/lib/d2srv/d2_tsig_key.h new file mode 100644 index 0000000000..615996ab91 --- /dev/null +++ b/src/lib/d2srv/d2_tsig_key.h @@ -0,0 +1,58 @@ +// Copyright (C) 2021 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/. + +#ifndef D2_TSIG_KEY_H +#define D2_TSIG_KEY_H + +#include +#include +#include + +#include + +namespace isc { +namespace d2 { + +/// @brief Statistics keeping extension of the DNS TSIGKey class. +/// +/// Implements a TSIGKey derived class which can be used as the value +/// of TSIGKeyPtr so with minimal or no update to the DNS++ library. +class D2TsigKey : public dns::TSIGKey { +public: + /// @brief Constructor. + /// + /// Initialize the key statistics. + /// + /// @param key_name Domain name of the key. + D2TsigKey(const std::string& key_name); + + /// @brief Destructor. + /// + /// Remove the key statistics. + virtual ~D2TsigKey(); + + /// @brief Reset statistics. + /// + virtual void resetStats(); + + /// @brief Statistics names (key). + /// + /// The list of statistic names for keys. + static std::set keyStats; + + /// @brief Statistics names (global). + /// + /// The list of global statistic names. + static std::set globalStats; +}; + +/// @brief Type of pointer to a D2 TSIG key. +typedef boost::shared_ptr D2TsigKeyPtr; + +} // namespace d2 +} // namespace isc + +#endif // D2_TSIG_KEY_H diff --git a/src/lib/d2srv/tests/Makefile.am b/src/lib/d2srv/tests/Makefile.am index fb7c76003d..caede036f9 100644 --- a/src/lib/d2srv/tests/Makefile.am +++ b/src/lib/d2srv/tests/Makefile.am @@ -19,7 +19,7 @@ if HAVE_GTEST TESTS += libd2srv_unittests libd2srv_unittests_SOURCES = run_unittests.cc -# Currently no unit test file was moved even partially. +libd2srv_unittests_SOURCES += d2_tsig_key_unittest.cc libd2srv_unittests_CPPFLAGS = $(AM_CPPFLAGS) $(GTEST_INCLUDES) libd2srv_unittests_LDFLAGS = $(AM_LDFLAGS) $(GTEST_LDFLAGS) @@ -27,6 +27,7 @@ libd2srv_unittests_LDFLAGS = $(AM_LDFLAGS) $(GTEST_LDFLAGS) libd2srv_unittests_LDADD = $(top_builddir)/src/lib/d2srv/libkea-d2srv.la libd2srv_unittests_LDADD += $(top_builddir)/src/lib/process/libkea-process.la libd2srv_unittests_LDADD += $(top_builddir)/src/lib/dhcp_ddns/libkea-dhcp_ddns.la +libd2srv_unittests_LDADD += $(top_builddir)/src/lib/stats/libkea-stats.la libd2srv_unittests_LDADD += $(top_builddir)/src/lib/config/libkea-cfgclient.la libd2srv_unittests_LDADD += $(top_builddir)/src/lib/http/libkea-http.la libd2srv_unittests_LDADD += $(top_builddir)/src/lib/dhcp/libkea-dhcp++.la diff --git a/src/lib/d2srv/tests/d2_tsig_key_unittest.cc b/src/lib/d2srv/tests/d2_tsig_key_unittest.cc new file mode 100644 index 0000000000..c73ed1bb12 --- /dev/null +++ b/src/lib/d2srv/tests/d2_tsig_key_unittest.cc @@ -0,0 +1,87 @@ +// Copyright (C) 2021 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/. + +#include + +#include +#include +#include + +#include + +#include +#include + +using namespace isc::d2; +using namespace isc::data; +using namespace isc::stats; +using namespace std; + +namespace { + +/// @brief Fixture class for TSIG key / DNS update statictics. +class D2TsigKeyTest : public ::testing::Test { +public: + /// @brief Constructor. + D2TsigKeyTest() { + StatsMgr::instance(); + StatsMgr::instance().removeAll(); + StatsMgr::instance().setMaxSampleCountDefault(0); + } + + /// @brief Destructor. + ~D2TsigKeyTest() { + StatsMgr::instance().removeAll(); + StatsMgr::instance().setMaxSampleCountDefault(0); + } +}; + +/// @brief Check TSIG key life. +TEST_F(D2TsigKeyTest, key) { + // Statistics names. + ASSERT_EQ(5, D2TsigKey::keyStats.size()); + ASSERT_EQ(6, D2TsigKey::globalStats.size()); + + // Get the statistics manager. + StatsMgr& stat_mgr = StatsMgr::instance(); + ASSERT_EQ(0, stat_mgr.count()); + + // Create a key. + const string& key_spec = "foo.bar.::test"; + D2TsigKeyPtr key(new D2TsigKey(key_spec)); + EXPECT_EQ(5, stat_mgr.count()); + + // Get the 'sent' statistics. + const string& stat_name = "key[foo.bar.].sent"; + EXPECT_EQ(1, stat_mgr.getSize(stat_name)); + ObservationPtr stat = stat_mgr.getObservation(stat_name); + ASSERT_TRUE(stat); + IntegerSample sample; + ASSERT_NO_THROW(sample = stat->getInteger()); + EXPECT_EQ(0, sample.first); + + // Increment the 'sent' statistics. + stat_mgr.addValue(stat_name, static_cast(1)); + stat = stat_mgr.getObservation(stat_name); + ASSERT_TRUE(stat); + ASSERT_NO_THROW(sample = stat->getInteger()); + EXPECT_EQ(1, sample.first); + + // Reset the key statistics. + ASSERT_NO_THROW(key->resetStats()); + stat = stat_mgr.getObservation(stat_name); + ASSERT_TRUE(stat); + ASSERT_NO_THROW(sample = stat->getInteger()); + EXPECT_EQ(0, sample.first); + + // Destroy the key: its stats are removed. + key.reset(); + EXPECT_EQ(0, stat_mgr.count()); + stat = stat_mgr.getObservation(stat_name); + EXPECT_FALSE(stat); +} + +} // end of anonymous namespace