X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=metrics.h;h=a8156587a5f2484da831eda01af26cc0c4742454;hb=c0961059aa9335a88feb00a667ee32d95a7a888e;hp=e54bbcf41b083ea1dcc36c2a2ab781cad81471dc;hpb=df2284056394481ce5d5216f774d4a146b4983eb;p=nageru diff --git a/metrics.h b/metrics.h index e54bbcf..a815658 100644 --- a/metrics.h +++ b/metrics.h @@ -7,31 +7,87 @@ // which makes it quite unwieldy. Thus, we'll package our own for the time being. #include +#include +#include #include #include -#include +#include + +class Histogram; class Metrics { public: enum Type { TYPE_COUNTER, TYPE_GAUGE, + TYPE_HISTOGRAM, // Internal use only. }; - void register_int_metric(const std::string &name, std::atomic *location, Type type = TYPE_COUNTER); - void register_double_metric(const std::string &name, std::atomic *location, Type type = TYPE_COUNTER); + void add(const std::string &name, std::atomic *location, Type type = TYPE_COUNTER) + { + add(name, {}, location, type); + } + + void add(const std::string &name, std::atomic *location, Type type = TYPE_COUNTER) + { + add(name, {}, location, type); + } + + void add(const std::string &name, Histogram *location) + { + add(name, {}, location); + } + + void add(const std::string &name, const std::vector> &labels, std::atomic *location, Type type = TYPE_COUNTER); + void add(const std::string &name, const std::vector> &labels, std::atomic *location, Type type = TYPE_COUNTER); + void add(const std::string &name, const std::vector> &labels, Histogram *location); + std::string serialize() const; private: - template + enum DataType { + DATA_TYPE_INT64, + DATA_TYPE_DOUBLE, + DATA_TYPE_HISTOGRAM, + }; + struct Metric { - Type type; - std::atomic *location; + DataType data_type; + std::string name; + std::vector> labels; + union { + std::atomic *location_int64; + std::atomic *location_double; + Histogram *location_histogram; + }; }; mutable std::mutex mu; - std::unordered_map> int_metrics; - std::unordered_map> double_metrics; + std::map types; + std::vector metrics; + std::vector histograms; +}; + +class Histogram { +public: + void init(const std::vector &bucket_vals); + void init_uniform(size_t num_buckets); // Sets up buckets 0..(N-1). + void init_geometric(double min, double max, size_t num_buckets); + void count_event(double val); + std::string serialize(const std::string &name, const std::vector> &labels) const; + +private: + // Bucket counts number of events where val[i - 1] < x <= val[i]. + // The end histogram ends up being made into a cumulative one, + // but that's not how we store it here. + struct Bucket { + double val; + std::atomic count{0}; + }; + std::unique_ptr buckets; + size_t num_buckets; + std::atomic sum{0.0}; + std::atomic count_after_last_bucket{0}; }; extern Metrics global_metrics;