]> git.ipfire.org Git - thirdparty/kea.git/commitdiff
[#2040] Checkpoint: began D2 stats
authorFrancis Dupont <fdupont@isc.org>
Wed, 18 Aug 2021 18:15:18 +0000 (20:15 +0200)
committerRazvan Becheriu <razvan@isc.org>
Fri, 3 Sep 2021 14:10:59 +0000 (17:10 +0300)
src/bin/d2/d2_controller.cc
src/bin/d2/d2_process.cc
src/bin/d2/tests/d2_command_unittest.cc
src/lib/d2srv/Makefile.am
src/lib/d2srv/d2_tsig_key.cc [new file with mode: 0644]
src/lib/d2srv/d2_tsig_key.h [new file with mode: 0644]
src/lib/d2srv/tests/Makefile.am
src/lib/d2srv/tests/d2_tsig_key_unittest.cc [new file with mode: 0644]

index dc31b552b7676d387e5ccc71f8a40afdffde83ae..60f24eb473ffcf47800366f392601c7338f9d904 100644 (file)
 #include <d2/d2_controller.h>
 #include <d2/d2_process.h>
 #include <d2/parser_context.h>
+#include <stats/stats_mgr.h>
 
 #include <stdlib.h>
 
 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
index 973e98e24838107d1af7d6733f19dd6fb919466d..a741a978c7745bcdf49440baa2b1a19380f88777 100644 (file)
@@ -14,6 +14,7 @@
 #include <d2srv/d2_log.h>
 #include <hooks/hooks.h>
 #include <hooks/hooks_manager.h>
+#include <stats/stats_mgr.h>
 
 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
index 5192e7831bbb862d748ec72bf6a7df3dd363b3c3..8f956e79abfeecc641d82425afc9fea275322ecc 100644 (file)
@@ -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");
 }
index 78de1a20a29b73ccafc1d4ae1fdb3dd874d85e27..af8a226565b78440d84de7fbcea980c9131b382b 100644 (file)
@@ -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 (file)
index 0000000..229f7c0
--- /dev/null
@@ -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 <config.h>
+
+#include <d2srv/d2_tsig_key.h>
+#include <stats/stats_mgr.h>
+
+using namespace isc::dns;
+using namespace isc::stats;
+using namespace std;
+
+namespace isc {
+namespace d2 {
+
+set<string>
+D2TsigKey::keyStats = {
+    "sent",
+    "signed",
+//  "unsigned",
+    "success",
+    "timeout",
+    "error"
+};
+
+set<string>
+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<int64_t>(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 (file)
index 0000000..615996a
--- /dev/null
@@ -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 <dns/name.h>
+#include <dns/tsigkey.h>
+#include <boost/shared_ptr.hpp>
+
+#include <set>
+
+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<std::string> keyStats;
+
+    /// @brief Statistics names (global).
+    ///
+    /// The list of global statistic names.
+    static std::set<std::string> globalStats;
+};
+
+/// @brief Type of pointer to a D2 TSIG key.
+typedef boost::shared_ptr<D2TsigKey> D2TsigKeyPtr;
+
+} // namespace d2
+} // namespace isc
+
+#endif // D2_TSIG_KEY_H
index fb7c76003db6b01116ba7fc7ea36d97024ea2838..caede036f9ecb048c501cb163ffcb711b33d15c1 100644 (file)
@@ -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 (file)
index 0000000..c73ed1b
--- /dev/null
@@ -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 <config.h>
+
+#include <cc/data.h>
+#include <d2srv/d2_tsig_key.h>
+#include <stats/stats_mgr.h>
+
+#include <gtest/gtest.h>
+
+#include <iostream>
+#include <sstream>
+
+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<int64_t>(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