- status-get
- version-get
+Starting with Kea version 2.0.0 the D2 server supports too the following
+operational commands for statistics:
+
+- statistic-get
+- statistic-get-all
+- statistic-reset
+- statistic-reset-all
+
The ``shutdown`` command supports the extra ``type`` argument which controls the
way the D2 server cleans up on exit.
The supported shutdown types are:
}
}
+DHCP-DDNS Server Statistics
+===========================
+
+Kea version 2.0.0 introduced statistics support for the DHCP-DDNS.
+
+Statistics are divided in three groups: Name Change Request, DNS update
+and per TSIG key DNS updates. If the statistics of the first two groups
+are cummulative, i.e. not affected by configuration change or reload,
+per key statistics are reset to 0 when the underlying object is
+(re)created.
+
+Currently the statistics management is limited:
+
+- only integer samples (i.e. a counter and a timestamp) are used
+- the maximum sample count is 1
+- there is no API to remove one or all statistics
+- there is no API to set the maxium sample count or age
+
+.. note::
+
+ Hook libraries like the GSS-TSIG add new statistics.
+
+A reference about Kea statistics can be found at :ref:`stats`.
+
+NCR Statistics
+--------------
+
+The Name Change Request statistics are:
+
+- ``ncr-received`` - received valid NCRs
+- ``ncr-invalid`` - received invalid NCRs
+- ``ncr-error`` - errors in NCR receptions other than I/) cancel on shutdown
+
+DNS Update Statistics
+---------------------
+
+The global DNS update statistics are:
+
+- ``update-sent`` - sent DNS updates
+- ``update-signed`` - sent DNS updates protected by TSIG
+- ``update-unsigned`` - sent DNS updates not protected by TSIG
+- ``update-success`` - DNS updates which completed with a success
+- ``update-timeout`` - DNS updates which completed on timeout
+- ``update-error`` - DNS updates which completed with an error other than
+ timeout
+
+Per TSIG key DNS Update Statistics
+----------------------------------
+
+The per TSIG key DNS update statistics are:
+
+- ``update-sent`` - sent DNS updates
+- ``update-success`` - DNS updates which completed with a success
+- ``update-timeout`` - DNS updates which completed on timeout
+- ``update-error`` - DNS updates which completed with an error other than
+ timeout
+
+The name of a per key statistics is ``key[<key-DNS-name>].<stat-name>``,
+for instance he name of the ``update-sent`` statistics for the
+``key.example.com.`` TSIG key is ``key[key.example.com.].update-sent``.
+
DHCP-DDNS Server Limitations
============================
#include <d2/d2_process.h>
#include <d2srv/d2_cfg_mgr.h>
#include <d2srv/d2_log.h>
+#include <d2srv/d2_stats.h>
#include <d2srv/d2_tsig_key.h>
#include <hooks/hooks.h>
#include <hooks/hooks_manager.h>
D2CfgMgrPtr tmp = getD2CfgMgr();
update_mgr_.reset(new D2UpdateMgr(queue_mgr_, tmp, getIoService()));
- // Instantiate stats manager.
+ // Instantiate stats manager.
+ // Initialize statistics.
isc::stats::StatsMgr& stats_mgr = isc::stats::StatsMgr::instance();
stats_mgr.setMaxSampleCountDefault(0);
- for (const auto& name : D2TsigKey::globalStats) {
- stats_mgr.setValue("global." + name, static_cast<int64_t>(0));
+ for (const auto& name : D2Stats::ncr) {
+ stats_mgr.setValue(name, static_cast<int64_t>(0));
+ }
+ for (const auto& name : D2Stats::update) {
+ stats_mgr.setValue(name, static_cast<int64_t>(0));
}
};
/// implementation.
static const size_t MAX_TRANSACTIONS_DEFAULT = 32;
- // @todo This structure is not yet used. It is here in anticipation of
- // enabled statistics capture.
- struct Stats {
- uint64_t start_time_;
- uint64_t stop_time_;
- uint64_t update_count_;
- uint64_t min_update_time_;
- uint64_t max_update_time_;
- uint64_t server_rejects_;
- uint64_t server_timeouts_;
- };
-
/// @brief Constructor
///
/// @param queue_mgr reference to the queue manager receiving requests
try {
response_->fromWire(in_buf_->getData(), in_buf_->getLength(),
tsig_context_.get());
- incrStats("success");
+ incrStats("update-success");
} catch (const isc::Exception& ex) {
status = DNSClient::INVALID_RESPONSE;
LOG_DEBUG(d2_to_dns_logger, isc::log::DBGLVL_TRACE_DETAIL,
DHCP_DDNS_INVALID_RESPONSE).arg(ex.what());
- incrStats("error");
+ incrStats("update-error");
}
if (tsig_context_) {
tsig_context_.reset();
}
} else if (status == DNSClient::TIMEOUT) {
- incrStats("timeout");
+ incrStats("update-timeout");
} else {
- incrStats("error");
+ incrStats("update-error");
}
// Once we are done with internal business, let's call a callback supplied
io_service.post(io_fetch);
// Update sent statistics.
- incrStats("sent");
+ incrStats("update-sent");
if (tsig_key) {
- incrStats("signed", false);
+ incrStats("update-signed", false);
} else {
- incrStats("unsigned", false);
+ incrStats("update-unsigned", false);
}
}
void
DNSClientImpl::incrStats(const std::string& stat, bool update_key) {
StatsMgr& mgr = StatsMgr::instance();
- mgr.addValue("global." + stat, static_cast<int64_t>(1));
+ mgr.addValue(stat, static_cast<int64_t>(1));
if (update_key && !tsig_key_name_.empty()) {
mgr.addValue(StatsMgr::generateName("key", tsig_key_name_, stat),
static_cast<int64_t>(1));
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_stats.cc d2_stats.h
libkea_d2srv_la_SOURCES += d2_tsig_key.cc d2_tsig_key.h
EXTRA_DIST += d2_messages.mes
--- /dev/null
+// 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_stats.h>
+
+using namespace std;
+
+namespace isc {
+namespace d2 {
+
+set<string>
+D2Stats::ncr = {
+ "ncr-received",
+ "ncr-invalid",
+ "ncr-error"
+};
+
+set<string>
+D2Stats::update = {
+ "update-sent",
+ "update-signed",
+ "update-unsigned",
+ "update-success",
+ "update-timeout",
+ "update-error"
+};
+
+set<string>
+D2Stats::key = {
+ "update-sent",
+ "update-success",
+ "update-timeout",
+ "update-error"
+};
+
+} // namespace d2
+} // namespace isc
--- /dev/null
+// 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_STATS_H
+#define D2_STATS_H
+
+#include <set>
+#include <string>
+
+namespace isc {
+namespace d2 {
+
+/// @brief Statistics Names.
+class D2Stats {
+public:
+ /// @brief Global NCR statistics names.
+ ///
+ /// - ncr-received
+ /// - ncr-invalid
+ /// - ncr-error
+ static std::set<std::string> ncr;
+
+ /// @brief Global DNS update statistics names.
+ ///
+ /// - update-sent
+ /// - update-signed
+ /// - update-unsigned
+ /// - update-success
+ /// - update-timeout
+ /// - update-error
+ static std::set<std::string> update;
+
+ /// @brief Key DNS update statistics names.
+ ///
+ /// - update-sent
+ /// - update-success
+ /// - update-timeout
+ /// - update-error
+ static std::set<std::string> key;
+};
+
+} // namespace d2
+} // namespace isc
+
+#endif // D2_STATS_H
#include <config.h>
+#include <d2srv/d2_stats.h>
#include <d2srv/d2_tsig_key.h>
#include <stats/stats_mgr.h>
namespace isc {
namespace d2 {
-set<string>
-D2TsigKey::keyStats = {
- "sent",
- "success",
- "timeout",
- "error"
-};
-
-set<string>
-D2TsigKey::globalStats = {
- "sent",
- "signed",
- "unsigned",
- "success",
- "timeout",
- "error"
-};
-
D2TsigKey::D2TsigKey(const std::string& key_spec) : TSIGKey(key_spec) {
initStats();
}
D2TsigKey::initStats() {
StatsMgr& stats_mgr = StatsMgr::instance();
const string& kname = getKeyName().toText();
- for (const auto& name : keyStats) {
+ for (const auto& name : D2Stats::key) {
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) {
+ for (const auto& name : D2Stats::key) {
string sname = StatsMgr::generateName("key", kname, name);
stats_mgr.del(sname);
}
D2TsigKey::resetStats() {
StatsMgr& stats_mgr = StatsMgr::instance();
const string& kname = getKeyName().toText();
- for (const auto& name : keyStats) {
+ for (const auto& name : D2Stats::key) {
string sname = StatsMgr::generateName("key", kname, name);
stats_mgr.reset(sname);
}
#include <dns/tsigkey.h>
#include <boost/shared_ptr.hpp>
-#include <set>
-
namespace isc {
namespace d2 {
///
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;
-
private:
/// @brief Initialize key statistics.
void initStats();
#include <config.h>
#include <cc/data.h>
+#include <d2srv/d2_stats.h>
#include <d2srv/d2_tsig_key.h>
#include <stats/stats_mgr.h>
namespace {
+/// @brief Check statistics names.
+TEST(D2StatsTest, names) {
+ ASSERT_EQ(3, D2Stats::ncr.size());
+ ASSERT_EQ(6, D2Stats::update.size());
+ ASSERT_EQ(4, D2Stats::key.size());
+}
+
/// @brief Fixture class for TSIG key / DNS update statictics.
class D2TsigKeyTest : public ::testing::Test {
public:
/// @brief Check TSIG key life.
TEST_F(D2TsigKeyTest, key) {
- // Statistics names.
- ASSERT_EQ(4, D2TsigKey::keyStats.size());
- ASSERT_EQ(6, D2TsigKey::globalStats.size());
-
// Get the statistics manager.
StatsMgr& stat_mgr = StatsMgr::instance();
ASSERT_EQ(0, stat_mgr.count());
EXPECT_EQ(4, stat_mgr.count());
// Get the 'sent' statistics.
- const string& stat_name = "key[foo.bar.].sent";
+ const string& stat_name = "key[foo.bar.].update-sent";
EXPECT_EQ(1, stat_mgr.getSize(stat_name));
ObservationPtr stat = stat_mgr.getObservation(stat_name);
ASSERT_TRUE(stat);
libkea_dhcp_ddns_la_LDFLAGS += -no-undefined -version-info 16:0:0
libkea_dhcp_ddns_la_LIBADD =
+libkea_dhcp_ddns_la_LIBADD += $(top_builddir)/src/lib/stats/libkea-stats.la
libkea_dhcp_ddns_la_LIBADD += $(top_builddir)/src/lib/dhcp/libkea-dhcp++.la
libkea_dhcp_ddns_la_LIBADD += $(top_builddir)/src/lib/asiolink/libkea-asiolink.la
libkea_dhcp_ddns_la_LIBADD += $(top_builddir)/src/lib/cc/libkea-cc.la
#include <dhcp_ddns/dhcp_ddns_log.h>
#include <dhcp_ddns/ncr_udp.h>
+#include <stats/stats_mgr.h>
#include <functional>
try {
ncr = NameChangeRequest::fromFormat(format_, input_buffer);
+ isc::stats::StatsMgr::instance().addValue("ncr-received",
+ static_cast<int64_t>(0));
} catch (const NcrMessageError& ex) {
// log it and go back to listening
LOG_ERROR(dhcp_ddns_logger, DHCP_DDNS_INVALID_NCR).arg(ex.what());
+ isc::stats::StatsMgr::instance().addValue("ncr-invalid",
+ static_cast<int64_t>(0));
// Queue up the next receive.
// NOTE: We must call the base class, NEVER doReceive
} else {
LOG_ERROR(dhcp_ddns_logger, DHCP_DDNS_NCR_UDP_RECV_ERROR)
.arg(error_code.message());
+ isc::stats::StatsMgr::instance().addValue("ncr-error",
+ static_cast<int64_t>(0));
result = ERROR;
}
}
}
}
-}; // end of isc::dhcp_ddns namespace
-}; // end of isc namespace
+} // end of isc::dhcp_ddns namespace
+} // end of isc namespace
libdhcp_ddns_unittests_LDFLAGS = $(AM_LDFLAGS) $(CRYPTO_LDFLAGS) $(GTEST_LDFLAGS)
libdhcp_ddns_unittests_LDADD = $(top_builddir)/src/lib/dhcp_ddns/libkea-dhcp_ddns.la
+libdhcp_ddns_unittests_LDADD += $(top_builddir)/src/lib/stats/libkea-stats.la
libdhcp_ddns_unittests_LDADD += $(top_builddir)/src/lib/dhcp/libkea-dhcp++.la
libdhcp_ddns_unittests_LDADD += $(top_builddir)/src/lib/asiolink/libkea-asiolink.la
libdhcp_ddns_unittests_LDADD += $(top_builddir)/src/lib/cc/libkea-cc.la