Index: statsreport/metrics.h |
diff --git a/statsreport/metrics.h b/statsreport/metrics.h |
deleted file mode 100644 |
index 360370512e3c67500189f89d2cd96a37c1419b60..0000000000000000000000000000000000000000 |
--- a/statsreport/metrics.h |
+++ /dev/null |
@@ -1,539 +0,0 @@ |
-// Copyright 2006-2009 Google Inc. |
-// |
-// Licensed under the Apache License, Version 2.0 (the "License"); |
-// you may not use this file except in compliance with the License. |
-// You may obtain a copy of the License at |
-// |
-// http://www.apache.org/licenses/LICENSE-2.0 |
-// |
-// Unless required by applicable law or agreed to in writing, software |
-// distributed under the License is distributed on an "AS IS" BASIS, |
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
-// See the License for the specific language governing permissions and |
-// limitations under the License. |
-// ======================================================================== |
-// |
-// Declares the interface to in-memory metrics capture |
-#ifndef OMAHA_STATSREPORT_METRICS_H__ |
-#define OMAHA_STATSREPORT_METRICS_H__ |
- |
-#include <iterator> |
-#include "base/basictypes.h" |
-#include "omaha/base/highres_timer-win32.h" |
-#include "omaha/base/logging/logging.h" |
- |
-/// Macros to declare & define named & typed metrics. |
-/// Put declarations in headers or in cpp files, where you need access |
-/// to the metrics. For each declared metric, there must be precisely |
-/// one definition in a compilation unit someplace. |
- |
-/// A count metric should be used to report anything that monotonically |
-/// increases. |
-/// Examples: |
-/// # event count |
-/// how often does this condition hit, this function get called |
-/// # aggregate sums |
-/// how many bytes are written |
-#define DECLARE_METRIC_count(name) DECLARE_METRIC(CountMetric, name) |
-#define DEFINE_METRIC_count(name) DEFINE_METRIC(CountMetric, name) |
- |
-/// Use timing metrics to report on the performance of important things. |
-/// A timing metric will report the count of occurrences, as well as the |
-/// average, min and max times. |
-/// Samples are measured in milliseconds if you use the TIME_SCOPE macro |
-/// or the HighResTimer class to collect samples. |
-#define DECLARE_METRIC_timing(name) DECLARE_METRIC(TimingMetric, name) |
-#define DEFINE_METRIC_timing(name) DEFINE_METRIC(TimingMetric, name) |
- |
-/// Collects a sample from here to the end of the current scope, and |
-/// adds the sample to the timing metric supplied |
-#define TIME_SCOPE(timing) \ |
- stats_report::TimingSample __xxsample__(timing) |
- |
-/// Use integer metrics to report runtime values that fluctuate. |
-/// Examples: |
-/// # object count |
-/// How many objects of some type exist |
-/// # disk space or memory |
-/// How much disk space or memory is in use |
-#define DECLARE_METRIC_integer(name) DECLARE_METRIC(IntegerMetric, name) |
-#define DEFINE_METRIC_integer(name) DEFINE_METRIC(IntegerMetric, name) |
- |
- |
-/// Use boolean metrics to report the occurrence of important but rare events |
-/// or conditions. Note that a boolean metric is tri-state, so you typically |
-/// want to set it only in one direction, and typically to true. |
-/// Setting a boolean metric one way or another on a trigger event will report |
-/// the setting of the boolean immediately prior to reporting, which is |
-/// typically not what you want. |
-#define DECLARE_METRIC_bool(name) DECLARE_METRIC(BoolMetric, name) |
-#define DEFINE_METRIC_bool(name) DEFINE_METRIC(BoolMetric, name) |
- |
- |
-/// Implementation macros |
-#define DECLARE_METRIC(type, name) \ |
- namespace omaha_client_statsreport { \ |
- extern stats_report::type metric_##name; \ |
- } \ |
- using omaha_client_statsreport::metric_##name |
- |
-#define DEFINE_METRIC(type, name) \ |
- namespace omaha_client_statsreport { \ |
- stats_report::type metric_##name(#name, \ |
- &stats_report::g_global_metric_storage); \ |
- } \ |
- using omaha_client_statsreport::metric_##name |
- |
- |
-namespace stats_report { |
- |
-enum MetricType { |
- // use zero for invalid, because global storage defaults to zero |
- kInvalidType = 0, |
- kCountType, |
- kTimingType, |
- kIntegerType, |
- kBoolType |
-}; |
- |
-// fwd. |
-struct MetricCollectionBase; |
-class MetricCollection; |
-class MetricBase; |
-class IntegerMetricBase; |
-class CountMetric; |
-class TimingMetric; |
-class IntegerMetric; |
-class BoolMetric; |
- |
-/// Base class for all stats instances. |
-/// Stats instances are chained together against a MetricCollection to |
-/// allow enumerating stats. |
-/// |
-/// MetricCollection is factored into a class to make it easier to unittest |
-/// the implementation. |
-class MetricBase { |
-public: |
- /// @name Downcasts |
- /// @{ |
- CountMetric &AsCount(); |
- TimingMetric &AsTiming(); |
- IntegerMetric &AsInteger(); |
- BoolMetric &AsBool(); |
- |
- const CountMetric &AsCount() const; |
- const TimingMetric &AsTiming() const; |
- const IntegerMetric &AsInteger() const; |
- const BoolMetric &AsBool() const; |
- /// @} |
- |
- /// @name Accessors |
- /// @{ |
- MetricType type() const { return type_; } |
- MetricBase *next() const { return next_; } |
- const char *name() const { return name_; } |
- /// @} |
- |
- // TODO(omaha): does this need to be virtual? |
- virtual ~MetricBase() = 0; |
- |
-protected: |
- class ObjectLock; |
- void Lock() const; |
- void Unlock() const; |
- |
- /// Constructs a MetricBase and adds to the provided MetricCollection. |
- /// @note Metrics can only be constructed up to the point where the |
- /// MetricCollection is initialized, and there's no locking performed. |
- /// The assumption is that outside unit tests, Metrics will we declared |
- /// as static/global variables, and initialized at static initialization |
- /// time - and static initialization is single-threaded. |
- MetricBase(const char *name, MetricType type, MetricCollectionBase *coll); |
- |
- /// Constructs a named typed MetricBase |
- MetricBase(const char *name, MetricType type); |
- |
- /// Our name |
- char const *const name_; |
- |
- /// type of this metric |
- MetricType const type_; |
- |
- /// chains to next stat instance |
- MetricBase *const next_; |
- |
- /// The collection we're created against |
- MetricCollectionBase *const coll_; |
- |
-private: |
- DISALLOW_EVIL_CONSTRUCTORS(MetricBase); |
-}; |
- |
-/// Must be a POD |
-struct MetricCollectionBase { |
- bool initialized_; |
- MetricBase *first_; |
-}; |
- |
-/// Inherit from base, which is a POD and can be initialized at link time. |
-/// |
-/// The global MetricCollection is aliased to a link-time initialized |
-/// instance of MetricCollectionBase, and must not extend the size of its |
-/// base class. |
-class MetricCollection: public MetricCollectionBase { |
-public: |
- MetricCollection() { |
- initialized_ = false; |
- first_ = NULL; |
- } |
- ~MetricCollection() { |
- DCHECK(NULL == first_); |
- } |
- |
- /// Initialize must be called after all metrics have been added to the |
- /// collection, but before enumerating it for e.g. aggregation or reporting. |
- /// The intent is that outside unit tests, there will only be the global |
- /// metrics collection, which will accrue all metrics defined with the |
- /// DEFINE_METRIC_* macros. |
- /// Typically you'd call Initialize very early in your main function, and |
- /// Uninitialize towards the end of main. |
- /// It is an error to Initialize() when the collection is initialized(). |
- void Initialize(); |
- |
- /// Uninitialize must be called before removing (deleting or deconstructing) |
- /// metrics from the collection. |
- /// It is an error to Uninitialize() when the collection is !initialized(). |
- void Uninitialize(); |
- |
- MetricBase *first() const { return first_; } |
- bool initialized() const { return initialized_; } |
- |
-private: |
- using MetricCollectionBase::initialized_; |
- using MetricCollectionBase::first_; |
- |
- DISALLOW_EVIL_CONSTRUCTORS(MetricCollection); |
- |
- /// MetricBase is intimate with us |
- friend class MetricBase; |
-}; |
- |
-/// Implements a forward_iterator for MetricCollection. |
-class MetricIterator: public std::iterator<std::forward_iterator_tag, |
- MetricBase *> { |
-public: |
- MetricIterator() : curr_(NULL) { |
- } |
- MetricIterator(const MetricIterator &other) : curr_(other.curr_) { |
- } |
- MetricIterator(const MetricCollection &coll) : curr_(coll.first()) { |
- DCHECK(coll.initialized()); |
- } |
- |
- MetricBase *operator*() const { |
- return curr_; |
- } |
- MetricBase *operator->() const { |
- return curr_; |
- } |
- MetricIterator operator++() { // preincrement |
- if (curr_) |
- curr_ = curr_->next(); |
- |
- return (*this); |
- } |
- MetricIterator operator++(int) {// postincrement |
- MetricIterator ret = *this; |
- ++*this; |
- return (ret); |
- } |
- |
-private: |
- MetricBase *curr_; |
-}; |
- |
-inline bool operator == (const MetricIterator &a, const MetricIterator &b) { |
- return *a == *b; |
-} |
-inline bool operator != (const MetricIterator &a, const MetricIterator &b) { |
- return !operator == (a, b); |
-} |
- |
-/// Globally defined counters are registered here |
-extern MetricCollectionBase g_global_metric_storage; |
- |
-/// And more conveniently accessed through here |
-extern MetricCollection &g_global_metrics; |
- |
-/// Base class for integer metrics |
-class IntegerMetricBase: public MetricBase { |
-public: |
- /// Sets the current value |
- void Set(int64 value); |
- |
- /// Retrieves the current value |
- int64 value() const; |
- |
- void operator ++ () { Increment(); } |
- void operator ++ (int) { Increment(); } |
- void operator += (int64 addend) { Add(addend); } |
- |
-protected: |
- IntegerMetricBase(const char *name, |
- MetricType type, |
- MetricCollectionBase *coll) |
- : MetricBase(name, type, coll), value_(0) { |
- } |
- IntegerMetricBase(const char *name, MetricType type, int64 value) |
- : MetricBase(name, type), value_(value) { |
- } |
- |
- void Increment(); |
- void Decrement(); |
- void Add(int64 value); |
- void Subtract(int64 value); |
- |
- int64 value_; |
- |
-private: |
- DISALLOW_EVIL_CONSTRUCTORS(IntegerMetricBase); |
-}; |
- |
-/// A count metric is a cumulative counter of events. |
-class CountMetric: public IntegerMetricBase { |
-public: |
- CountMetric(const char *name, MetricCollectionBase *coll) |
- : IntegerMetricBase(name, kCountType, coll) { |
- } |
- |
- CountMetric(const char *name, int64 value) |
- : IntegerMetricBase(name, kCountType, value) { |
- } |
- |
- /// Nulls the metric and returns the current values. |
- int64 Reset(); |
- |
-private: |
- DISALLOW_EVIL_CONSTRUCTORS(CountMetric); |
-}; |
- |
-class TimingMetric: public MetricBase { |
-public: |
- struct TimingData { |
- uint32 count; |
- uint32 align; // allow access to the alignment gap between count and sum, |
- // makes it esier to unittest. |
- int64 sum; // ms |
- int64 minimum; // ms |
- int64 maximum; // ms |
- }; |
- |
- TimingMetric(const char *name, MetricCollectionBase *coll) |
- : MetricBase(name, kTimingType, coll) { |
- Clear(); |
- } |
- |
- TimingMetric(const char *name, const TimingData &value) |
- : MetricBase(name, kTimingType), data_(value) { |
- } |
- |
- uint32 count() const; |
- int64 sum() const; |
- int64 minimum() const; |
- int64 maximum() const; |
- int64 average() const; |
- |
- /// Adds a single sample to the metric |
- /// @param time_ms time (in milliseconds) for this sample |
- void AddSample(int64 time_ms); |
- |
- /// Adds count samples to the metric |
- /// @note use this when capturing time over a variable number of items to |
- /// normalize e.g. download time per byte or KB. This records one sample |
- /// over count items, which is numerically more stable for the average |
- /// than dividing the captured time by the item count. As a side benefit |
- /// the timer will also record the item count. |
- /// @note if count == 0, no sample will be recorded |
- /// @param count number of samples to add |
- /// @param total_time_ms the total time consumed by all the "count" samples |
- void AddSamples(int64 count, int64 total_time_ms); |
- |
- /// Nulls the metric and returns the current values. |
- TimingData Reset(); |
- |
-private: |
- DISALLOW_EVIL_CONSTRUCTORS(TimingMetric); |
- |
- void Clear(); |
- |
- TimingData data_; |
-}; |
- |
-/// A convenience class to sample the time from construction to destruction |
-/// against a given timing metric. |
-class TimingSample { |
-public: |
- /// @param timing the metric the sample is to be tallied against |
- explicit TimingSample(TimingMetric &timing) : timing_(timing), count_(1) { |
- } |
- |
- /// @param timing the metric the sample is to be tallied against |
- /// @param item_count count of items processed, used to divide the sampled |
- /// time so as to capture time per item, which is often a better measure |
- /// than the total time over a varying number of items. |
- TimingSample(TimingMetric &timing, uint32 item_count) : timing_(timing), |
- count_(item_count) { |
- } |
- |
- ~TimingSample() { |
- // We discard samples with a zero count |
- if(count_ == 1) |
- timing_.AddSample(timer_.GetElapsedMs()); |
- else |
- timing_.AddSamples(count_, timer_.GetElapsedMs()); |
- } |
- |
- /// @name Accessors |
- /// @{ |
- uint32 count() const { return count_; } |
- void set_count(uint32 count) { count_ = count; } |
- /// @} |
- |
-private: |
- /// Collects the sample for us. |
- omaha::HighresTimer timer_; |
- |
- /// The metric we tally against. |
- TimingMetric &timing_; |
- |
- /// The item count we divide the captured time by |
- uint32 count_; |
- |
- DISALLOW_EVIL_CONSTRUCTORS(TimingSample); |
-}; |
- |
-/// An integer metric is used to sample values that vary over time. |
-/// On aggregation the instantaneous value of the integer metric is captured. |
-class IntegerMetric: public IntegerMetricBase { |
-public: |
- IntegerMetric(const char *name, MetricCollectionBase *coll) |
- : IntegerMetricBase(name, kIntegerType, coll) { |
- } |
- |
- IntegerMetric(const char *name, int64 value) |
- : IntegerMetricBase(name, kIntegerType, value) { |
- } |
- |
- void operator = (int64 value) { Set(value); } |
- |
- void operator -- () { Decrement(); } |
- void operator -- (int) { Decrement(); } |
- void operator -= (int64 sub) { Subtract(sub); } |
- |
-private: |
- DISALLOW_EVIL_CONSTRUCTORS(IntegerMetric); |
-}; |
- |
-/// A bool metric is tri-state, and can be: |
-/// - unset, |
-/// - true or |
-/// - false |
-/// to match other metrics, which are implicitly unset if they've not changed |
-/// from their initial value. |
-class BoolMetric: public MetricBase { |
-public: |
- /// Values we can take |
- enum TristateBoolValue { |
- kBoolUnset = -1, |
- kBoolFalse, |
- kBoolTrue, |
- }; |
- |
- BoolMetric(const char *name, MetricCollectionBase *coll) |
- : MetricBase(name, kBoolType, coll), value_(kBoolUnset) { |
- } |
- |
- BoolMetric(const char *name, uint32 value) |
- : MetricBase(name, kBoolType) { |
- switch (value) { |
- case kBoolFalse: |
- case kBoolTrue: |
- value_ = static_cast<TristateBoolValue>(value); |
- break; |
- |
- default: |
- DCHECK(false && "Unexpected tristate bool value on construction"); |
- value_ = kBoolUnset; |
- } |
- } |
- |
- /// Sets the flag to the provided value. |
- void Set(bool value); |
- |
- void operator = (bool value) { |
- Set(value); |
- } |
- |
- /// Nulls the metric and returns the current values. |
- TristateBoolValue Reset(); |
- |
- /// Returns the current value - not threadsafe |
- TristateBoolValue value() const { return value_; }; |
- |
-private: |
- DISALLOW_EVIL_CONSTRUCTORS(BoolMetric); |
- |
- TristateBoolValue value_; |
-}; |
- |
-inline CountMetric &MetricBase::AsCount() { |
- DCHECK_EQ(kCountType, type()); |
- |
- return static_cast<CountMetric&>(*this); |
-} |
- |
-inline TimingMetric &MetricBase::AsTiming() { |
- DCHECK_EQ(kTimingType, type()); |
- |
- return static_cast<TimingMetric&>(*this); |
-} |
- |
-inline IntegerMetric &MetricBase::AsInteger() { |
- DCHECK_EQ(kIntegerType, type()); |
- |
- return static_cast<IntegerMetric&>(*this); |
-} |
- |
-inline BoolMetric &MetricBase::AsBool() { |
- DCHECK_EQ(kBoolType, type()); |
- |
- return static_cast<BoolMetric&>(*this); |
-} |
- |
-inline const CountMetric &MetricBase::AsCount() const { |
- DCHECK_EQ(kCountType, type()); |
- |
- return static_cast<const CountMetric&>(*this); |
-} |
- |
-inline const TimingMetric &MetricBase::AsTiming() const { |
- DCHECK_EQ(kTimingType, type()); |
- |
- return static_cast<const TimingMetric&>(*this); |
-} |
- |
-inline const IntegerMetric &MetricBase::AsInteger() const { |
- DCHECK_EQ(kIntegerType, type()); |
- |
- return static_cast<const IntegerMetric&>(*this); |
-} |
- |
-inline const BoolMetric &MetricBase::AsBool() const { |
- DCHECK_EQ(kBoolType, type()); |
- |
- return static_cast<const BoolMetric&>(*this); |
-} |
- |
-} // namespace stats_report |
- |
-#endif // OMAHA_STATSREPORT_METRICS_H__ |