LogCabin
Core/RollingStat.h
Go to the documentation of this file.
00001 /* Copyright (c) 2015 Diego Ongaro
00002  *
00003  * Permission to use, copy, modify, and distribute this software for any
00004  * purpose with or without fee is hereby granted, provided that the above
00005  * copyright notice and this permission notice appear in all copies.
00006  *
00007  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR(S) DISCLAIM ALL WARRANTIES
00008  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
00009  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL AUTHORS BE LIABLE FOR
00010  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
00011  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
00012  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
00013  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
00014  */
00015 
00016 #ifndef LOGCABIN_CORE_ROLLINGSTAT_H
00017 #define LOGCABIN_CORE_ROLLINGSTAT_H
00018 
00019 #include <cinttypes>
00020 #include <iostream>
00021 #include <deque>
00022 
00023 #include "Core/Time.h"
00024 
00025 namespace LogCabin {
00026 
00027 // forward declaration
00028 namespace Protocol {
00029 class RollingStat;
00030 }
00031 
00032 namespace Core {
00033 
00034 /**
00035  * This class gathers statistics about a given metric over time, like its
00036  * average, standard deviation, and exponentially weighted moving average. This
00037  * class also keeps track of the last 5 "exceptional" values, typically those
00038  * that are above some pre-defined threshold.
00039  *
00040  * This currently assumes your metric is a uint64_t. It could probably be
00041  * abstracted out in some way, but most metrics in LogCabin seem to fit this
00042  * category.
00043  */
00044 class RollingStat {
00045   public:
00046     /**
00047      * Clock used for exceptional values.
00048      */
00049     typedef Core::Time::SteadyClock Clock;
00050     /**
00051      * Time point used for exceptional values.
00052      */
00053     typedef Clock::time_point TimePoint;
00054 
00055     /**
00056      * Constructor.
00057      */
00058     RollingStat();
00059 
00060     /**
00061      * Destructor.
00062      */
00063     ~RollingStat();
00064 
00065     /**
00066      * Return mean, or 0 if no values reported.
00067      */
00068     double getAverage() const;
00069     /**
00070      * Return number of values reported.
00071      */
00072     uint64_t getCount() const;
00073     /**
00074      * Return exponentially weighted moving average with alpha of 0.5,
00075      * or 0 if no values reported.
00076      */
00077     double getEWMA2() const;
00078     /**
00079      * Return exponentially weighted moving average with alpha of 0.25,
00080      * or 0 if no values reported.
00081      */
00082     double getEWMA4() const;
00083     /**
00084      * Return total number of exceptional values reported.
00085      */
00086     uint64_t getExceptionalCount() const;
00087     /**
00088      * Return last value reported, or 0 if no values reported.
00089      */
00090     uint64_t getLast() const;
00091     /**
00092      * Return up to the last 5 exceptional values reported, newest first.
00093      */
00094     std::vector<std::pair<TimePoint, uint64_t>> getLastExceptional() const;
00095     /**
00096      * Return the smallest value reported, or 0 if no values reported.
00097      */
00098     uint64_t getMin() const;
00099     /**
00100      * Return the largest value reported, or 0 if no values reported.
00101      */
00102     uint64_t getMax() const;
00103     /**
00104      * Return the cumulative total of all values reported, or 0 if no values
00105      * reported.
00106      */
00107     uint64_t getSum() const;
00108     /**
00109      * Return the standard deviation of all values reported, or 0 if no values
00110      * reported.
00111      */
00112     double getStdDev() const;
00113 
00114     /**
00115      * Report an exceptional value. Note that this does not include a 'push';
00116      * you may want to do that separately.
00117      * \param when
00118      *      The time the exceptional situation occurred (by convention, this is
00119      *      usually its start time).
00120      * \param value
00121      *      The exceptional value.
00122      */
00123     void noteExceptional(TimePoint when, uint64_t value);
00124 
00125     /**
00126      * Report a value.
00127      */
00128     void push(uint64_t value);
00129 
00130     /**
00131      * Serialize all the stats into the given empty ProtoBuf message.
00132      */
00133     void updateProtoBuf(Protocol::RollingStat& message) const;
00134 
00135     /**
00136      * Print all the stats.
00137      */
00138     friend std::ostream& operator<<(std::ostream& os,
00139                                     const RollingStat& stat);
00140 
00141   private:
00142     // See getters above for most of these.
00143     uint64_t count;
00144     double ewma2;
00145     double ewma4;
00146     uint64_t exceptionalCount;
00147     uint64_t last;
00148     std::deque<std::pair<TimePoint, uint64_t>> lastExceptional;
00149     uint64_t max;
00150     uint64_t min;
00151     uint64_t sum;
00152     /**
00153      * Used to calculate standard deviation. sum of x times x over all values.
00154      */
00155     uint64_t sumSquares;
00156 
00157 };
00158 
00159 } // namespace LogCabin::Core
00160 } // namespace LogCabin
00161 
00162 #endif /* LOGCABIN_CORE_ROLLINGSTAT_H */
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines