Kea  2.1.7-git
lib/stats/stats_mgr.cc
Go to the documentation of this file.
1 // Copyright (C) 2015-2020 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>
12 #include <cc/command_interpreter.h>
14 #include <boost/make_shared.hpp>
15 #include <chrono>
16 
17 using namespace std;
18 using namespace std::chrono;
19 using namespace isc::data;
20 using namespace isc::config;
21 using namespace isc::util;
22 
23 namespace isc {
24 namespace stats {
25 
26 StatsMgr&
27 StatsMgr::instance() {
28  static StatsMgr stats_mgr;
29  return (stats_mgr);
30 }
31 
32 StatsMgr::StatsMgr() :
33  global_(boost::make_shared<StatContext>()), mutex_(new mutex) {
34 }
35 
36 void
37 StatsMgr::setValue(const string& name, const int64_t value) {
38  if (MultiThreadingMgr::instance().getMode()) {
39  lock_guard<mutex> lock(*mutex_);
40  setValueInternal(name, value);
41  } else {
42  setValueInternal(name, value);
43  }
44 }
45 
46 void
47 StatsMgr::setValue(const string& name, const double value) {
48  if (MultiThreadingMgr::instance().getMode()) {
49  lock_guard<mutex> lock(*mutex_);
50  setValueInternal(name, value);
51  } else {
52  setValueInternal(name, value);
53  }
54 }
55 
56 void
57 StatsMgr::setValue(const string& name, const StatsDuration& value) {
58  if (MultiThreadingMgr::instance().getMode()) {
59  lock_guard<mutex> lock(*mutex_);
60  setValueInternal(name, value);
61  } else {
62  setValueInternal(name, value);
63  }
64 }
65 
66 void
67 StatsMgr::setValue(const string& name, const string& value) {
68  if (MultiThreadingMgr::instance().getMode()) {
69  lock_guard<mutex> lock(*mutex_);
70  setValueInternal(name, value);
71  } else {
72  setValueInternal(name, value);
73  }
74 }
75 
76 void
77 StatsMgr::addValue(const string& name, const int64_t value) {
78  if (MultiThreadingMgr::instance().getMode()) {
79  lock_guard<mutex> lock(*mutex_);
80  addValueInternal(name, value);
81  } else {
82  addValueInternal(name, value);
83  }
84 }
85 
86 void
87 StatsMgr::addValue(const string& name, const double value) {
88  if (MultiThreadingMgr::instance().getMode()) {
89  lock_guard<mutex> lock(*mutex_);
90  addValueInternal(name, value);
91  } else {
92  addValueInternal(name, value);
93  }
94 }
95 
96 void
97 StatsMgr::addValue(const string& name, const StatsDuration& value) {
98  if (MultiThreadingMgr::instance().getMode()) {
99  lock_guard<mutex> lock(*mutex_);
100  addValueInternal(name, value);
101  } else {
102  addValueInternal(name, value);
103  }
104 }
105 
106 void
107 StatsMgr::addValue(const string& name, const string& value) {
108  if (MultiThreadingMgr::instance().getMode()) {
109  lock_guard<mutex> lock(*mutex_);
110  addValueInternal(name, value);
111  } else {
112  addValueInternal(name, value);
113  }
114 }
115 
117 StatsMgr::getObservation(const string& name) const {
118  if (MultiThreadingMgr::instance().getMode()) {
119  lock_guard<mutex> lock(*mutex_);
120  return (getObservationInternal(name));
121  } else {
122  return (getObservationInternal(name));
123  }
124 }
125 
127 StatsMgr::getObservationInternal(const string& name) const {
129  // Currently we keep everything in a global context.
130  return (global_->get(name));
131 }
132 
133 void
134 StatsMgr::addObservation(const ObservationPtr& stat) {
135  if (MultiThreadingMgr::instance().getMode()) {
136  lock_guard<mutex> lock(*mutex_);
137  addObservationInternal(stat);
138  } else {
139  addObservationInternal(stat);
140  }
141 }
142 
143 void
144 StatsMgr::addObservationInternal(const ObservationPtr& stat) {
146  // Currently we keep everything in a global context.
147  global_->add(stat);
148 }
149 
150 bool
151 StatsMgr::deleteObservation(const string& name) {
152  if (MultiThreadingMgr::instance().getMode()) {
153  lock_guard<mutex> lock(*mutex_);
154  return (deleteObservationInternal(name));
155  } else {
156  return (deleteObservationInternal(name));
157  }
158 }
159 
160 bool
161 StatsMgr::deleteObservationInternal(const string& name) {
163  // Currently we keep everything in a global context.
164  return (global_->del(name));
165 }
166 
167 bool
168 StatsMgr::setMaxSampleAge(const string& name, const StatsDuration& duration) {
169  if (MultiThreadingMgr::instance().getMode()) {
170  lock_guard<mutex> lock(*mutex_);
171  return (setMaxSampleAgeInternal(name, duration));
172  } else {
173  return (setMaxSampleAgeInternal(name, duration));
174  }
175 }
176 
177 bool
178 StatsMgr::setMaxSampleAgeInternal(const string& name,
179  const StatsDuration& duration) {
180  ObservationPtr obs = getObservationInternal(name);
181  if (obs) {
182  obs->setMaxSampleAge(duration);
183  return (true);
184  }
185  return (false);
186 }
187 
188 bool
189 StatsMgr::setMaxSampleCount(const string& name, uint32_t max_samples) {
190  if (MultiThreadingMgr::instance().getMode()) {
191  lock_guard<mutex> lock(*mutex_);
192  return (setMaxSampleCountInternal(name, max_samples));
193  } else {
194  return (setMaxSampleCountInternal(name, max_samples));
195  }
196 }
197 
198 bool
199 StatsMgr::setMaxSampleCountInternal(const string& name,
200  uint32_t max_samples) {
201  ObservationPtr obs = getObservationInternal(name);
202  if (obs) {
203  obs->setMaxSampleCount(max_samples);
204  return (true);
205  }
206  return (false);
207 }
208 
209 void
210 StatsMgr::setMaxSampleAgeAll(const StatsDuration& duration) {
211  if (MultiThreadingMgr::instance().getMode()) {
212  lock_guard<mutex> lock(*mutex_);
213  setMaxSampleAgeAllInternal(duration);
214  } else {
215  setMaxSampleAgeAllInternal(duration);
216  }
217 }
218 
219 void
220 StatsMgr::setMaxSampleAgeAllInternal(const StatsDuration& duration) {
221  global_->setMaxSampleAgeAll(duration);
222 }
223 
224 void
225 StatsMgr::setMaxSampleCountAll(uint32_t max_samples) {
226  if (MultiThreadingMgr::instance().getMode()) {
227  lock_guard<mutex> lock(*mutex_);
228  setMaxSampleCountAllInternal(max_samples);
229  } else {
230  setMaxSampleCountAllInternal(max_samples);
231  }
232 }
233 
234 void
235 StatsMgr::setMaxSampleCountAllInternal(uint32_t max_samples) {
236  global_->setMaxSampleCountAll(max_samples);
237 }
238 
239 void
240 StatsMgr::setMaxSampleAgeDefault(const StatsDuration& duration) {
241  if (MultiThreadingMgr::instance().getMode()) {
242  lock_guard<mutex> lock(*mutex_);
243  setMaxSampleAgeDefaultInternal(duration);
244  } else {
245  setMaxSampleAgeDefaultInternal(duration);
246  }
247 }
248 
249 void
250 StatsMgr::setMaxSampleAgeDefaultInternal(const StatsDuration& duration) {
251  Observation::setMaxSampleAgeDefault(duration);
252 }
253 
254 void
255 StatsMgr::setMaxSampleCountDefault(uint32_t max_samples) {
256  if (MultiThreadingMgr::instance().getMode()) {
257  lock_guard<mutex> lock(*mutex_);
258  setMaxSampleCountDefaultInternal(max_samples);
259  } else {
260  setMaxSampleCountDefaultInternal(max_samples);
261  }
262 }
263 
264 void
265 StatsMgr::setMaxSampleCountDefaultInternal(uint32_t max_samples) {
266  Observation::setMaxSampleCountDefault(max_samples);
267 }
268 
269 const StatsDuration&
270 StatsMgr::getMaxSampleAgeDefault() const {
271  if (MultiThreadingMgr::instance().getMode()) {
272  lock_guard<mutex> lock(*mutex_);
273  return (getMaxSampleAgeDefaultInternal());
274  } else {
275  return (getMaxSampleAgeDefaultInternal());
276  }
277 }
278 
279 const StatsDuration&
280 StatsMgr::getMaxSampleAgeDefaultInternal() const {
281  return (Observation::getMaxSampleAgeDefault());
282 }
283 
284 uint32_t
285 StatsMgr::getMaxSampleCountDefault() const {
286  if (MultiThreadingMgr::instance().getMode()) {
287  lock_guard<mutex> lock(*mutex_);
288  return (getMaxSampleCountDefaultInternal());
289  } else {
290  return (getMaxSampleCountDefaultInternal());
291  }
292 }
293 
294 uint32_t
295 StatsMgr::getMaxSampleCountDefaultInternal() const {
296  return (Observation::getMaxSampleCountDefault());
297 }
298 
299 bool
300 StatsMgr::reset(const string& name) {
301  if (MultiThreadingMgr::instance().getMode()) {
302  lock_guard<mutex> lock(*mutex_);
303  return (resetInternal(name));
304  } else {
305  return (resetInternal(name));
306  }
307 }
308 
309 bool
310 StatsMgr::resetInternal(const string& name) {
311  ObservationPtr obs = getObservationInternal(name);
312  if (obs) {
313  obs->reset();
314  return (true);
315  }
316  return (false);
317 }
318 
319 bool
320 StatsMgr::del(const string& name) {
321  if (MultiThreadingMgr::instance().getMode()) {
322  lock_guard<mutex> lock(*mutex_);
323  return (delInternal(name));
324  } else {
325  return (delInternal(name));
326  }
327 }
328 
329 bool
330 StatsMgr::delInternal(const string& name) {
331  return (global_->del(name));
332 }
333 
334 void
335 StatsMgr::removeAll() {
336  if (MultiThreadingMgr::instance().getMode()) {
337  lock_guard<mutex> lock(*mutex_);
338  removeAllInternal();
339  } else {
340  removeAllInternal();
341  }
342 }
343 
344 void
345 StatsMgr::removeAllInternal() {
346  global_->clear();
347 }
348 
350 StatsMgr::get(const string& name) const {
351  if (MultiThreadingMgr::instance().getMode()) {
352  lock_guard<mutex> lock(*mutex_);
353  return (getInternal(name));
354  } else {
355  return (getInternal(name));
356  }
357 }
358 
360 StatsMgr::getInternal(const string& name) const {
361  ElementPtr map = Element::createMap(); // a map
362  ObservationPtr obs = getObservationInternal(name);
363  if (obs) {
364  map->set(name, obs->getJSON()); // that contains observations
365  }
366  return (map);
367 }
368 
370 StatsMgr::getAll() const {
371  if (MultiThreadingMgr::instance().getMode()) {
372  lock_guard<mutex> lock(*mutex_);
373  return (getAllInternal());
374  } else {
375  return (getAllInternal());
376  }
377 }
378 
380 StatsMgr::getAllInternal() const {
381  return (global_->getAll());
382 }
383 
384 void
385 StatsMgr::resetAll() {
386  if (MultiThreadingMgr::instance().getMode()) {
387  lock_guard<mutex> lock(*mutex_);
388  resetAllInternal();
389  } else {
390  resetAllInternal();
391  }
392 }
393 
394 void
395 StatsMgr::resetAllInternal() {
396  global_->resetAll();
397 }
398 
399 size_t
400 StatsMgr::getSize(const string& name) const {
401  if (MultiThreadingMgr::instance().getMode()) {
402  lock_guard<mutex> lock(*mutex_);
403  return (getSizeInternal(name));
404  } else {
405  return (getSizeInternal(name));
406  }
407 }
408 
409 size_t
410 StatsMgr::getSizeInternal(const string& name) const {
411  ObservationPtr obs = getObservationInternal(name);
412  if (obs) {
413  return (obs->getSize());
414  }
415  return (0);
416 }
417 
418 size_t
419 StatsMgr::count() const {
420  if (MultiThreadingMgr::instance().getMode()) {
421  lock_guard<mutex> lock(*mutex_);
422  return (countInternal());
423  } else {
424  return (countInternal());
425  }
426 }
427 
428 size_t
429 StatsMgr::countInternal() const {
430  return (global_->size());
431 }
432 
434 StatsMgr::statisticSetMaxSampleAgeHandler(const string& /*name*/,
435  const ConstElementPtr& params) {
436  string name, error;
437  StatsDuration duration;
438  if (!StatsMgr::getStatName(params, name, error)) {
439  return (createAnswer(CONTROL_RESULT_ERROR, error));
440  }
441  if (!StatsMgr::getStatDuration(params, duration, error)) {
442  return (createAnswer(CONTROL_RESULT_ERROR, error));
443  }
444  if (StatsMgr::instance().setMaxSampleAge(name, duration)) {
446  "Statistic '" + name + "' duration limit is set."));
447  } else {
449  "No '" + name + "' statistic found"));
450  }
451 }
452 
454 StatsMgr::statisticSetMaxSampleCountHandler(const string& /*name*/,
455  const ConstElementPtr& params) {
456  string name, error;
457  uint32_t max_samples;
458  if (!StatsMgr::getStatName(params, name, error)) {
459  return (createAnswer(CONTROL_RESULT_ERROR, error));
460  }
461  if (!StatsMgr::getStatMaxSamples(params, max_samples, error)) {
462  return (createAnswer(CONTROL_RESULT_ERROR, error));
463  }
464  if (StatsMgr::instance().setMaxSampleCount(name, max_samples)) {
466  "Statistic '" + name + "' count limit is set."));
467  } else {
469  "No '" + name + "' statistic found"));
470  }
471 }
472 
474 StatsMgr::statisticGetHandler(const string& /*name*/,
475  const ConstElementPtr& params) {
476  string name, error;
477  if (!StatsMgr::getStatName(params, name, error)) {
478  return (createAnswer(CONTROL_RESULT_ERROR, error));
479  }
481  StatsMgr::instance().get(name)));
482 }
483 
485 StatsMgr::statisticResetHandler(const string& /*name*/,
486  const ConstElementPtr& params) {
487  string name, error;
488  if (!StatsMgr::getStatName(params, name, error)) {
489  return (createAnswer(CONTROL_RESULT_ERROR, error));
490  }
491  if (StatsMgr::instance().reset(name)) {
493  "Statistic '" + name + "' reset."));
494  } else {
496  "No '" + name + "' statistic found"));
497  }
498 }
499 
501 StatsMgr::statisticRemoveHandler(const string& /*name*/,
502  const ConstElementPtr& params) {
503  string name, error;
504  if (!StatsMgr::getStatName(params, name, error)) {
505  return (createAnswer(CONTROL_RESULT_ERROR, error));
506  }
507  if (StatsMgr::instance().del(name)) {
509  "Statistic '" + name + "' removed."));
510  } else {
512  "No '" + name + "' statistic found"));
513  }
514 
515 }
516 
518 StatsMgr::statisticRemoveAllHandler(const string& /*name*/,
519  const ConstElementPtr& /*params*/) {
520  StatsMgr::instance().removeAll();
522  "Warning: statistic-remove-all command is deprecated."
523  " All statistics removed."));
524 }
525 
527 StatsMgr::statisticGetAllHandler(const string& /*name*/,
528  const ConstElementPtr& /*params*/) {
529  ConstElementPtr all_stats = StatsMgr::instance().getAll();
530  return (createAnswer(CONTROL_RESULT_SUCCESS, all_stats));
531 }
532 
534 StatsMgr::statisticResetAllHandler(const string& /*name*/,
535  const ConstElementPtr& /*params*/) {
536  StatsMgr::instance().resetAll();
538  "All statistics reset to neutral values."));
539 }
540 
542 StatsMgr::statisticSetMaxSampleAgeAllHandler(const ConstElementPtr& params) {
543  string error;
544  StatsDuration duration;
545  if (!StatsMgr::getStatDuration(params, duration, error)) {
546  return (createAnswer(CONTROL_RESULT_ERROR, error));
547  }
548  if (MultiThreadingMgr::instance().getMode()) {
549  lock_guard<mutex> lock(*mutex_);
550  StatsMgr::instance().setMaxSampleCountDefaultInternal(0);
551  StatsMgr::instance().setMaxSampleAgeDefaultInternal(duration);
552  StatsMgr::instance().setMaxSampleAgeAllInternal(duration);
553  } else {
554  StatsMgr::instance().setMaxSampleCountDefaultInternal(0);
555  StatsMgr::instance().setMaxSampleAgeDefaultInternal(duration);
556  StatsMgr::instance().setMaxSampleAgeAllInternal(duration);
557  }
559  "All statistics duration limit are set."));
560 }
561 
563 StatsMgr::statisticSetMaxSampleCountAllHandler(const ConstElementPtr& params) {
564  string error;
565  uint32_t max_samples;
566  if (!StatsMgr::getStatMaxSamples(params, max_samples, error)) {
567  return (createAnswer(CONTROL_RESULT_ERROR, error));
568  }
569  if (max_samples == 0) {
570  error = "'max-samples' parameter must not be zero";
571  return (createAnswer(CONTROL_RESULT_ERROR, error));
572  }
573  if (MultiThreadingMgr::instance().getMode()) {
574  lock_guard<mutex> lock(*mutex_);
575  StatsMgr::instance().setMaxSampleCountDefaultInternal(max_samples);
576  StatsMgr::instance().setMaxSampleCountAllInternal(max_samples);
577  } else {
578  StatsMgr::instance().setMaxSampleCountDefaultInternal(max_samples);
579  StatsMgr::instance().setMaxSampleCountAllInternal(max_samples);
580  }
582  "All statistics count limit are set."));
583 }
584 
585 bool
586 StatsMgr::getStatName(const ConstElementPtr& params,
587  string& name,
588  string& reason) {
589  if (!params) {
590  reason = "Missing mandatory 'name' parameter.";
591  return (false);
592  }
593  ConstElementPtr stat_name = params->get("name");
594  if (!stat_name) {
595  reason = "Missing mandatory 'name' parameter.";
596  return (false);
597  }
598  if (stat_name->getType() != Element::string) {
599  reason = "'name' parameter expected to be a string.";
600  return (false);
601  }
602  name = stat_name->stringValue();
603  return (true);
604 }
605 
606 bool
607 StatsMgr::getStatDuration(const ConstElementPtr& params,
608  StatsDuration& duration,
609  string& reason) {
610  if (!params) {
611  reason = "Missing mandatory 'duration' parameter.";
612  return (false);
613  }
614  ConstElementPtr stat_duration = params->get("duration");
615  if (!stat_duration) {
616  reason = "Missing mandatory 'duration' parameter.";
617  return (false);
618  }
619  duration = std::chrono::seconds(stat_duration->intValue());
620  return (true);
621 }
622 
623 bool
624 StatsMgr::getStatMaxSamples(const ConstElementPtr& params,
625  uint32_t& max_samples,
626  string& reason) {
627  if (!params) {
628  reason = "Missing mandatory 'max-samples' parameter.";
629  return (false);
630  }
631  ConstElementPtr stat_max_samples = params->get("max-samples");
632  if (!stat_max_samples) {
633  reason = "Missing mandatory 'max-samples' parameter.";
634  return (false);
635  }
636  if (stat_max_samples->getType() != Element::integer) {
637  reason = "'max-samples' parameter expected to be an integer.";
638  return (false);
639  }
640  max_samples = stat_max_samples->intValue();
641  return (true);
642 }
643 
644 } // end of namespace stats
645 } // end of namespace isc
ConstElementPtr createAnswer(const int status_code, const std::string &text, const ConstElementPtr &arg)
const int CONTROL_RESULT_SUCCESS
Status code indicating a successful operation.
const int CONTROL_RESULT_ERROR
Status code indicating a general failure.
boost::shared_ptr< Element > ElementPtr
Definition: data.h:24
STL namespace.
Statistics Manager class.
std::chrono::system_clock::duration StatsDuration
Defines duration type.
Definition: observation.h:39
Definition: edns.h:19
boost::shared_ptr< const Element > ConstElementPtr
Definition: data.h:27
Defines the logger used by the top-level component of kea-lfc.
This file contains several functions and constants that are used for handling commands and responses ...
boost::shared_ptr< Observation > ObservationPtr
Observation pointer.
Definition: observation.h:440