Kea 2.7.0
lib/stats/stats_mgr.cc
Go to the documentation of this file.
1// Copyright (C) 2015-2024 Internet Systems Consortium, Inc. ("ISC")
2//
3// This Source Code Form is subject to the terms of the Mozilla Public
4// License, v. 2.0. If a copy of the MPL was not distributed with this
5// file, You can obtain one at http://mozilla.org/MPL/2.0/.
6
7#include <config.h>
8
10#include <stats/stats_mgr.h>
11#include <cc/data.h>
14#include <util/bigints.h>
15
16#include <boost/make_shared.hpp>
17
18#include <chrono>
19
20using namespace std;
21using namespace std::chrono;
22using namespace isc::data;
23using namespace isc::config;
24using namespace isc::util;
25
26namespace isc {
27namespace stats {
28
29StatsMgr&
31 static StatsMgr stats_mgr;
32 return (stats_mgr);
33}
34
35StatsMgr::StatsMgr() :
36 global_(boost::make_shared<StatContext>()), mutex_(new mutex()) {
37}
38
39void
40StatsMgr::setValue(const string& name, const int64_t value) {
41 MultiThreadingLock lock(*mutex_);
42 setValueInternal(name, value);
43}
44
45void
46StatsMgr::setValue(const string& name, const int128_t& value) {
47 MultiThreadingLock lock(*mutex_);
48 setValueInternal(name, value);
49}
50
51void
52StatsMgr::setValue(const string& name, const double value) {
53 MultiThreadingLock lock(*mutex_);
54 setValueInternal(name, value);
55}
56
57void
58StatsMgr::setValue(const string& name, const StatsDuration& value) {
59 MultiThreadingLock lock(*mutex_);
60 setValueInternal(name, value);
61}
62
63void
64StatsMgr::setValue(const string& name, const string& value) {
65 MultiThreadingLock lock(*mutex_);
66 setValueInternal(name, value);
67}
68
69void
70StatsMgr::addValue(const string& name, const int64_t value) {
71 MultiThreadingLock lock(*mutex_);
72 addValueInternal(name, value);
73}
74
75void
76StatsMgr::addValue(const string& name, const int128_t& value) {
77 MultiThreadingLock lock(*mutex_);
78 addValueInternal(name, value);
79}
80
81void
82StatsMgr::addValue(const string& name, const double value) {
83 MultiThreadingLock lock(*mutex_);
84 addValueInternal(name, value);
85}
86
87void
88StatsMgr::addValue(const string& name, const StatsDuration& value) {
89 MultiThreadingLock lock(*mutex_);
90 addValueInternal(name, value);
91}
92
93void
94StatsMgr::addValue(const string& name, const string& value) {
95 MultiThreadingLock lock(*mutex_);
96 addValueInternal(name, value);
97}
98
100StatsMgr::getObservation(const string& name) const {
101 MultiThreadingLock lock(*mutex_);
102 return (getObservationInternal(name));
103}
104
106StatsMgr::getObservationInternal(const string& name) const {
108 // Currently we keep everything in a global context.
109 return (global_->get(name));
110}
111
112void
117
118void
121 // Currently we keep everything in a global context.
122 global_->add(stat);
123}
124
125bool
126StatsMgr::deleteObservation(const string& name) {
127 MultiThreadingLock lock(*mutex_);
128 return (deleteObservationInternal(name));
129}
130
131bool
132StatsMgr::deleteObservationInternal(const string& name) {
134 // Currently we keep everything in a global context.
135 return (global_->del(name));
136}
137
138bool
139StatsMgr::setMaxSampleAge(const string& name, const StatsDuration& duration) {
140 MultiThreadingLock lock(*mutex_);
141 return (setMaxSampleAgeInternal(name, duration));
142}
143
144bool
145StatsMgr::setMaxSampleAgeInternal(const string& name,
146 const StatsDuration& duration) {
148 if (obs) {
149 obs->setMaxSampleAge(duration);
150 return (true);
151 }
152 return (false);
153}
154
155bool
156StatsMgr::setMaxSampleCount(const string& name, uint32_t max_samples) {
157 MultiThreadingLock lock(*mutex_);
158 return (setMaxSampleCountInternal(name, max_samples));
159}
160
161bool
162StatsMgr::setMaxSampleCountInternal(const string& name,
163 uint32_t max_samples) {
165 if (obs) {
166 obs->setMaxSampleCount(max_samples);
167 return (true);
168 }
169 return (false);
170}
171
172void
174 MultiThreadingLock lock(*mutex_);
175 setMaxSampleAgeAllInternal(duration);
176}
177
178void
179StatsMgr::setMaxSampleAgeAllInternal(const StatsDuration& duration) {
180 global_->setMaxSampleAgeAll(duration);
181}
182
183void
184StatsMgr::setMaxSampleCountAll(uint32_t max_samples) {
185 MultiThreadingLock lock(*mutex_);
186 setMaxSampleCountAllInternal(max_samples);
187}
188
189void
190StatsMgr::setMaxSampleCountAllInternal(uint32_t max_samples) {
191 global_->setMaxSampleCountAll(max_samples);
192}
193
194void
196 MultiThreadingLock lock(*mutex_);
197 setMaxSampleAgeDefaultInternal(duration);
198}
199
200void
201StatsMgr::setMaxSampleAgeDefaultInternal(const StatsDuration& duration) {
203}
204
205void
207 MultiThreadingLock lock(*mutex_);
208 setMaxSampleCountDefaultInternal(max_samples);
209}
210
211void
212StatsMgr::setMaxSampleCountDefaultInternal(uint32_t max_samples) {
214}
215
216const StatsDuration&
218 MultiThreadingLock lock(*mutex_);
219 return (getMaxSampleAgeDefaultInternal());
220}
221
222const StatsDuration&
223StatsMgr::getMaxSampleAgeDefaultInternal() const {
225}
226
227uint32_t
229 MultiThreadingLock lock(*mutex_);
230 return (getMaxSampleCountDefaultInternal());
231}
232
233uint32_t
234StatsMgr::getMaxSampleCountDefaultInternal() const {
236}
237
238bool
239StatsMgr::reset(const string& name) {
240 MultiThreadingLock lock(*mutex_);
241 return (resetInternal(name));
242}
243
244bool
245StatsMgr::resetInternal(const string& name) {
247 if (obs) {
248 obs->reset();
249 return (true);
250 }
251 return (false);
252}
253
254bool
255StatsMgr::del(const string& name) {
256 MultiThreadingLock lock(*mutex_);
257 return (delInternal(name));
258}
259
260bool
261StatsMgr::delInternal(const string& name) {
262 return (global_->del(name));
263}
264
265void
267 MultiThreadingLock lock(*mutex_);
268 removeAllInternal();
269}
270
271void
272StatsMgr::removeAllInternal() {
273 global_->clear();
274}
275
277StatsMgr::get(const string& name) const {
278 MultiThreadingLock lock(*mutex_);
279 return (getInternal(name));
280}
281
283StatsMgr::getInternal(const string& name) const {
284 ElementPtr map = Element::createMap(); // a map
286 if (obs) {
287 map->set(name, obs->getJSON()); // that contains observations
288 }
289 return (map);
290}
291
294 MultiThreadingLock lock(*mutex_);
295 return (getAllInternal());
296}
297
299StatsMgr::getAllInternal() const {
300 return (global_->getAll());
301}
302
303void
305 MultiThreadingLock lock(*mutex_);
306 resetAllInternal();
307}
308
309void
310StatsMgr::resetAllInternal() {
311 global_->resetAll();
312}
313
314size_t
315StatsMgr::getSize(const string& name) const {
316 MultiThreadingLock lock(*mutex_);
317 return (getSizeInternal(name));
318}
319
320size_t
321StatsMgr::getSizeInternal(const string& name) const {
323 if (obs) {
324 return (obs->getSize());
325 }
326 return (0);
327}
328
329size_t
331 MultiThreadingLock lock(*mutex_);
332 return (countInternal());
333}
334
335size_t
336StatsMgr::countInternal() const {
337 return (global_->size());
338}
339
342 const ConstElementPtr& params) {
343 string name, error;
344 StatsDuration duration;
345 if (!StatsMgr::getStatName(params, name, error)) {
346 return (createAnswer(CONTROL_RESULT_ERROR, error));
347 }
348 if (!StatsMgr::getStatDuration(params, duration, error)) {
349 return (createAnswer(CONTROL_RESULT_ERROR, error));
350 }
351 if (StatsMgr::instance().setMaxSampleAge(name, duration)) {
353 "Statistic '" + name + "' duration limit is set."));
354 } else {
356 "No '" + name + "' statistic found"));
357 }
358}
359
362 const ConstElementPtr& params) {
363 string name, error;
364 uint32_t max_samples;
365 if (!StatsMgr::getStatName(params, name, error)) {
366 return (createAnswer(CONTROL_RESULT_ERROR, error));
367 }
368 if (!StatsMgr::getStatMaxSamples(params, max_samples, error)) {
369 return (createAnswer(CONTROL_RESULT_ERROR, error));
370 }
371 if (StatsMgr::instance().setMaxSampleCount(name, max_samples)) {
373 "Statistic '" + name + "' count limit is set."));
374 } else {
376 "No '" + name + "' statistic found"));
377 }
378}
379
381StatsMgr::statisticGetHandler(const string& /*name*/,
382 const ConstElementPtr& params) {
383 string name, error;
384 if (!StatsMgr::getStatName(params, name, error)) {
385 return (createAnswer(CONTROL_RESULT_ERROR, error));
386 }
388 StatsMgr::instance().get(name)));
389}
390
392StatsMgr::statisticResetHandler(const string& /*name*/,
393 const ConstElementPtr& params) {
394 string name, error;
395 if (!StatsMgr::getStatName(params, name, error)) {
396 return (createAnswer(CONTROL_RESULT_ERROR, error));
397 }
398 if (StatsMgr::instance().reset(name)) {
400 "Statistic '" + name + "' reset."));
401 } else {
403 "No '" + name + "' statistic found"));
404 }
405}
406
408StatsMgr::statisticRemoveHandler(const string& /*name*/,
409 const ConstElementPtr& params) {
410 string name, error;
411 if (!StatsMgr::getStatName(params, name, error)) {
412 return (createAnswer(CONTROL_RESULT_ERROR, error));
413 }
414 if (StatsMgr::instance().del(name)) {
416 "Statistic '" + name + "' removed."));
417 } else {
419 "No '" + name + "' statistic found"));
420 }
421
422}
423
426 const ConstElementPtr& /*params*/) {
427 StatsMgr::instance().removeAll();
429 "Warning: statistic-remove-all command is deprecated."
430 " All statistics removed."));
431}
432
434StatsMgr::statisticGetAllHandler(const string& /*name*/,
435 const ConstElementPtr& /*params*/) {
436 ConstElementPtr all_stats = StatsMgr::instance().getAll();
437 return (createAnswer(CONTROL_RESULT_SUCCESS, all_stats));
438}
439
442 const ConstElementPtr& /*params*/) {
443 StatsMgr::instance().resetAll();
445 "All statistics reset to neutral values."));
446}
447
450 string error;
451 StatsDuration duration;
452 if (!StatsMgr::getStatDuration(params, duration, error)) {
453 return (createAnswer(CONTROL_RESULT_ERROR, error));
454 }
455 MultiThreadingLock lock(*mutex_);
456 StatsMgr::instance().setMaxSampleCountDefaultInternal(0);
457 StatsMgr::instance().setMaxSampleAgeDefaultInternal(duration);
458 StatsMgr::instance().setMaxSampleAgeAllInternal(duration);
460 "All statistics duration limit are set."));
461}
462
465 string error;
466 uint32_t max_samples;
467 if (!StatsMgr::getStatMaxSamples(params, max_samples, error)) {
468 return (createAnswer(CONTROL_RESULT_ERROR, error));
469 }
470 if (max_samples == 0) {
471 error = "'max-samples' parameter must not be zero";
472 return (createAnswer(CONTROL_RESULT_ERROR, error));
473 }
474 MultiThreadingLock lock(*mutex_);
475 StatsMgr::instance().setMaxSampleCountDefaultInternal(max_samples);
476 StatsMgr::instance().setMaxSampleCountAllInternal(max_samples);
478 "All statistics count limit are set."));
479}
480
481bool
482StatsMgr::getStatName(const ConstElementPtr& params,
483 string& name,
484 string& reason) {
485 if (!params) {
486 reason = "Missing mandatory 'name' parameter.";
487 return (false);
488 }
489 ConstElementPtr stat_name = params->get("name");
490 if (!stat_name) {
491 reason = "Missing mandatory 'name' parameter.";
492 return (false);
493 }
494 if (stat_name->getType() != Element::string) {
495 reason = "'name' parameter expected to be a string.";
496 return (false);
497 }
498 name = stat_name->stringValue();
499 return (true);
500}
501
502bool
503StatsMgr::getStatDuration(const ConstElementPtr& params,
504 StatsDuration& duration,
505 string& reason) {
506 if (!params) {
507 reason = "Missing mandatory 'duration' parameter.";
508 return (false);
509 }
510 ConstElementPtr stat_duration = params->get("duration");
511 if (!stat_duration) {
512 reason = "Missing mandatory 'duration' parameter.";
513 return (false);
514 }
515 duration = std::chrono::seconds(stat_duration->intValue());
516 return (true);
517}
518
519bool
520StatsMgr::getStatMaxSamples(const ConstElementPtr& params,
521 uint32_t& max_samples,
522 string& reason) {
523 if (!params) {
524 reason = "Missing mandatory 'max-samples' parameter.";
525 return (false);
526 }
527 ConstElementPtr stat_max_samples = params->get("max-samples");
528 if (!stat_max_samples) {
529 reason = "Missing mandatory 'max-samples' parameter.";
530 return (false);
531 }
532 if (stat_max_samples->getType() != Element::integer) {
533 reason = "'max-samples' parameter expected to be an integer.";
534 return (false);
535 }
536 max_samples = stat_max_samples->intValue();
537 return (true);
538}
539
540} // end of namespace stats
541} // end of namespace isc
static ElementPtr createMap(const Position &pos=ZERO_POSITION())
Creates an empty MapElement type ElementPtr.
Definition data.cc:304
static const StatsDuration & getMaxSampleAgeDefault()
Get default maximum age of samples.
static uint32_t getMaxSampleCountDefault()
Get default maximum count of samples.
static void setMaxSampleCountDefault(uint32_t max_samples)
Determines default maximum count of samples.
static void setMaxSampleAgeDefault(const StatsDuration &duration)
Determines default maximum age of samples.
Statistics Manager class.
ObservationPtr getObservation(const std::string &name) const
Returns an observation.
ObservationPtr getObservationInternal(const std::string &name) const
Returns an observation in a thread safe context.
static StatsMgr & instance()
Statistics Manager accessor method.
void addObservationInternal(const ObservationPtr &stat)
Adds a new observation in a thread safe context.
void addValueInternal(const std::string &name, DataType value)
Adds specified value to a given statistic (internal version).
void addObservation(const ObservationPtr &stat)
Adds a new observation.
void setValueInternal(const std::string &name, DataType value)
Sets a given statistic to specified value (internal version).
This file contains several functions and constants that are used for handling commands and responses ...
isc::data::ConstElementPtr statisticSetMaxSampleCountAllHandler(const isc::data::ConstElementPtr &params)
Handles statistic-sample-count-set-all command.
static isc::data::ConstElementPtr statisticResetHandler(const std::string &name, const isc::data::ConstElementPtr &params)
Handles statistic-reset command.
static isc::data::ConstElementPtr statisticGetAllHandler(const std::string &name, const isc::data::ConstElementPtr &params)
Handles statistic-get-all command.
static isc::data::ConstElementPtr statisticRemoveHandler(const std::string &name, const isc::data::ConstElementPtr &params)
Handles statistic-remove command.
static isc::data::ConstElementPtr statisticGetHandler(const std::string &name, const isc::data::ConstElementPtr &params)
Handles statistic-get command.
isc::data::ConstElementPtr statisticSetMaxSampleAgeAllHandler(const isc::data::ConstElementPtr &params)
Handles statistic-sample-age-set-all command.
static isc::data::ConstElementPtr statisticResetAllHandler(const std::string &name, const isc::data::ConstElementPtr &params)
Handles statistic-reset-all command.
static isc::data::ConstElementPtr statisticSetMaxSampleAgeHandler(const std::string &name, const isc::data::ConstElementPtr &params)
Handles statistic-sample-age-set command.
static isc::data::ConstElementPtr statisticRemoveAllHandler(const std::string &name, const isc::data::ConstElementPtr &params)
Handles statistic-remove-all command.
static isc::data::ConstElementPtr statisticSetMaxSampleCountHandler(const std::string &name, const isc::data::ConstElementPtr &params)
Handles statistic-sample-count-set command.
bool reset(const std::string &name)
Resets specified statistic.
void removeAll()
Removes all collected statistics.
void resetAll()
Resets all collected statistics back to zero.
bool del(const std::string &name)
Removes specified statistic.
size_t count() const
Returns number of available statistics.
isc::data::ConstElementPtr getAll() const
Returns all statistics as a JSON structure.
size_t getSize(const std::string &name) const
Returns size of specified statistic.
isc::data::ConstElementPtr get(const std::string &name) const
Returns a single statistic as a JSON structure.
void setMaxSampleCountDefault(uint32_t max_samples)
Set default count limit.
bool setMaxSampleCount(const std::string &name, uint32_t max_samples)
Determines how many samples of a given statistic should be kept.
uint32_t getMaxSampleCountDefault() const
Get default count limit.
void setValue(const std::string &name, const int64_t value)
Records absolute integer observation.
bool setMaxSampleAge(const std::string &name, const StatsDuration &duration)
Determines maximum age of samples.
const StatsDuration & getMaxSampleAgeDefault() const
Get default duration limit.
void setMaxSampleAgeAll(const StatsDuration &duration)
Set duration limit for all collected statistics.
void setMaxSampleCountAll(uint32_t max_samples)
Set count limit for all collected statistics.
void addValue(const std::string &name, const int64_t value)
Records incremental integer observation.
void setMaxSampleAgeDefault(const StatsDuration &duration)
Set default duration limit.
const int CONTROL_RESULT_ERROR
Status code indicating a general failure.
ConstElementPtr createAnswer()
Creates a standard config/command level success answer message (i.e.
const int CONTROL_RESULT_SUCCESS
Status code indicating a successful operation.
boost::shared_ptr< const Element > ConstElementPtr
Definition data.h:29
boost::shared_ptr< Element > ElementPtr
Definition data.h:28
boost::shared_ptr< Observation > ObservationPtr
Observation pointer.
std::chrono::system_clock::duration StatsDuration
Defines duration type.
Definition observation.h:43
boost::multiprecision::checked_int128_t int128_t
Definition bigints.h:19
Defines the logger used by the top-level component of kea-lfc.
Statistics context.
Definition context.h:31
RAII lock object to protect the code in the same scope with a mutex.