diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-05-04 11:36:04 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-05-04 11:36:04 +0000 |
commit | 040eee1aa49b49df4698d83a05af57c220127fd1 (patch) | |
tree | f635435954e6ccde5eee9893889e24f30ca68346 /src/lib/stats/stats_mgr.cc | |
parent | Initial commit. (diff) | |
download | isc-kea-upstream.tar.xz isc-kea-upstream.zip |
Adding upstream version 2.2.0.upstream/2.2.0upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'src/lib/stats/stats_mgr.cc')
-rw-r--r-- | src/lib/stats/stats_mgr.cc | 645 |
1 files changed, 645 insertions, 0 deletions
diff --git a/src/lib/stats/stats_mgr.cc b/src/lib/stats/stats_mgr.cc new file mode 100644 index 0000000..58b36ab --- /dev/null +++ b/src/lib/stats/stats_mgr.cc @@ -0,0 +1,645 @@ +// Copyright (C) 2015-2020 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 <exceptions/exceptions.h> +#include <stats/stats_mgr.h> +#include <cc/data.h> +#include <cc/command_interpreter.h> +#include <util/multi_threading_mgr.h> +#include <boost/make_shared.hpp> +#include <chrono> + +using namespace std; +using namespace std::chrono; +using namespace isc::data; +using namespace isc::config; +using namespace isc::util; + +namespace isc { +namespace stats { + +StatsMgr& +StatsMgr::instance() { + static StatsMgr stats_mgr; + return (stats_mgr); +} + +StatsMgr::StatsMgr() : + global_(boost::make_shared<StatContext>()), mutex_(new mutex) { +} + +void +StatsMgr::setValue(const string& name, const int64_t value) { + if (MultiThreadingMgr::instance().getMode()) { + lock_guard<mutex> lock(*mutex_); + setValueInternal(name, value); + } else { + setValueInternal(name, value); + } +} + +void +StatsMgr::setValue(const string& name, const double value) { + if (MultiThreadingMgr::instance().getMode()) { + lock_guard<mutex> lock(*mutex_); + setValueInternal(name, value); + } else { + setValueInternal(name, value); + } +} + +void +StatsMgr::setValue(const string& name, const StatsDuration& value) { + if (MultiThreadingMgr::instance().getMode()) { + lock_guard<mutex> lock(*mutex_); + setValueInternal(name, value); + } else { + setValueInternal(name, value); + } +} + +void +StatsMgr::setValue(const string& name, const string& value) { + if (MultiThreadingMgr::instance().getMode()) { + lock_guard<mutex> lock(*mutex_); + setValueInternal(name, value); + } else { + setValueInternal(name, value); + } +} + +void +StatsMgr::addValue(const string& name, const int64_t value) { + if (MultiThreadingMgr::instance().getMode()) { + lock_guard<mutex> lock(*mutex_); + addValueInternal(name, value); + } else { + addValueInternal(name, value); + } +} + +void +StatsMgr::addValue(const string& name, const double value) { + if (MultiThreadingMgr::instance().getMode()) { + lock_guard<mutex> lock(*mutex_); + addValueInternal(name, value); + } else { + addValueInternal(name, value); + } +} + +void +StatsMgr::addValue(const string& name, const StatsDuration& value) { + if (MultiThreadingMgr::instance().getMode()) { + lock_guard<mutex> lock(*mutex_); + addValueInternal(name, value); + } else { + addValueInternal(name, value); + } +} + +void +StatsMgr::addValue(const string& name, const string& value) { + if (MultiThreadingMgr::instance().getMode()) { + lock_guard<mutex> lock(*mutex_); + addValueInternal(name, value); + } else { + addValueInternal(name, value); + } +} + +ObservationPtr +StatsMgr::getObservation(const string& name) const { + if (MultiThreadingMgr::instance().getMode()) { + lock_guard<mutex> lock(*mutex_); + return (getObservationInternal(name)); + } else { + return (getObservationInternal(name)); + } +} + +ObservationPtr +StatsMgr::getObservationInternal(const string& name) const { + /// @todo: Implement contexts. + // Currently we keep everything in a global context. + return (global_->get(name)); +} + +void +StatsMgr::addObservation(const ObservationPtr& stat) { + if (MultiThreadingMgr::instance().getMode()) { + lock_guard<mutex> lock(*mutex_); + addObservationInternal(stat); + } else { + addObservationInternal(stat); + } +} + +void +StatsMgr::addObservationInternal(const ObservationPtr& stat) { + /// @todo: Implement contexts. + // Currently we keep everything in a global context. + global_->add(stat); +} + +bool +StatsMgr::deleteObservation(const string& name) { + if (MultiThreadingMgr::instance().getMode()) { + lock_guard<mutex> lock(*mutex_); + return (deleteObservationInternal(name)); + } else { + return (deleteObservationInternal(name)); + } +} + +bool +StatsMgr::deleteObservationInternal(const string& name) { + /// @todo: Implement contexts. + // Currently we keep everything in a global context. + return (global_->del(name)); +} + +bool +StatsMgr::setMaxSampleAge(const string& name, const StatsDuration& duration) { + if (MultiThreadingMgr::instance().getMode()) { + lock_guard<mutex> lock(*mutex_); + return (setMaxSampleAgeInternal(name, duration)); + } else { + return (setMaxSampleAgeInternal(name, duration)); + } +} + +bool +StatsMgr::setMaxSampleAgeInternal(const string& name, + const StatsDuration& duration) { + ObservationPtr obs = getObservationInternal(name); + if (obs) { + obs->setMaxSampleAge(duration); + return (true); + } + return (false); +} + +bool +StatsMgr::setMaxSampleCount(const string& name, uint32_t max_samples) { + if (MultiThreadingMgr::instance().getMode()) { + lock_guard<mutex> lock(*mutex_); + return (setMaxSampleCountInternal(name, max_samples)); + } else { + return (setMaxSampleCountInternal(name, max_samples)); + } +} + +bool +StatsMgr::setMaxSampleCountInternal(const string& name, + uint32_t max_samples) { + ObservationPtr obs = getObservationInternal(name); + if (obs) { + obs->setMaxSampleCount(max_samples); + return (true); + } + return (false); +} + +void +StatsMgr::setMaxSampleAgeAll(const StatsDuration& duration) { + if (MultiThreadingMgr::instance().getMode()) { + lock_guard<mutex> lock(*mutex_); + setMaxSampleAgeAllInternal(duration); + } else { + setMaxSampleAgeAllInternal(duration); + } +} + +void +StatsMgr::setMaxSampleAgeAllInternal(const StatsDuration& duration) { + global_->setMaxSampleAgeAll(duration); +} + +void +StatsMgr::setMaxSampleCountAll(uint32_t max_samples) { + if (MultiThreadingMgr::instance().getMode()) { + lock_guard<mutex> lock(*mutex_); + setMaxSampleCountAllInternal(max_samples); + } else { + setMaxSampleCountAllInternal(max_samples); + } +} + +void +StatsMgr::setMaxSampleCountAllInternal(uint32_t max_samples) { + global_->setMaxSampleCountAll(max_samples); +} + +void +StatsMgr::setMaxSampleAgeDefault(const StatsDuration& duration) { + if (MultiThreadingMgr::instance().getMode()) { + lock_guard<mutex> lock(*mutex_); + setMaxSampleAgeDefaultInternal(duration); + } else { + setMaxSampleAgeDefaultInternal(duration); + } +} + +void +StatsMgr::setMaxSampleAgeDefaultInternal(const StatsDuration& duration) { + Observation::setMaxSampleAgeDefault(duration); +} + +void +StatsMgr::setMaxSampleCountDefault(uint32_t max_samples) { + if (MultiThreadingMgr::instance().getMode()) { + lock_guard<mutex> lock(*mutex_); + setMaxSampleCountDefaultInternal(max_samples); + } else { + setMaxSampleCountDefaultInternal(max_samples); + } +} + +void +StatsMgr::setMaxSampleCountDefaultInternal(uint32_t max_samples) { + Observation::setMaxSampleCountDefault(max_samples); +} + +const StatsDuration& +StatsMgr::getMaxSampleAgeDefault() const { + if (MultiThreadingMgr::instance().getMode()) { + lock_guard<mutex> lock(*mutex_); + return (getMaxSampleAgeDefaultInternal()); + } else { + return (getMaxSampleAgeDefaultInternal()); + } +} + +const StatsDuration& +StatsMgr::getMaxSampleAgeDefaultInternal() const { + return (Observation::getMaxSampleAgeDefault()); +} + +uint32_t +StatsMgr::getMaxSampleCountDefault() const { + if (MultiThreadingMgr::instance().getMode()) { + lock_guard<mutex> lock(*mutex_); + return (getMaxSampleCountDefaultInternal()); + } else { + return (getMaxSampleCountDefaultInternal()); + } +} + +uint32_t +StatsMgr::getMaxSampleCountDefaultInternal() const { + return (Observation::getMaxSampleCountDefault()); +} + +bool +StatsMgr::reset(const string& name) { + if (MultiThreadingMgr::instance().getMode()) { + lock_guard<mutex> lock(*mutex_); + return (resetInternal(name)); + } else { + return (resetInternal(name)); + } +} + +bool +StatsMgr::resetInternal(const string& name) { + ObservationPtr obs = getObservationInternal(name); + if (obs) { + obs->reset(); + return (true); + } + return (false); +} + +bool +StatsMgr::del(const string& name) { + if (MultiThreadingMgr::instance().getMode()) { + lock_guard<mutex> lock(*mutex_); + return (delInternal(name)); + } else { + return (delInternal(name)); + } +} + +bool +StatsMgr::delInternal(const string& name) { + return (global_->del(name)); +} + +void +StatsMgr::removeAll() { + if (MultiThreadingMgr::instance().getMode()) { + lock_guard<mutex> lock(*mutex_); + removeAllInternal(); + } else { + removeAllInternal(); + } +} + +void +StatsMgr::removeAllInternal() { + global_->clear(); +} + +ConstElementPtr +StatsMgr::get(const string& name) const { + if (MultiThreadingMgr::instance().getMode()) { + lock_guard<mutex> lock(*mutex_); + return (getInternal(name)); + } else { + return (getInternal(name)); + } +} + +ConstElementPtr +StatsMgr::getInternal(const string& name) const { + ElementPtr map = Element::createMap(); // a map + ObservationPtr obs = getObservationInternal(name); + if (obs) { + map->set(name, obs->getJSON()); // that contains observations + } + return (map); +} + +ConstElementPtr +StatsMgr::getAll() const { + if (MultiThreadingMgr::instance().getMode()) { + lock_guard<mutex> lock(*mutex_); + return (getAllInternal()); + } else { + return (getAllInternal()); + } +} + +ConstElementPtr +StatsMgr::getAllInternal() const { + return (global_->getAll()); +} + +void +StatsMgr::resetAll() { + if (MultiThreadingMgr::instance().getMode()) { + lock_guard<mutex> lock(*mutex_); + resetAllInternal(); + } else { + resetAllInternal(); + } +} + +void +StatsMgr::resetAllInternal() { + global_->resetAll(); +} + +size_t +StatsMgr::getSize(const string& name) const { + if (MultiThreadingMgr::instance().getMode()) { + lock_guard<mutex> lock(*mutex_); + return (getSizeInternal(name)); + } else { + return (getSizeInternal(name)); + } +} + +size_t +StatsMgr::getSizeInternal(const string& name) const { + ObservationPtr obs = getObservationInternal(name); + if (obs) { + return (obs->getSize()); + } + return (0); +} + +size_t +StatsMgr::count() const { + if (MultiThreadingMgr::instance().getMode()) { + lock_guard<mutex> lock(*mutex_); + return (countInternal()); + } else { + return (countInternal()); + } +} + +size_t +StatsMgr::countInternal() const { + return (global_->size()); +} + +ConstElementPtr +StatsMgr::statisticSetMaxSampleAgeHandler(const string& /*name*/, + const ConstElementPtr& params) { + string name, error; + StatsDuration duration; + if (!StatsMgr::getStatName(params, name, error)) { + return (createAnswer(CONTROL_RESULT_ERROR, error)); + } + if (!StatsMgr::getStatDuration(params, duration, error)) { + return (createAnswer(CONTROL_RESULT_ERROR, error)); + } + if (StatsMgr::instance().setMaxSampleAge(name, duration)) { + return (createAnswer(CONTROL_RESULT_SUCCESS, + "Statistic '" + name + "' duration limit is set.")); + } else { + return (createAnswer(CONTROL_RESULT_ERROR, + "No '" + name + "' statistic found")); + } +} + +ConstElementPtr +StatsMgr::statisticSetMaxSampleCountHandler(const string& /*name*/, + const ConstElementPtr& params) { + string name, error; + uint32_t max_samples; + if (!StatsMgr::getStatName(params, name, error)) { + return (createAnswer(CONTROL_RESULT_ERROR, error)); + } + if (!StatsMgr::getStatMaxSamples(params, max_samples, error)) { + return (createAnswer(CONTROL_RESULT_ERROR, error)); + } + if (StatsMgr::instance().setMaxSampleCount(name, max_samples)) { + return (createAnswer(CONTROL_RESULT_SUCCESS, + "Statistic '" + name + "' count limit is set.")); + } else { + return (createAnswer(CONTROL_RESULT_ERROR, + "No '" + name + "' statistic found")); + } +} + +ConstElementPtr +StatsMgr::statisticGetHandler(const string& /*name*/, + const ConstElementPtr& params) { + string name, error; + if (!StatsMgr::getStatName(params, name, error)) { + return (createAnswer(CONTROL_RESULT_ERROR, error)); + } + return (createAnswer(CONTROL_RESULT_SUCCESS, + StatsMgr::instance().get(name))); +} + +ConstElementPtr +StatsMgr::statisticResetHandler(const string& /*name*/, + const ConstElementPtr& params) { + string name, error; + if (!StatsMgr::getStatName(params, name, error)) { + return (createAnswer(CONTROL_RESULT_ERROR, error)); + } + if (StatsMgr::instance().reset(name)) { + return (createAnswer(CONTROL_RESULT_SUCCESS, + "Statistic '" + name + "' reset.")); + } else { + return (createAnswer(CONTROL_RESULT_ERROR, + "No '" + name + "' statistic found")); + } +} + +ConstElementPtr +StatsMgr::statisticRemoveHandler(const string& /*name*/, + const ConstElementPtr& params) { + string name, error; + if (!StatsMgr::getStatName(params, name, error)) { + return (createAnswer(CONTROL_RESULT_ERROR, error)); + } + if (StatsMgr::instance().del(name)) { + return (createAnswer(CONTROL_RESULT_SUCCESS, + "Statistic '" + name + "' removed.")); + } else { + return (createAnswer(CONTROL_RESULT_ERROR, + "No '" + name + "' statistic found")); + } + +} + +ConstElementPtr +StatsMgr::statisticRemoveAllHandler(const string& /*name*/, + const ConstElementPtr& /*params*/) { + StatsMgr::instance().removeAll(); + return (createAnswer(CONTROL_RESULT_SUCCESS, + "Warning: statistic-remove-all command is deprecated." + " All statistics removed.")); +} + +ConstElementPtr +StatsMgr::statisticGetAllHandler(const string& /*name*/, + const ConstElementPtr& /*params*/) { + ConstElementPtr all_stats = StatsMgr::instance().getAll(); + return (createAnswer(CONTROL_RESULT_SUCCESS, all_stats)); +} + +ConstElementPtr +StatsMgr::statisticResetAllHandler(const string& /*name*/, + const ConstElementPtr& /*params*/) { + StatsMgr::instance().resetAll(); + return (createAnswer(CONTROL_RESULT_SUCCESS, + "All statistics reset to neutral values.")); +} + +ConstElementPtr +StatsMgr::statisticSetMaxSampleAgeAllHandler(const ConstElementPtr& params) { + string error; + StatsDuration duration; + if (!StatsMgr::getStatDuration(params, duration, error)) { + return (createAnswer(CONTROL_RESULT_ERROR, error)); + } + if (MultiThreadingMgr::instance().getMode()) { + lock_guard<mutex> lock(*mutex_); + StatsMgr::instance().setMaxSampleCountDefaultInternal(0); + StatsMgr::instance().setMaxSampleAgeDefaultInternal(duration); + StatsMgr::instance().setMaxSampleAgeAllInternal(duration); + } else { + StatsMgr::instance().setMaxSampleCountDefaultInternal(0); + StatsMgr::instance().setMaxSampleAgeDefaultInternal(duration); + StatsMgr::instance().setMaxSampleAgeAllInternal(duration); + } + return (createAnswer(CONTROL_RESULT_SUCCESS, + "All statistics duration limit are set.")); +} + +ConstElementPtr +StatsMgr::statisticSetMaxSampleCountAllHandler(const ConstElementPtr& params) { + string error; + uint32_t max_samples; + if (!StatsMgr::getStatMaxSamples(params, max_samples, error)) { + return (createAnswer(CONTROL_RESULT_ERROR, error)); + } + if (max_samples == 0) { + error = "'max-samples' parameter must not be zero"; + return (createAnswer(CONTROL_RESULT_ERROR, error)); + } + if (MultiThreadingMgr::instance().getMode()) { + lock_guard<mutex> lock(*mutex_); + StatsMgr::instance().setMaxSampleCountDefaultInternal(max_samples); + StatsMgr::instance().setMaxSampleCountAllInternal(max_samples); + } else { + StatsMgr::instance().setMaxSampleCountDefaultInternal(max_samples); + StatsMgr::instance().setMaxSampleCountAllInternal(max_samples); + } + return (createAnswer(CONTROL_RESULT_SUCCESS, + "All statistics count limit are set.")); +} + +bool +StatsMgr::getStatName(const ConstElementPtr& params, + string& name, + string& reason) { + if (!params) { + reason = "Missing mandatory 'name' parameter."; + return (false); + } + ConstElementPtr stat_name = params->get("name"); + if (!stat_name) { + reason = "Missing mandatory 'name' parameter."; + return (false); + } + if (stat_name->getType() != Element::string) { + reason = "'name' parameter expected to be a string."; + return (false); + } + name = stat_name->stringValue(); + return (true); +} + +bool +StatsMgr::getStatDuration(const ConstElementPtr& params, + StatsDuration& duration, + string& reason) { + if (!params) { + reason = "Missing mandatory 'duration' parameter."; + return (false); + } + ConstElementPtr stat_duration = params->get("duration"); + if (!stat_duration) { + reason = "Missing mandatory 'duration' parameter."; + return (false); + } + duration = std::chrono::seconds(stat_duration->intValue()); + return (true); +} + +bool +StatsMgr::getStatMaxSamples(const ConstElementPtr& params, + uint32_t& max_samples, + string& reason) { + if (!params) { + reason = "Missing mandatory 'max-samples' parameter."; + return (false); + } + ConstElementPtr stat_max_samples = params->get("max-samples"); + if (!stat_max_samples) { + reason = "Missing mandatory 'max-samples' parameter."; + return (false); + } + if (stat_max_samples->getType() != Element::integer) { + reason = "'max-samples' parameter expected to be an integer."; + return (false); + } + max_samples = stat_max_samples->intValue(); + return (true); +} + +} // end of namespace stats +} // end of namespace isc |