stats_mgr.h 6.19 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
// Copyright (C) 2015 Internet Systems Consortium, Inc. ("ISC")
//
// Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
// copyright notice and this permission notice appear in all copies.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
// AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.

#ifndef STATSMGR_H
#define STATSMGR_H

#include <stats/observation.h>
#include <stats/context.h>
#include <boost/noncopyable.hpp>

#include <map>
#include <string>
#include <vector>

namespace isc {
namespace stats {

class StatsMgr : public boost::noncopyable {
 public:

32
    /// @brief Statistics Manager accessor method.
33 34 35
    static StatsMgr& instance();

    // methods used data producers
36 37
    void addValue(const std::string& name, uint64_t value);
    void addValue(const std::string& name, double value);
38
    void addValue(const std::string& name, StatsDuration time);
39
    void addValue(const std::string& name, const std::string& value);
40 41 42
    void setValue(const std::string& name, uint64_t value);
    void setValue(const std::string& name, double value);
    void setValue(const std::string& name, StatsDuration value);
43
    void setValue(const std::string& name, const std::string& value);
44 45 46 47 48 49 50

    /// @brief determines whether a given statistic is kept as a single value
    ///        or as a number of values
    /// 
    /// Specifies that statistic name should be stored not as a single value,
    /// but rather as a set of values. duration determines the timespan.
    /// Samples older than duration will be discarded. This is time-constrained
51 52 53 54
    /// approach. For sample count constrained approach, see @ref
    /// setMaxSampleCount() below.
    ///
    /// @todo: Not implemented.
55 56
    ///
    /// Example: to set a statistic to keep observations for the last 5 minutes,
57
    /// call setMaxSampleAge("incoming-packets", time_duration(0,5,0,0));
58
    /// to revert statistic to a single value, call:
59 60 61
    /// setMaxSampleAge("incoming-packets" time_duration(0,0,0,0))
    void setMaxSampleAge(const std::string& name,
                         boost::posix_time::time_duration duration);
62 63 64 65 66 67 68

    /// @brief determines how many samples of a given statistic should be kept.
    ///
    /// Specifies that statistic name should be stored not as single value, but
    /// rather as a set of values. In this form, at most max_samples will be kept.
    /// When adding max_samples+1 sample, the oldest sample will be discarded.
    ///
69 70
    /// @todo: Not implemented.
    ///
71 72
    /// Example:
    /// To set a statistic to keep the last 100 observations, call:
73 74 75 76 77 78 79 80 81 82 83 84 85 86
    /// setMaxSampleCount("incoming-packets", 100);
    void setMaxSampleCount(const std::string& name, uint32_t max_samples);

    /// @brief Resets specified statistic.
    ///
    /// This is a convenience function and is equivalent to setValue(name,
    /// neutral_value), where neutral_value is 0, 0.0 or "".
    /// @param name name of the statistic to be reset.
    /// @return true if successful, false if there's no such statistic
    bool reset(const std::string& name);

    /// @brief Removes specified statistic.
    /// @param name name of the statistic to be removed.
    /// @return true if successful, false if there's no such statistic
87
    bool del(const std::string& name);
88

89 90
    /// @brief Resets all collected statistics back to zero.
    void resetAll();
91

92 93 94 95 96
    /// @brief Removes all collected statistics.
    void removeAll();

    /// @brief Returns number of available statistics.
    /// @return number of recorded statistics.
97
    size_t count() const;
98 99 100

    /// @brief Returns a single statistic as a JSON structure
    /// @return JSON structures representing a single statistic
101
    isc::data::ConstElementPtr get(const std::string& name) const;
102 103 104

    /// @brief Returns all statistics as a JSON structure
    /// @return JSON structures representing all statistics
105
    isc::data::ConstElementPtr getAll() const;
106 107 108 109 110 111

    /// @brief Returns an observation
    ///
    /// Used in testing only. Production code should use @ref get() method.
    /// @param name name of the statistic
    /// @return Pointer to the Observation object
112
    ObservationPtr getObservation(const std::string& name) const;
113 114

 private:
115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159

    template<typename DataType>
    void setValueInternal(const std::string& name, DataType value) {
        ObservationPtr stat = getObservation(name);
        if (stat) {
            stat->setValue(value);
        } else {
            stat.reset(new Observation(name, value));
            addObservation(stat);
        }
    }

    template<typename DataType>
    void addValueInternal(const std::string& name, DataType value) {
        ObservationPtr existing = getObservation(name);
        if (!existing) {
            // We tried to add to a non-existing statistic. We can recover from
            // that. Simply add the new incremental value as a new statistic and
            // we're done.
            setValue(name, value);
            return;
        } else {
            // Let's hope it is of correct type. If not, the underlying
            // addValue() method will throw.
            existing->addValue(value);
        }
    }

    /// @brief Private constructor
    /// StatsMgr is a singleton. It should be accessed using @ref instance
    /// method.
    StatsMgr();

    /// @brief Adds a new observation
    ///
    /// That's an utility method used by public @ref setValue() and
    /// @ref addValue() methods.
    /// @param obs observation
    void addObservation(const ObservationPtr& o);

    /// @brief Tries to delete an observation
    ///
    /// @param name of the statistic to be deleted
    /// @return true if deleted, false if not found
    bool deleteObservation(const std::string& name);
160 161 162 163 164 165 166 167 168

    // This is a global context. All stats will initially be stored here.
    StatContextPtr global_;
};

};
};

#endif // STATS_MGR