/src/kea/src/lib/stats/stats_mgr.cc
Line | Count | Source |
1 | | // Copyright (C) 2015-2025 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 | | |
9 | | #include <exceptions/exceptions.h> |
10 | | #include <stats/stats_mgr.h> |
11 | | #include <cc/data.h> |
12 | | #include <cc/command_interpreter.h> |
13 | | #include <util/multi_threading_mgr.h> |
14 | | #include <util/bigints.h> |
15 | | |
16 | | #include <boost/make_shared.hpp> |
17 | | |
18 | | #include <chrono> |
19 | | |
20 | | using namespace std; |
21 | | using namespace std::chrono; |
22 | | using namespace isc::data; |
23 | | using namespace isc::config; |
24 | | using namespace isc::util; |
25 | | |
26 | | namespace isc { |
27 | | namespace stats { |
28 | | |
29 | | StatsMgr& |
30 | 140k | StatsMgr::instance() { |
31 | 140k | static StatsMgr stats_mgr; |
32 | 140k | return (stats_mgr); |
33 | 140k | } |
34 | | |
35 | | StatsMgr::StatsMgr() : |
36 | 21 | global_(boost::make_shared<StatContext>()), mutex_(new mutex()) { |
37 | 21 | } |
38 | | |
39 | | void |
40 | 1.11M | StatsMgr::setValue(const string& name, const int64_t value) { |
41 | 1.11M | MultiThreadingLock lock(*mutex_); |
42 | 1.11M | setValueInternal(name, value); |
43 | 1.11M | } |
44 | | |
45 | | void |
46 | 636 | StatsMgr::setValue(const string& name, const int128_t& value) { |
47 | 636 | MultiThreadingLock lock(*mutex_); |
48 | 636 | setValueInternal(name, value); |
49 | 636 | } |
50 | | |
51 | | void |
52 | 0 | StatsMgr::setValue(const string& name, const double value) { |
53 | 0 | MultiThreadingLock lock(*mutex_); |
54 | 0 | setValueInternal(name, value); |
55 | 0 | } |
56 | | |
57 | | void |
58 | 0 | StatsMgr::setValue(const string& name, const StatsDuration& value) { |
59 | 0 | MultiThreadingLock lock(*mutex_); |
60 | 0 | setValueInternal(name, value); |
61 | 0 | } |
62 | | |
63 | | void |
64 | 0 | StatsMgr::setValue(const string& name, const string& value) { |
65 | 0 | MultiThreadingLock lock(*mutex_); |
66 | 0 | setValueInternal(name, value); |
67 | 0 | } |
68 | | |
69 | | void |
70 | 62.9k | StatsMgr::addValue(const string& name, const int64_t value) { |
71 | 62.9k | MultiThreadingLock lock(*mutex_); |
72 | 62.9k | addValueInternal(name, value); |
73 | 62.9k | } |
74 | | |
75 | | void |
76 | 0 | StatsMgr::addValue(const string& name, const int128_t& value) { |
77 | 0 | MultiThreadingLock lock(*mutex_); |
78 | 0 | addValueInternal(name, value); |
79 | 0 | } |
80 | | |
81 | | void |
82 | 0 | StatsMgr::addValue(const string& name, const double value) { |
83 | 0 | MultiThreadingLock lock(*mutex_); |
84 | 0 | addValueInternal(name, value); |
85 | 0 | } |
86 | | |
87 | | void |
88 | 0 | StatsMgr::addValue(const string& name, const StatsDuration& value) { |
89 | 0 | MultiThreadingLock lock(*mutex_); |
90 | 0 | addValueInternal(name, value); |
91 | 0 | } |
92 | | |
93 | | void |
94 | 0 | StatsMgr::addValue(const string& name, const string& value) { |
95 | 0 | MultiThreadingLock lock(*mutex_); |
96 | 0 | addValueInternal(name, value); |
97 | 0 | } |
98 | | |
99 | | ObservationPtr |
100 | 95.7k | StatsMgr::getObservation(const string& name) const { |
101 | 95.7k | MultiThreadingLock lock(*mutex_); |
102 | 95.7k | return (getObservationInternal(name)); |
103 | 95.7k | } |
104 | | |
105 | | ObservationPtr |
106 | 1.27M | StatsMgr::getObservationInternal(const string& name) const { |
107 | | /// @todo: Implement contexts. |
108 | | // Currently we keep everything in a global context. |
109 | 1.27M | return (global_->get(name)); |
110 | 1.27M | } |
111 | | |
112 | | void |
113 | 0 | StatsMgr::addObservation(const ObservationPtr& stat) { |
114 | 0 | MultiThreadingLock lock(*mutex_); |
115 | 0 | addObservationInternal(stat); |
116 | 0 | } |
117 | | |
118 | | void |
119 | 82.9k | StatsMgr::addObservationInternal(const ObservationPtr& stat) { |
120 | | /// @todo: Implement contexts. |
121 | | // Currently we keep everything in a global context. |
122 | 82.9k | global_->add(stat); |
123 | 82.9k | } |
124 | | |
125 | | bool |
126 | 0 | StatsMgr::deleteObservation(const string& name) { |
127 | 0 | MultiThreadingLock lock(*mutex_); |
128 | 0 | return (deleteObservationInternal(name)); |
129 | 0 | } |
130 | | |
131 | | bool |
132 | 0 | StatsMgr::deleteObservationInternal(const string& name) { |
133 | | /// @todo: Implement contexts. |
134 | | // Currently we keep everything in a global context. |
135 | 0 | return (global_->del(name)); |
136 | 0 | } |
137 | | |
138 | | bool |
139 | 0 | StatsMgr::setMaxSampleAge(const string& name, const StatsDuration& duration) { |
140 | 0 | MultiThreadingLock lock(*mutex_); |
141 | 0 | return (setMaxSampleAgeInternal(name, duration)); |
142 | 0 | } |
143 | | |
144 | | bool |
145 | | StatsMgr::setMaxSampleAgeInternal(const string& name, |
146 | 0 | const StatsDuration& duration) { |
147 | 0 | ObservationPtr obs = getObservationInternal(name); |
148 | 0 | if (obs) { |
149 | 0 | obs->setMaxSampleAge(duration); |
150 | 0 | return (true); |
151 | 0 | } |
152 | 0 | return (false); |
153 | 0 | } |
154 | | |
155 | | bool |
156 | 0 | StatsMgr::setMaxSampleCount(const string& name, uint32_t max_samples) { |
157 | 0 | MultiThreadingLock lock(*mutex_); |
158 | 0 | return (setMaxSampleCountInternal(name, max_samples)); |
159 | 0 | } |
160 | | |
161 | | bool |
162 | | StatsMgr::setMaxSampleCountInternal(const string& name, |
163 | 0 | uint32_t max_samples) { |
164 | 0 | ObservationPtr obs = getObservationInternal(name); |
165 | 0 | if (obs) { |
166 | 0 | obs->setMaxSampleCount(max_samples); |
167 | 0 | return (true); |
168 | 0 | } |
169 | 0 | return (false); |
170 | 0 | } |
171 | | |
172 | | void |
173 | 0 | StatsMgr::setMaxSampleAgeAll(const StatsDuration& duration) { |
174 | 0 | MultiThreadingLock lock(*mutex_); |
175 | 0 | setMaxSampleAgeAllInternal(duration); |
176 | 0 | } |
177 | | |
178 | | void |
179 | 0 | StatsMgr::setMaxSampleAgeAllInternal(const StatsDuration& duration) { |
180 | 0 | global_->setMaxSampleAgeAll(duration); |
181 | 0 | } |
182 | | |
183 | | void |
184 | 18.0k | StatsMgr::setMaxSampleCountAll(uint32_t max_samples) { |
185 | 18.0k | MultiThreadingLock lock(*mutex_); |
186 | 18.0k | setMaxSampleCountAllInternal(max_samples); |
187 | 18.0k | } |
188 | | |
189 | | void |
190 | 18.0k | StatsMgr::setMaxSampleCountAllInternal(uint32_t max_samples) { |
191 | 18.0k | global_->setMaxSampleCountAll(max_samples); |
192 | 18.0k | } |
193 | | |
194 | | void |
195 | 18.0k | StatsMgr::setMaxSampleAgeDefault(const StatsDuration& duration) { |
196 | 18.0k | MultiThreadingLock lock(*mutex_); |
197 | 18.0k | setMaxSampleAgeDefaultInternal(duration); |
198 | 18.0k | } |
199 | | |
200 | | void |
201 | 18.0k | StatsMgr::setMaxSampleAgeDefaultInternal(const StatsDuration& duration) { |
202 | 18.0k | Observation::setMaxSampleAgeDefault(duration); |
203 | 18.0k | } |
204 | | |
205 | | void |
206 | 18.0k | StatsMgr::setMaxSampleCountDefault(uint32_t max_samples) { |
207 | 18.0k | MultiThreadingLock lock(*mutex_); |
208 | 18.0k | setMaxSampleCountDefaultInternal(max_samples); |
209 | 18.0k | } |
210 | | |
211 | | void |
212 | 18.0k | StatsMgr::setMaxSampleCountDefaultInternal(uint32_t max_samples) { |
213 | 18.0k | Observation::setMaxSampleCountDefault(max_samples); |
214 | 18.0k | } |
215 | | |
216 | | const StatsDuration& |
217 | 0 | StatsMgr::getMaxSampleAgeDefault() const { |
218 | 0 | MultiThreadingLock lock(*mutex_); |
219 | 0 | return (getMaxSampleAgeDefaultInternal()); |
220 | 0 | } |
221 | | |
222 | | const StatsDuration& |
223 | 0 | StatsMgr::getMaxSampleAgeDefaultInternal() const { |
224 | 0 | return (Observation::getMaxSampleAgeDefault()); |
225 | 0 | } |
226 | | |
227 | | uint32_t |
228 | 0 | StatsMgr::getMaxSampleCountDefault() const { |
229 | 0 | MultiThreadingLock lock(*mutex_); |
230 | 0 | return (getMaxSampleCountDefaultInternal()); |
231 | 0 | } |
232 | | |
233 | | uint32_t |
234 | 0 | StatsMgr::getMaxSampleCountDefaultInternal() const { |
235 | 0 | return (Observation::getMaxSampleCountDefault()); |
236 | 0 | } |
237 | | |
238 | | bool |
239 | 0 | StatsMgr::reset(const string& name) { |
240 | 0 | MultiThreadingLock lock(*mutex_); |
241 | 0 | return (resetInternal(name)); |
242 | 0 | } |
243 | | |
244 | | bool |
245 | 0 | StatsMgr::resetInternal(const string& name) { |
246 | 0 | ObservationPtr obs = getObservationInternal(name); |
247 | 0 | if (obs) { |
248 | 0 | obs->reset(); |
249 | 0 | return (true); |
250 | 0 | } |
251 | 0 | return (false); |
252 | 0 | } |
253 | | |
254 | | bool |
255 | 82.1k | StatsMgr::del(const string& name) { |
256 | 82.1k | MultiThreadingLock lock(*mutex_); |
257 | 82.1k | return (delInternal(name)); |
258 | 82.1k | } |
259 | | |
260 | | bool |
261 | 82.1k | StatsMgr::delInternal(const string& name) { |
262 | 82.1k | return (global_->del(name)); |
263 | 82.1k | } |
264 | | |
265 | | void |
266 | 0 | StatsMgr::removeAll() { |
267 | 0 | MultiThreadingLock lock(*mutex_); |
268 | 0 | removeAllInternal(); |
269 | 0 | } |
270 | | |
271 | | void |
272 | 0 | StatsMgr::removeAllInternal() { |
273 | 0 | global_->clear(); |
274 | 0 | } |
275 | | |
276 | | ConstElementPtr |
277 | 0 | StatsMgr::get(const string& name) const { |
278 | 0 | MultiThreadingLock lock(*mutex_); |
279 | 0 | return (getInternal(name)); |
280 | 0 | } |
281 | | |
282 | | ConstElementPtr |
283 | 0 | StatsMgr::getInternal(const string& name) const { |
284 | 0 | ElementPtr map = Element::createMap(); // a map |
285 | 0 | ObservationPtr obs = getObservationInternal(name); |
286 | 0 | if (obs) { |
287 | 0 | map->set(name, obs->getJSON()); // that contains observations |
288 | 0 | } |
289 | 0 | return (map); |
290 | 0 | } |
291 | | |
292 | | ConstElementPtr |
293 | 0 | StatsMgr::getAll() const { |
294 | 0 | MultiThreadingLock lock(*mutex_); |
295 | 0 | return (getAllInternal()); |
296 | 0 | } |
297 | | |
298 | | ConstElementPtr |
299 | 0 | StatsMgr::getAllGlobal() const { |
300 | 0 | MultiThreadingLock lock(*mutex_); |
301 | 0 | return (getAllGlobalInternal()); |
302 | 0 | } |
303 | | |
304 | | ConstElementPtr |
305 | 0 | StatsMgr::getAllInternal() const { |
306 | 0 | return (global_->getAll()); |
307 | 0 | } |
308 | | |
309 | | ConstElementPtr |
310 | 0 | StatsMgr::getAllGlobalInternal() const { |
311 | 0 | return (global_->getAllGlobal()); |
312 | 0 | } |
313 | | |
314 | | void |
315 | 0 | StatsMgr::resetAll() { |
316 | 0 | MultiThreadingLock lock(*mutex_); |
317 | 0 | resetAllInternal(); |
318 | 0 | } |
319 | | |
320 | | void |
321 | 0 | StatsMgr::resetAllInternal() { |
322 | 0 | global_->resetAll(); |
323 | 0 | } |
324 | | |
325 | | size_t |
326 | 0 | StatsMgr::getSize(const string& name) const { |
327 | 0 | MultiThreadingLock lock(*mutex_); |
328 | 0 | return (getSizeInternal(name)); |
329 | 0 | } |
330 | | |
331 | | size_t |
332 | 0 | StatsMgr::getSizeInternal(const string& name) const { |
333 | 0 | ObservationPtr obs = getObservationInternal(name); |
334 | 0 | if (obs) { |
335 | 0 | return (obs->getSize()); |
336 | 0 | } |
337 | 0 | return (0); |
338 | 0 | } |
339 | | |
340 | | size_t |
341 | 0 | StatsMgr::count() const { |
342 | 0 | MultiThreadingLock lock(*mutex_); |
343 | 0 | return (countInternal()); |
344 | 0 | } |
345 | | |
346 | | size_t |
347 | 0 | StatsMgr::countInternal() const { |
348 | 0 | return (global_->size()); |
349 | 0 | } |
350 | | |
351 | | ConstElementPtr |
352 | | StatsMgr::statisticSetMaxSampleAgeHandler(const string& /*name*/, |
353 | 0 | const ConstElementPtr& params) { |
354 | 0 | string name, error; |
355 | 0 | StatsDuration duration; |
356 | 0 | if (!StatsMgr::getStatName(params, name, error)) { |
357 | 0 | return (createAnswer(CONTROL_RESULT_ERROR, error)); |
358 | 0 | } |
359 | 0 | if (!StatsMgr::getStatDuration(params, duration, error)) { |
360 | 0 | return (createAnswer(CONTROL_RESULT_ERROR, error)); |
361 | 0 | } |
362 | 0 | if (StatsMgr::instance().setMaxSampleAge(name, duration)) { |
363 | 0 | return (createAnswer(CONTROL_RESULT_SUCCESS, |
364 | 0 | "Statistic '" + name + "' duration limit is set.")); |
365 | 0 | } else { |
366 | 0 | return (createAnswer(CONTROL_RESULT_ERROR, |
367 | 0 | "No '" + name + "' statistic found")); |
368 | 0 | } |
369 | 0 | } |
370 | | |
371 | | ConstElementPtr |
372 | | StatsMgr::statisticSetMaxSampleCountHandler(const string& /*name*/, |
373 | 0 | const ConstElementPtr& params) { |
374 | 0 | string name, error; |
375 | 0 | uint32_t max_samples; |
376 | 0 | if (!StatsMgr::getStatName(params, name, error)) { |
377 | 0 | return (createAnswer(CONTROL_RESULT_ERROR, error)); |
378 | 0 | } |
379 | 0 | if (!StatsMgr::getStatMaxSamples(params, max_samples, error)) { |
380 | 0 | return (createAnswer(CONTROL_RESULT_ERROR, error)); |
381 | 0 | } |
382 | 0 | if (StatsMgr::instance().setMaxSampleCount(name, max_samples)) { |
383 | 0 | return (createAnswer(CONTROL_RESULT_SUCCESS, |
384 | 0 | "Statistic '" + name + "' count limit is set.")); |
385 | 0 | } else { |
386 | 0 | return (createAnswer(CONTROL_RESULT_ERROR, |
387 | 0 | "No '" + name + "' statistic found")); |
388 | 0 | } |
389 | 0 | } |
390 | | |
391 | | ConstElementPtr |
392 | | StatsMgr::statisticGetHandler(const string& /*name*/, |
393 | 0 | const ConstElementPtr& params) { |
394 | 0 | string name, error; |
395 | 0 | if (!StatsMgr::getStatName(params, name, error)) { |
396 | 0 | return (createAnswer(CONTROL_RESULT_ERROR, error)); |
397 | 0 | } |
398 | 0 | return (createAnswer(CONTROL_RESULT_SUCCESS, |
399 | 0 | StatsMgr::instance().get(name))); |
400 | 0 | } |
401 | | |
402 | | ConstElementPtr |
403 | | StatsMgr::statisticResetHandler(const string& /*name*/, |
404 | 1 | const ConstElementPtr& params) { |
405 | 1 | string name, error; |
406 | 1 | if (!StatsMgr::getStatName(params, name, error)) { |
407 | 1 | return (createAnswer(CONTROL_RESULT_ERROR, error)); |
408 | 1 | } |
409 | 0 | if (StatsMgr::instance().reset(name)) { |
410 | 0 | return (createAnswer(CONTROL_RESULT_SUCCESS, |
411 | 0 | "Statistic '" + name + "' reset.")); |
412 | 0 | } else { |
413 | 0 | return (createAnswer(CONTROL_RESULT_ERROR, |
414 | 0 | "No '" + name + "' statistic found")); |
415 | 0 | } |
416 | 0 | } |
417 | | |
418 | | ConstElementPtr |
419 | | StatsMgr::statisticRemoveHandler(const string& /*name*/, |
420 | 0 | const ConstElementPtr& params) { |
421 | 0 | string name, error; |
422 | 0 | if (!StatsMgr::getStatName(params, name, error)) { |
423 | 0 | return (createAnswer(CONTROL_RESULT_ERROR, error)); |
424 | 0 | } |
425 | 0 | if (StatsMgr::instance().del(name)) { |
426 | 0 | return (createAnswer(CONTROL_RESULT_SUCCESS, |
427 | 0 | "Statistic '" + name + "' removed.")); |
428 | 0 | } else { |
429 | 0 | return (createAnswer(CONTROL_RESULT_ERROR, |
430 | 0 | "No '" + name + "' statistic found")); |
431 | 0 | } |
432 | |
|
433 | 0 | } |
434 | | |
435 | | ConstElementPtr |
436 | | StatsMgr::statisticRemoveAllHandler(const string& /*name*/, |
437 | 0 | const ConstElementPtr& /*params*/) { |
438 | 0 | StatsMgr::instance().removeAll(); |
439 | 0 | return (createAnswer(CONTROL_RESULT_SUCCESS, |
440 | 0 | "Warning: statistic-remove-all command is deprecated." |
441 | 0 | " All statistics removed.")); |
442 | 0 | } |
443 | | |
444 | | ConstElementPtr |
445 | | StatsMgr::statisticGetAllHandler(const string& /*name*/, |
446 | 0 | const ConstElementPtr& /*params*/) { |
447 | 0 | ConstElementPtr all_stats = StatsMgr::instance().getAll(); |
448 | 0 | return (createAnswer(CONTROL_RESULT_SUCCESS, all_stats)); |
449 | 0 | } |
450 | | |
451 | | ConstElementPtr |
452 | | StatsMgr::statisticGlobalGetAllHandler(const string& /*name*/, |
453 | 0 | const ConstElementPtr& /*params*/) { |
454 | 0 | ConstElementPtr all_stats = StatsMgr::instance().getAllGlobal(); |
455 | 0 | return (createAnswer(CONTROL_RESULT_SUCCESS, all_stats)); |
456 | 0 | } |
457 | | |
458 | | ConstElementPtr |
459 | | StatsMgr::statisticResetAllHandler(const string& /*name*/, |
460 | 0 | const ConstElementPtr& /*params*/) { |
461 | 0 | StatsMgr::instance().resetAll(); |
462 | 0 | return (createAnswer(CONTROL_RESULT_SUCCESS, |
463 | 0 | "All statistics reset to neutral values.")); |
464 | 0 | } |
465 | | |
466 | | ConstElementPtr |
467 | 0 | StatsMgr::statisticSetMaxSampleAgeAllHandler(const ConstElementPtr& params) { |
468 | 0 | string error; |
469 | 0 | StatsDuration duration; |
470 | 0 | if (!StatsMgr::getStatDuration(params, duration, error)) { |
471 | 0 | return (createAnswer(CONTROL_RESULT_ERROR, error)); |
472 | 0 | } |
473 | 0 | MultiThreadingLock lock(*mutex_); |
474 | 0 | StatsMgr::instance().setMaxSampleCountDefaultInternal(0); |
475 | 0 | StatsMgr::instance().setMaxSampleAgeDefaultInternal(duration); |
476 | 0 | StatsMgr::instance().setMaxSampleAgeAllInternal(duration); |
477 | 0 | return (createAnswer(CONTROL_RESULT_SUCCESS, |
478 | 0 | "All statistics duration limit are set.")); |
479 | 0 | } |
480 | | |
481 | | ConstElementPtr |
482 | 0 | StatsMgr::statisticSetMaxSampleCountAllHandler(const ConstElementPtr& params) { |
483 | 0 | string error; |
484 | 0 | uint32_t max_samples; |
485 | 0 | if (!StatsMgr::getStatMaxSamples(params, max_samples, error)) { |
486 | 0 | return (createAnswer(CONTROL_RESULT_ERROR, error)); |
487 | 0 | } |
488 | 0 | if (max_samples == 0) { |
489 | 0 | error = "'max-samples' parameter must not be zero"; |
490 | 0 | return (createAnswer(CONTROL_RESULT_ERROR, error)); |
491 | 0 | } |
492 | 0 | MultiThreadingLock lock(*mutex_); |
493 | 0 | StatsMgr::instance().setMaxSampleCountDefaultInternal(max_samples); |
494 | 0 | StatsMgr::instance().setMaxSampleCountAllInternal(max_samples); |
495 | 0 | return (createAnswer(CONTROL_RESULT_SUCCESS, |
496 | 0 | "All statistics count limit are set.")); |
497 | 0 | } |
498 | | |
499 | | bool |
500 | | StatsMgr::getStatName(const ConstElementPtr& params, |
501 | | string& name, |
502 | 1 | string& reason) { |
503 | 1 | if (!params) { |
504 | 1 | reason = "Missing mandatory 'name' parameter."; |
505 | 1 | return (false); |
506 | 1 | } |
507 | 0 | ConstElementPtr stat_name = params->get("name"); |
508 | 0 | if (!stat_name) { |
509 | 0 | reason = "Missing mandatory 'name' parameter."; |
510 | 0 | return (false); |
511 | 0 | } |
512 | 0 | if (stat_name->getType() != Element::string) { |
513 | 0 | reason = "'name' parameter expected to be a string."; |
514 | 0 | return (false); |
515 | 0 | } |
516 | 0 | name = stat_name->stringValue(); |
517 | 0 | return (true); |
518 | 0 | } |
519 | | |
520 | | bool |
521 | | StatsMgr::getStatDuration(const ConstElementPtr& params, |
522 | | StatsDuration& duration, |
523 | 0 | string& reason) { |
524 | 0 | if (!params) { |
525 | 0 | reason = "Missing mandatory 'duration' parameter."; |
526 | 0 | return (false); |
527 | 0 | } |
528 | 0 | ConstElementPtr stat_duration = params->get("duration"); |
529 | 0 | if (!stat_duration) { |
530 | 0 | reason = "Missing mandatory 'duration' parameter."; |
531 | 0 | return (false); |
532 | 0 | } |
533 | 0 | duration = std::chrono::seconds(stat_duration->intValue()); |
534 | 0 | return (true); |
535 | 0 | } |
536 | | |
537 | | bool |
538 | | StatsMgr::getStatMaxSamples(const ConstElementPtr& params, |
539 | | uint32_t& max_samples, |
540 | 0 | string& reason) { |
541 | 0 | if (!params) { |
542 | 0 | reason = "Missing mandatory 'max-samples' parameter."; |
543 | 0 | return (false); |
544 | 0 | } |
545 | 0 | ConstElementPtr stat_max_samples = params->get("max-samples"); |
546 | 0 | if (!stat_max_samples) { |
547 | 0 | reason = "Missing mandatory 'max-samples' parameter."; |
548 | 0 | return (false); |
549 | 0 | } |
550 | 0 | if (stat_max_samples->getType() != Element::integer) { |
551 | 0 | reason = "'max-samples' parameter expected to be an integer."; |
552 | 0 | return (false); |
553 | 0 | } |
554 | 0 | max_samples = stat_max_samples->intValue(); |
555 | 0 | return (true); |
556 | 0 | } |
557 | | |
558 | | } // end of namespace stats |
559 | | } // end of namespace isc |