Browse Source

[3793] StatsMgr implementation added.

Tomek Mrugalski 10 years ago
parent
commit
2b01685208
2 changed files with 202 additions and 10 deletions
  1. 148 0
      src/lib/stats/stats_mgr.cc
  2. 54 10
      src/lib/stats/stats_mgr.h

+ 148 - 0
src/lib/stats/stats_mgr.cc

@@ -0,0 +1,148 @@
+// 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.
+
+#include <exceptions/exceptions.h>
+#include <stats/stats_mgr.h>
+
+using namespace std;
+
+namespace isc {
+namespace stats {
+
+StatsMgr& StatsMgr::instance() {
+    static StatsMgr stats_mgr;
+    return (stats_mgr);
+}
+
+StatsMgr::StatsMgr()
+    :global_(new StatContext()) {
+
+}
+
+void StatsMgr::setValue(const std::string& name, uint64_t value) {
+    setValueInternal(name, value);
+}
+
+void StatsMgr::setValue(const std::string& name, double value) {
+    setValueInternal(name, value);
+}
+
+void StatsMgr::setValue(const std::string& name, StatsDuration value) {
+    setValueInternal(name, value);
+}
+void StatsMgr::setValue(const std::string& name, const std::string& value) {
+    setValueInternal(name, value);
+}
+
+void StatsMgr::addValue(const std::string& name, uint64_t value) {
+    addValueInternal(name, value);
+}
+
+void StatsMgr::addValue(const std::string& name, double value) {
+    addValueInternal(name, value);
+}
+
+void StatsMgr::addValue(const std::string& name, StatsDuration value) {
+    addValueInternal(name, value);
+}
+
+void StatsMgr::addValue(const std::string& name, const std::string& value) {
+    addValueInternal(name, value);
+}
+
+ObservationPtr StatsMgr::getObservation(const std::string& name) const {
+    /// @todo: Implement contexts.
+    // Currently we keep everyting is a global context.
+    return (global_->get(name));
+}
+
+void StatsMgr::addObservation(const ObservationPtr& stat) {
+    /// @todo: Implement contexts.
+    // Currently we keep everyting is a global context.
+    return (global_->add(stat));
+}
+
+bool StatsMgr::deleteObservation(const std::string& name) {
+    /// @todo: Implement contexts.
+    // Currently we keep everyting is a global context.
+    return (global_->del(name));
+}
+
+void StatsMgr::setMaxSampleAge(const std::string& ,
+                               boost::posix_time::time_duration) {
+    isc_throw(NotImplemented, "setMaxSampleAge not implemented");
+}
+
+void StatsMgr::setMaxSampleCount(const std::string& , uint32_t){
+    isc_throw(NotImplemented, "setMaxSampleCount not implemented");
+}
+
+bool StatsMgr::reset(const std::string& name) {
+    ObservationPtr obs = getObservation(name);
+    if (obs) {
+        obs->reset();
+        return (true);
+    } else {
+        return (false);
+    }
+}
+
+bool StatsMgr::del(const std::string& name) {
+    return (global_->del(name));
+}
+
+void StatsMgr::removeAll() {
+    global_->stats_.clear();
+}
+
+isc::data::ConstElementPtr StatsMgr::get(const std::string& name) const {
+    isc::data::ElementPtr response = isc::data::Element::createMap(); // a map
+    ObservationPtr obs = getObservation(name);
+    if (obs) {
+        response->set(name, obs->getJSON()); // that contains the observation
+    }
+    return (response);
+}
+
+isc::data::ConstElementPtr StatsMgr::getAll() const {
+    isc::data::ElementPtr map = isc::data::Element::createMap(); // a map
+
+    // Let's iterate over all stored statistics...
+    for (std::map<std::string, ObservationPtr>::iterator s = global_->stats_.begin();
+         s != global_->stats_.end(); ++s) {
+
+        // ... and add each of them to the map.
+        map->set(s->first, s->second->getJSON());
+    }
+    return (map);
+}
+
+void StatsMgr::resetAll() {
+    // Let's iterate over all stored statistics...
+    for (std::map<std::string, ObservationPtr>::iterator s = global_->stats_.begin();
+         s != global_->stats_.end(); ++s) {
+
+        // ... and reset each statistic.
+        s->second->reset();
+    }
+}
+
+size_t StatsMgr::count() const {
+    return (global_->stats_.size());
+}
+
+
+
+};
+};

