4 // A simple global class to keep track of metrics export in Prometheus format.
5 // It would be better to use a more full-featured Prometheus client library for this,
6 // but it would introduce a dependency that is not commonly packaged in distributions,
7 // which makes it quite unwieldy. Thus, we'll package our own for the time being.
18 // Prometheus recommends the use of timestamps instead of “time since event”,
19 // so you can use this to get the number of seconds since the epoch.
20 // Note that this will be wrong if your clock changes, so for non-metric use,
21 // you should use std::chrono::steady_clock instead.
22 double get_timestamp_for_metrics();
29 TYPE_HISTOGRAM, // Internal use only.
32 void add(const std::string &name, std::atomic<int64_t> *location, Type type = TYPE_COUNTER)
34 add(name, {}, location, type);
37 void add(const std::string &name, std::atomic<double> *location, Type type = TYPE_COUNTER)
39 add(name, {}, location, type);
42 void add(const std::string &name, Histogram *location)
44 add(name, {}, location);
47 void add(const std::string &name, const std::vector<std::pair<std::string, std::string>> &labels, std::atomic<int64_t> *location, Type type = TYPE_COUNTER);
48 void add(const std::string &name, const std::vector<std::pair<std::string, std::string>> &labels, std::atomic<double> *location, Type type = TYPE_COUNTER);
49 void add(const std::string &name, const std::vector<std::pair<std::string, std::string>> &labels, Histogram *location);
51 std::string serialize() const;
54 static std::string serialize_name(const std::string &name, const std::vector<std::pair<std::string, std::string>> &labels);
62 MetricKey(const std::string &name, const std::vector<std::pair<std::string, std::string>> labels)
63 : name(name), labels(labels), serialized(serialize_name(name, labels))
67 bool operator< (const MetricKey &other) const
69 return serialized < other.serialized;
72 const std::string name;
73 const std::vector<std::pair<std::string, std::string>> labels;
74 const std::string serialized;
79 std::atomic<int64_t> *location_int64;
80 std::atomic<double> *location_double;
81 Histogram *location_histogram;
85 mutable std::mutex mu;
86 std::map<std::string, Type> types; // Ordered the same as metrics, assuming no { signs in names (which are illegal).
87 std::map<MetricKey, Metric> metrics;
88 std::vector<Histogram> histograms;
90 friend class Histogram;
95 void init(const std::vector<double> &bucket_vals);
96 void init_uniform(size_t num_buckets); // Sets up buckets 0..(N-1).
97 void init_geometric(double min, double max, size_t num_buckets);
98 void count_event(double val);
99 std::string serialize(const std::string &name, const std::vector<std::pair<std::string, std::string>> &labels) const;
102 // Bucket <i> counts number of events where val[i - 1] < x <= val[i].
103 // The end histogram ends up being made into a cumulative one,
104 // but that's not how we store it here.
107 std::atomic<int64_t> count{0};
109 std::unique_ptr<Bucket[]> buckets;
111 std::atomic<double> sum{0.0};
112 std::atomic<int64_t> count_after_last_bucket{0};
115 extern Metrics global_metrics;
117 #endif // !defined(_METRICS_H)