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 #ifndef STATSMGR_H
8 #define STATSMGR_H
9 
10 #include <stats/observation.h>
11 #include <stats/context.h>
12 #include <boost/noncopyable.hpp>
13 #include <boost/scoped_ptr.hpp>
14 
15 #include <map>
16 #include <mutex>
17 #include <string>
18 #include <vector>
19 #include <sstream>
20 
21 namespace isc {
22 namespace stats {
23 
24 /// @brief Statistics Manager class
25 ///
26 /// StatsMgr is a singleton class that represents a subsystem that manages
27 /// collection, storage and reporting of various types of statistics.
28 /// It is also the intended API for both core code and hooks.
29 ///
30 /// As of May 2015, Tomek ran performance benchmarks (see unit-tests in
31 /// stats_mgr_unittest.cc with performance in their names) and it seems
32 /// the code is able to register ~2.5-3 million observations per second, even
33 /// with 1000 different statistics recorded. That seems sufficient for now,
34 /// so there is no immediate need to develop any multi-threading solutions
35 /// for now. However, should this decision be revised in the future, the
36 /// best place for it would to be modify @ref addObservation method here.
37 /// It's the common code point that all new observations must pass through.
38 /// One possible way to enable multi-threading would be to run a separate
39 /// thread handling collection. The main thread would call @ref addValue and
40 /// @ref setValue methods that would end up calling @ref addObservation.
41 /// That method would pass the data to separate thread to be collected and
42 /// would immediately return. Further processing would be mostly as it
43 /// is today, except happening in a separate thread. One unsolved issue in
44 /// this approach is how to extract data, but that will remain unsolvable
45 /// until we get the control socket implementation.
46 ///
47 /// Statistics Manager does not use logging by design. The reasons are:
48 /// - performance impact (logging every observation would degrade performance
49 ///   significantly. While it's possible to log on sufficiently high debug
50 ///   level, such a log would be not that useful)
51 /// - dependency (statistics are intended to be a lightweight library, adding
52 ///   dependency on libkea-log, which has its own dependencies, including
53 ///   external log4cplus, is against 'lightweight' design)
54 /// - if logging of specific statistics is warranted, it is recommended to
55 ///   add log entries in the code that calls StatsMgr.
56 /// - enabling logging in StatsMgr does not offer fine tuning. It would be
57 ///   either all or nothing. Adding logging entries only when necessary
58 ///   in the code that uses StatsMgr gives better granularity.
59 ///
60 /// If this decision is revisited in the future, the most universal places
61 /// for adding logging have been marked in @ref addValueInternal and
62 /// @ref setValueInternal.
63 class StatsMgr : public boost::noncopyable {
64 public:
65 
66     /// @brief Statistics Manager accessor method.
67     static StatsMgr& instance();
68 
69     /// @defgroup producer_methods Methods are used by data producers.
70     ///
71     /// @brief The following methods are used by data producers:
72     ///
73     /// @{
74 
75     /// @brief Records absolute integer observation.
76     ///
77     /// @param name name of the observation
78     /// @param value integer value observed
79     /// @throw InvalidStatType if statistic is not integer
80     void setValue(const std::string& name, const int64_t value);
81 
82     /// @brief Records absolute floating point observation.
83     ///
84     /// @param name name of the observation
85     /// @param value floating point value observed
86     /// @throw InvalidStatType if statistic is not fp
87     void setValue(const std::string& name, const double value);
88 
89     /// @brief Records absolute duration observation.
90     ///
91     /// @param name name of the observation
92     /// @param value duration value observed
93     /// @throw InvalidStatType if statistic is not time duration
94     void setValue(const std::string& name, const StatsDuration& value);
95 
96     /// @brief Records absolute string observation.
97     ///
98     /// @param name name of the observation
99     /// @param value string value observed
100     /// @throw InvalidStatType if statistic is not a string
101     void setValue(const std::string& name, const std::string& value);
102 
103     /// @brief Records incremental integer observation.
104     ///
105     /// @param name name of the observation
106     /// @param value integer value observed
107     /// @throw InvalidStatType if statistic is not integer
108     void addValue(const std::string& name, const int64_t value);
109 
110     /// @brief Records incremental floating point observation.
111     ///
112     /// @param name name of the observation
113     /// @param value floating point value observed
114     /// @throw InvalidStatType if statistic is not fp
115     void addValue(const std::string& name, const double value);
116 
117     /// @brief Records incremental duration observation.
118     ///
119     /// @param name name of the observation
120     /// @param value duration value observed
121     /// @throw InvalidStatType if statistic is not time duration
122     void addValue(const std::string& name, const StatsDuration& value);
123 
124     /// @brief Records incremental string observation.
125     ///
126     /// @param name name of the observation
127     /// @param value string value observed
128     /// @throw InvalidStatType if statistic is not a string
129     void addValue(const std::string& name, const std::string& value);
130 
131     /// @brief Determines maximum age of samples.
132     ///
133     /// Specifies that statistic name should be stored not as a single value,
134     /// but rather as a set of values. duration determines the timespan.
135     /// Samples older than duration will be discarded. This is time-constrained
136     /// approach. For sample count constrained approach, see @ref
137     /// setMaxSampleCount() below.
138     /// Example:
139     /// To set a statistic to keep observations for the last 5 minutes, call:
140     /// setMaxSampleAge("incoming-packets", StatsDuration::minutes(5));
141     /// to revert statistic to a single value, call:
142     /// setMaxSampleAge("incoming-packets", StatsDuration:zero());
143     ///
144     /// @param name name of the observation
145     /// @param duration determines maximum age of samples
146     /// @return true if successful, false if there's no such statistic
147     bool setMaxSampleAge(const std::string& name, const StatsDuration& duration);
148 
149     /// @brief Determines how many samples of a given statistic should be kept.
150     ///
151     /// Specifies that statistic name should be stored not as single value, but
152     /// rather as a set of values. In this form, at most max_samples will be kept.
153     /// When adding max_samples + 1 sample, the oldest sample will be discarded.
154     /// Example:
155     /// To set a statistic to keep the last 100 observations, call:
156     /// setMaxSampleCount("incoming-packets", 100);
157     ///
158     /// @param name name of the observation
159     /// @param max_samples how many samples of a given statistic should be kept
160     /// @return true if successful, false if there's no such statistic
161     bool setMaxSampleCount(const std::string& name, uint32_t max_samples);
162 
163     /// @brief Set duration limit for all collected statistics.
164     ///
165     /// @param duration determines maximum age of samples
166     void setMaxSampleAgeAll(const StatsDuration& duration);
167 
168     /// @brief Set count limit for all collected statistics.
169     ///
170     /// @param max_samples how many samples of a given statistic should be kept
171     void setMaxSampleCountAll(uint32_t max_samples);
172 
173     /// @brief Set default duration limit.
174     ///
175     /// @param duration default maximum age of samples to keep
176     void setMaxSampleAgeDefault(const StatsDuration& duration);
177 
178     /// @brief Set default count limit.
179     ///
180     /// @param max_samples default maximum number of samples to keep
181     /// (0 means to disable count limit and enable age limit)
182     void setMaxSampleCountDefault(uint32_t max_samples);
183 
184     /// @brief Get default duration limit.
185     ///
186     /// @return default maximum age of samples to keep.
187     const StatsDuration& getMaxSampleAgeDefault() const;
188 
189     /// @brief Get default count limit.
190     ///
191     /// @return default maximum number of samples to keep.
192     /// (0 means that count limit was disabled)
193     uint32_t getMaxSampleCountDefault() const;
194 
195     /// @}
196 
197     /// @defgroup consumer_methods Methods are used by data consumers.
198     ///
199     /// @brief The following methods are used by data consumers:
200     ///
201     /// @{
202 
203     /// @brief Resets specified statistic.
204     ///
205     /// This is a convenience function and is equivalent to setValue(name,
206     /// neutral_value), where neutral_value is 0, 0.0 or "".
207     ///
208     /// @param name name of the statistic to be reset.
209     /// @return true if successful, false if there's no such statistic
210     bool reset(const std::string& name);
211 
212     /// @brief Removes specified statistic.
213     ///
214     /// @param name name of the statistic to be removed.
215     /// @return true if successful, false if there's no such statistic
216     bool del(const std::string& name);
217 
218     /// @brief Resets all collected statistics back to zero.
219     void resetAll();
220 
221     /// @brief Removes all collected statistics.
222     /// @note This command was deprecated.
223     void removeAll();
224 
225     /// @brief Returns size of specified statistic.
226     ///
227     /// @param name name of the statistic which size should be return.
228     /// @return size of specified statistic, 0 means lack of given statistic.
229     size_t getSize(const std::string& name) const;
230 
231     /// @brief Returns number of available statistics.
232     ///
233     /// @return number of recorded statistics.
234     size_t count() const;
235 
236     /// @brief Returns a single statistic as a JSON structure.
237     ///
238     /// @return JSON structures representing a single statistic
239     isc::data::ConstElementPtr get(const std::string& name) const;
240 
241     /// @brief Returns all statistics as a JSON structure.
242     ///
243     /// @return JSON structures representing all statistics
244     isc::data::ConstElementPtr getAll() const;
245 
246     /// @}
247 
248     /// @brief Returns an observation.
249     ///
250     /// Used in testing only. Production code should use @ref get() method
251     /// when the value is dereferenced.
252     /// Calls @ref getObservationInternal() method in a thread safe context.
253     ///
254     /// @param name name of the statistic
255     /// @return Pointer to the Observation object
256     ObservationPtr getObservation(const std::string& name) const;
257 
258     /// @brief Returns an observation in a thread safe context.
259     ///
260     /// Used in testing only. Production code should use @ref get() method
261     /// when the value is dereferenced. Should be called in a thread safe context.
262     ///
263     /// @param name name of the statistic
264     /// @return Pointer to the Observation object
265     ObservationPtr getObservationInternal(const std::string& name) const;
266 
267     /// @brief Generates statistic name in a given context
268     ///
269     /// Example:
270     /// @code
271     /// generateName("subnet", 123, "received-packets");
272     /// @endcode
273     /// will return subnet[123].received-packets. Any printable type
274     /// can be used as index.
275     ///
276     /// @tparam Type any type that can be used to index contexts
277     /// @param context name of the context (e.g. 'subnet')
278     /// @param index value used for indexing contexts (e.g. subnet_id)
279     /// @param stat_name name of the statistic
280     /// @return returns full statistic name in form context[index].stat_name
281     template<typename Type>
generateName(const std::string & context,Type index,const std::string & stat_name)282     static std::string generateName(const std::string& context, Type index,
283                                     const std::string& stat_name) {
284         std::stringstream name;
285         name << context << "[" << index << "]." << stat_name;
286         return (name.str());
287     }
288 
289     /// @defgroup command_methods Methods are used to handle commands.
290     ///
291     /// @brief The following methods are used to handle commands:
292     ///
293     /// @{
294 
295     /// @brief Handles statistic-get command
296     ///
297     /// This method handles statistic-get command, which returns value
298     /// of a given statistic). It expects one parameter stored in params map:
299     /// name: name of the statistic
300     ///
301     /// Example params structure:
302     /// {
303     ///     "name": "packets-received"
304     /// }
305     ///
306     /// @param name name of the command (ignored, should be "statistic-get")
307     /// @param params structure containing a map that contains "name"
308     /// @return answer containing details of specified statistic
309     static isc::data::ConstElementPtr
310     statisticGetHandler(const std::string& name,
311                         const isc::data::ConstElementPtr& params);
312 
313     /// @brief Handles statistic-reset command
314     ///
315     /// This method handles statistic-reset command, which resets value
316     /// of a given statistic. It expects one parameter stored in params map:
317     /// name: name of the statistic
318     ///
319     /// Example params structure:
320     /// {
321     ///     "name": "packets-received"
322     /// }
323     ///
324     /// @param name name of the command (ignored, should be "statistic-reset")
325     /// @param params structure containing a map that contains "name"
326     /// @return answer containing confirmation
327     static isc::data::ConstElementPtr
328     statisticResetHandler(const std::string& name,
329                           const isc::data::ConstElementPtr& params);
330 
331     /// @brief Handles statistic-remove command
332     ///
333     /// This method handles statistic-reset command, which removes a given
334     /// statistic completely. It expects one parameter stored in params map:
335     /// name: name of the statistic
336     ///
337     /// Example params structure:
338     /// {
339     ///     "name": "packets-received"
340     /// }
341     ///
342     /// @param name name of the command (ignored, should be "statistic-remove")
343     /// @param params structure containing a map that contains "name" element
344     /// @return answer containing confirmation
345     static isc::data::ConstElementPtr
346     statisticRemoveHandler(const std::string& name,
347                            const isc::data::ConstElementPtr& params);
348 
349     /// @brief Handles statistic-sample-age-set command
350     ///
351     /// This method handles statistic-sample-age-set command,
352     /// which sets max_sample_age_ limit of a given statistic
353     /// and leaves max_sample_count_ disabled.
354     /// It expects two parameters stored in params map:
355     /// name: name of the statistic
356     /// duration: time limit expressed as a number of seconds
357     ///
358     /// Example params structure:
359     /// {
360     ///     "name": "packets-received",
361     ///     "duration": 1245
362     /// }
363     ///
364     /// @param name name of the command (ignored, should be "statistic-sample-age-set")
365     /// @param params structure containing a map that contains "name" and "duration"
366     /// @return answer containing information about successfully setup limit of statistic
367     static isc::data::ConstElementPtr
368     statisticSetMaxSampleAgeHandler(const std::string& name,
369                                     const isc::data::ConstElementPtr& params);
370 
371     /// @brief Handles statistic-sample-count-set command
372     ///
373     /// This method handles statistic-sample-count-set command,
374     /// which sets max_sample_count_ limit of a given statistic
375     /// and leaves max_sample_age_ disabled.
376     /// It expects two parameters stored in params map:
377     /// name: name of the statistic
378     /// max-samples: count limit
379     ///
380     /// Example params structure:
381     /// {
382     ///     "name": "packets-received",
383     ///     "max-samples": 15
384     /// }
385     ///
386     /// @param name name of the command (ignored, should be "statistic-sample-count-set")
387     /// @param params structure containing a map that contains "name" and "max-samples"
388     /// @return answer containing information about successfully setup limit of statistic
389     static isc::data::ConstElementPtr
390     statisticSetMaxSampleCountHandler(const std::string& name,
391                                       const isc::data::ConstElementPtr& params);
392 
393     /// @brief Handles statistic-get-all command
394     ///
395     /// This method handles statistic-get-all command, which returns values
396     /// of all statistics. Params parameter is ignored.
397     ///
398     /// @param name name of the command (ignored, should be "statistic-get-all")
399     /// @param params ignored
400     /// @return answer containing values of all statistic
401     static isc::data::ConstElementPtr
402     statisticGetAllHandler(const std::string& name,
403                            const isc::data::ConstElementPtr& params);
404 
405     /// @brief Handles statistic-reset-all command
406     ///
407     /// This method handles statistic-reset-all command, which sets values of
408     /// all statistics back to zero. Params parameter is ignored.
409     ///
410     /// @param name name of the command (ignored, should be "statistic-reset-all")
411     /// @param params ignored
412     /// @return answer confirming success of this operation
413     static isc::data::ConstElementPtr
414     statisticResetAllHandler(const std::string& name,
415                              const isc::data::ConstElementPtr& params);
416 
417     /// @brief Handles statistic-remove-all command
418     ///
419     /// @note The statistic-remove-all command was deprecated.
420     ///
421     /// This method handles statistic-remove-all command, which removes all
422     /// statistics. Params parameter is ignored.
423     ///
424     /// @param name name of the command (ignored, should be "statistic-remove-all")
425     /// @param params ignored
426     /// @return answer confirming success of this operation
427     static isc::data::ConstElementPtr
428     statisticRemoveAllHandler(const std::string& name,
429                               const isc::data::ConstElementPtr& params);
430 
431     /// @brief Handles statistic-sample-age-set-all command
432     ///
433     /// This method handles statistic-sample-age-set-all command,
434     /// which sets max_sample_age_ limit to all statistics and the default.
435     /// It expects one parameter stored in params map:
436     /// duration: limit expressed as a number of seconds
437     ///
438     /// Example params structure:
439     /// {
440     ///     "duration": 1245
441     /// }
442     ///
443     /// @param params structure containing a map that contains "duration"
444     /// @return answer confirming success of this operation
445     isc::data::ConstElementPtr
446     statisticSetMaxSampleAgeAllHandler(const isc::data::ConstElementPtr& params);
447 
448     /// @brief Handles statistic-sample-count-set-all command
449     ///
450     /// This method handles statistic-sample-count-set-all command,
451     /// which sets max_sample_count_ limit of all statistics and the default.
452     /// It expects one parameter stored in params map:
453     /// max-samples: count limit
454     /// The value 0 is out of range.
455     ///
456     /// Example params structure:
457     /// {
458     ///     "max-samples": 15
459     /// }
460     ///
461     /// @param params structure containing a map that contains "max-samples"
462     /// @return answer confirming success of this operation
463     isc::data::ConstElementPtr
464     statisticSetMaxSampleCountAllHandler(const isc::data::ConstElementPtr& params);
465 
466     /// @}
467 
468 private:
469 
470     /// @private
471 
472     /// @brief Private constructor.
473     ///
474     /// StatsMgr is a singleton. It should be accessed using @ref instance
475     /// method.
476     StatsMgr();
477 
478     /// @public
479 
480     /// @brief Sets a given statistic to specified value (internal version).
481     ///
482     /// This template method sets statistic identified by name to a value
483     /// specified by value. This internal method is used by public @ref setValue
484     /// methods.
485     ///
486     /// @tparam DataType one of int64_t, double, StatsDuration or string
487     /// @param name name of the statistic
488     /// @param value specified statistic will be set to this value
489     /// @throw InvalidStatType is statistic exists and has a different type.
490     template<typename DataType>
setValueInternal(const std::string & name,DataType value)491     void setValueInternal(const std::string& name, DataType value) {
492         // If we want to log each observation, here would be the best place for it.
493         ObservationPtr stat = getObservationInternal(name);
494         if (stat) {
495             stat->setValue(value);
496         } else {
497             stat.reset(new Observation(name, value));
498             addObservationInternal(stat);
499         }
500     }
501 
502     /// @public
503 
504     /// @brief Adds specified value to a given statistic (internal version).
505     ///
506     /// This template method adds specified value to a given statistic (identified
507     /// by name to a value). This internal method is used by public @ref setValue
508     /// methods.
509     ///
510     /// @tparam DataType one of int64_t, double, StatsDuration or string
511     /// @param name name of the statistic
512     /// @param value specified statistic will be set to this value
513     /// @throw InvalidStatType is statistic exists and has a different type.
514     template<typename DataType>
addValueInternal(const std::string & name,DataType value)515     void addValueInternal(const std::string& name, DataType value) {
516         // If we want to log each observation, here would be the best place for it.
517         ObservationPtr existing = getObservationInternal(name);
518         if (!existing) {
519             // We tried to add to a non-existing statistic. We can recover from
520             // that. Simply add the new incremental value as a new statistic and
521             // we're done.
522             setValueInternal(name, value);
523             return;
524         } else {
525             // Let's hope it is of correct type. If not, the underlying
526             // addValue() method will throw.
527             existing->addValue(value);
528         }
529     }
530 
531     /// @public
532 
533     /// @brief Adds a new observation.
534     ///
535     /// That's an utility method used by public @ref setValue() and
536     /// @ref addValue() methods.
537     /// Calls @ref addObservationInternal() method in a thread safe context.
538     ///
539     /// @param stat observation
540     void addObservation(const ObservationPtr& stat);
541 
542     /// @public
543 
544     /// @brief Adds a new observation in a thread safe context.
545     ///
546     /// That's an utility method used by public @ref setValue() and
547     /// @ref addValue() methods.
548     /// Should be called in a thread safe context.
549     ///
550     /// @param stat observation
551     void addObservationInternal(const ObservationPtr& stat);
552 
553     /// @private
554 
555     /// @brief Tries to delete an observation.
556     ///
557     /// Calls @ref deleteObservationInternal() method in a thread safe context.
558     ///
559     /// @param name of the statistic to be deleted
560     /// @return true if deleted, false if not found
561     bool deleteObservation(const std::string& name);
562 
563     /// @private
564 
565     /// @brief Tries to delete an observation in a thread safe context.
566     ///
567     /// Should be called in a thread safe context.
568     ///
569     /// @param name of the statistic to be deleted
570     /// @return true if deleted, false if not found
571     bool deleteObservationInternal(const std::string& name);
572 
573     /// @private
574 
575     /// @brief Determines maximum age of samples.
576     ///
577     /// Should be called in a thread safe context.
578     ///
579     /// @param name name of the observation
580     /// @param duration determines maximum age of samples
581     /// @return true if successful, false if there's no such statistic
582     bool setMaxSampleAgeInternal(const std::string& name, const StatsDuration& duration);
583 
584     /// @private
585 
586     /// @brief Determines how many samples of a given statistic should be kept.
587     ///
588     /// Should be called in a thread safe context.
589     ///
590     /// @param name name of the observation
591     /// @param max_samples how many samples of a given statistic should be kept
592     /// @return true if successful, false if there's no such statistic
593     bool setMaxSampleCountInternal(const std::string& name, uint32_t max_samples);
594 
595     /// @private
596 
597     /// @brief Set duration limit for all collected statistics.
598     ///
599     /// Should be called in a thread safe context.
600     ///
601     /// @param duration determines maximum age of samples
602     void setMaxSampleAgeAllInternal(const StatsDuration& duration);
603 
604     /// @private
605 
606     /// @brief Set count limit for all collected statistics.
607     ///
608     /// Should be called in a thread safe context.
609     ///
610     /// @param max_samples how many samples of a given statistic should be kept
611     void setMaxSampleCountAllInternal(uint32_t max_samples);
612 
613     /// @private
614 
615     /// @brief Set default duration limit.
616     ///
617     /// Should be called in a thread safe context.
618     ///
619     /// @param duration default maximum age of samples to keep.
620     void setMaxSampleAgeDefaultInternal(const StatsDuration& duration);
621 
622     /// @brief Set default count limit.
623     ///
624     /// Should be called in a thread safe context.
625     ///
626     /// @param max_samples default maximum number of samples to keep.
627     /// (0 means to disable count limit and enable age limit)
628     void setMaxSampleCountDefaultInternal(uint32_t max_samples);
629 
630     /// @private
631 
632     /// @brief Get default duration limit.
633     ///
634     /// Should be called in a thread safe context.
635     ///
636     /// @return default maximum age of samples to keep.
637     const StatsDuration& getMaxSampleAgeDefaultInternal() const;
638 
639     /// @brief Get default count limit.
640     ///
641     /// Should be called in a thread safe context.
642     ///
643     /// @return default maximum number of samples to keep.
644     /// (0 means that count limit was disabled)
645     uint32_t getMaxSampleCountDefaultInternal() const;
646 
647     /// @private
648 
649     /// @brief Resets specified statistic.
650     ///
651     /// Should be called in a thread safe context.
652     ///
653     /// @param name name of the statistic to be reset.
654     /// @return true if successful, false if there's no such statistic
655     bool resetInternal(const std::string& name);
656 
657     /// @private
658 
659     /// @brief Removes specified statistic.
660     ///
661     /// Should be called in a thread safe context.
662     ///
663     /// @param name name of the statistic to be removed.
664     /// @return true if successful, false if there's no such statistic
665     bool delInternal(const std::string& name);
666 
667     /// @private
668 
669     /// @brief Resets all collected statistics back to zero.
670     ///
671     /// Should be called in a thread safe context.
672     void resetAllInternal();
673 
674     /// @private
675 
676     /// @brief Removes all collected statistics.
677     ///
678     /// Should be called in a thread safe context.
679     void removeAllInternal();
680 
681     /// @private
682 
683     /// @brief Returns size of specified statistic.
684     ///
685     /// Should be called in a thread safe context.
686     ///
687     /// @param name name of the statistic which size should be return.
688     /// @return size of specified statistic, 0 means lack of given statistic.
689     size_t getSizeInternal(const std::string& name) const;
690 
691     /// @private
692 
693     /// @brief Returns number of available statistics.
694     ///
695     /// Should be called in a thread safe context.
696     ///
697     /// @return number of recorded statistics.
698     size_t countInternal() const;
699 
700     /// @private
701 
702     /// @brief Returns a single statistic as a JSON structure.
703     ///
704     /// Should be called in a thread safe context.
705     ///
706     /// @return JSON structures representing a single statistic
707     isc::data::ConstElementPtr getInternal(const std::string& name) const;
708 
709     /// @private
710 
711     /// @brief Returns all statistics as a JSON structure.
712     ///
713     /// Should be called in a thread safe context.
714     ///
715     /// @return JSON structures representing all statistics
716     isc::data::ConstElementPtr getAllInternal() const;
717 
718     /// @private
719 
720     /// @brief Utility method that attempts to extract statistic name
721     ///
722     /// This method attempts to extract statistic name from the params
723     /// structure. It is expected to be a map that contains 'name' element,
724     /// that is of type string. If present as expected, statistic name
725     /// set and true is returned. If missing or is of incorrect type, the reason
726     /// is specified in reason parameter and false is returned.
727     ///
728     /// @param params parameters structure received in command
729     /// @param name [out] name of the statistic (if no error detected)
730     /// @param reason [out] failure reason (if error is detected)
731     /// @return true (if everything is ok), false otherwise
732     static bool getStatName(const isc::data::ConstElementPtr& params,
733                             std::string& name,
734                             std::string& reason);
735 
736     /// @private
737 
738     /// @brief Utility method that attempts to extract duration limit for
739     /// a given statistic
740     ///
741     /// This method attempts to extract duration limit for a given statistic
742     /// from the params structure.
743     /// It is expected to be a map that contains four 'duration' elements: 'hours',
744     /// 'minutes', 'seconds' and 'milliseconds'
745     /// all are of type int. If present as expected, statistic duration
746     /// limit is set and true is returned.
747     /// If any of these four parameters is missing or is of incorrect type,
748     /// the reason is specified in reason parameter and false is returned.
749     ///
750     /// @param params parameters structure received in command
751     /// @param duration [out] duration limit for the statistic (if no error detected)
752     /// @param reason [out] failure reason (if error is detected)
753     /// @return true (if everything is ok), false otherwise
754     static bool getStatDuration(const isc::data::ConstElementPtr& params,
755                                 StatsDuration& duration,
756                                 std::string& reason);
757 
758     /// @private
759 
760     /// @brief Utility method that attempts to extract count limit for
761     /// a given statistic
762     ///
763     /// This method attempts to extract count limit for a given statistic
764     /// from the params structure.
765     /// It is expected to be a map that contains 'max-samples' element,
766     /// that is of type int. If present as expected, statistic count
767     /// limit (max_samples) is set and true is returned.
768     /// If missing or is of incorrect type, the reason is specified in reason
769     /// parameter and false is returned.
770     ///
771     /// @param params parameters structure received in command
772     /// @param max_samples [out] count limit for the statistic (if no error detected)
773     /// @param reason [out] failure reason (if error is detected)
774     /// @return true (if everything is ok), false otherwise
775     static bool getStatMaxSamples(const isc::data::ConstElementPtr& params,
776                                   uint32_t& max_samples,
777                                   std::string& reason);
778 
779     /// @brief This is a global context. All statistics will initially be stored here.
780     StatContextPtr global_;
781 
782     /// @brief The mutex used to protect internal state.
783     const boost::scoped_ptr<std::mutex> mutex_;
784 };
785 
786 }  // namespace stats
787 }  // namespace isc
788 
789 #endif // STATS_MGR
790