+ 54 - 10
src/lib/stats/stats_mgr.h

@@ -29,6 +29,7 @@ namespace stats {
 class StatsMgr : public boost::noncopyable {
 class StatsMgr : public boost::noncopyable {
  public:
  public:
 
 
+    /// @brief Statistics Manager accessor method.
     static StatsMgr& instance();
     static StatsMgr& instance();
 
 
     // methods used data producers
     // methods used data producers
@@ -36,9 +37,9 @@ class StatsMgr : public boost::noncopyable {
     void addValue(const std::string& name, double value);
     void addValue(const std::string& name, double value);
     void addValue(const std::string& name, StatsDuration time);
     void addValue(const std::string& name, StatsDuration time);
     void addValue(const std::string& name, const std::string& value);
     void addValue(const std::string& name, const std::string& value);
-    void setValue(const std::string& name, uint64_t value = 1);
-    void setValue(const std::string& name, double value = 1.0f);
-    void setValue(const std::string& name, StatsDuration time);
+    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);
     void setValue(const std::string& name, const std::string& value);
     void setValue(const std::string& name, const std::string& value);
 
 
     /// @brief determines whether a given statistic is kept as a single value
     /// @brief determines whether a given statistic is kept as a single value
@@ -83,7 +84,7 @@ class StatsMgr : public boost::noncopyable {
     /// @brief Removes specified statistic.
     /// @brief Removes specified statistic.
     /// @param name name of the statistic to be removed.
     /// @param name name of the statistic to be removed.
     /// @return true if successful, false if there's no such statistic
     /// @return true if successful, false if there's no such statistic
-    bool remove(const std::string& name);
+    bool del(const std::string& name);
 
 
     /// @brief Resets all collected statistics back to zero.
     /// @brief Resets all collected statistics back to zero.
     void resetAll();
     void resetAll();
@@ -93,26 +94,69 @@ class StatsMgr : public boost::noncopyable {
 
 
     /// @brief Returns number of available statistics.
     /// @brief Returns number of available statistics.
     /// @return number of recorded statistics.
     /// @return number of recorded statistics.
-    size_t count();
+    size_t count() const;
 
 
     /// @brief Returns a single statistic as a JSON structure
     /// @brief Returns a single statistic as a JSON structure
     /// @return JSON structures representing a single statistic
     /// @return JSON structures representing a single statistic
-    isc::data::ConstElementPtr get(const std::string& name);
+    isc::data::ConstElementPtr get(const std::string& name) const;
 
 
     /// @brief Returns all statistics as a JSON structure
     /// @brief Returns all statistics as a JSON structure
     /// @return JSON structures representing all statistics
     /// @return JSON structures representing all statistics
-    isc::data::ConstElementPtr getAll();
+    isc::data::ConstElementPtr getAll() const;
 
 
     /// @brief Returns an observation
     /// @brief Returns an observation
     ///
     ///
     /// Used in testing only. Production code should use @ref get() method.
     /// Used in testing only. Production code should use @ref get() method.
     /// @param name name of the statistic
     /// @param name name of the statistic
     /// @return Pointer to the Observation object
     /// @return Pointer to the Observation object
-    ObservationPtr getObservation(const std::string& name);
+    ObservationPtr getObservation(const std::string& name) const;
 
 
  private:
  private:
-    /// @brief returns a context for specified name
-    StatContextPtr getContext(const std::string& name);
+
+    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);
 
 
     // This is a global context. All stats will initially be stored here.
     // This is a global context. All stats will initially be stored here.
     StatContextPtr global_;
     StatContextPtr global_;