class Histogram;
+// Prometheus recommends the use of timestamps instead of “time since event”,
+// so you can use this to get the number of seconds since the epoch.
+// Note that this will be wrong if your clock changes, so for non-metric use,
+// you should use std::chrono::steady_clock instead.
+double get_timestamp_for_metrics();
+
class Metrics {
public:
enum Type {
TYPE_GAUGE,
TYPE_HISTOGRAM, // Internal use only.
};
+ enum Laziness {
+ PRINT_ALWAYS,
+ PRINT_WHEN_NONEMPTY,
+ };
void add(const std::string &name, std::atomic<int64_t> *location, Type type = TYPE_COUNTER)
{
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);
void add(const std::string &name, const std::vector<std::pair<std::string, std::string>> &labels, std::atomic<double> *location, Type type = TYPE_COUNTER);
- void add(const std::string &name, const std::vector<std::pair<std::string, std::string>> &labels, Histogram *location);
+ void add(const std::string &name, const std::vector<std::pair<std::string, std::string>> &labels, Histogram *location, Laziness laziness = PRINT_ALWAYS);
+
+ void remove(const std::string &name)
+ {
+ remove(name, {});
+ }
+
+ void remove(const std::string &name, const std::vector<std::pair<std::string, std::string>> &labels);
std::string serialize() const;
private:
+ static std::string serialize_name(const std::string &name, const std::vector<std::pair<std::string, std::string>> &labels);
+ static std::string serialize_labels(const std::vector<std::pair<std::string, std::string>> &labels);
+
enum DataType {
DATA_TYPE_INT64,
DATA_TYPE_DOUBLE,
DATA_TYPE_HISTOGRAM,
};
-
+ struct MetricKey {
+ MetricKey(const std::string &name, const std::vector<std::pair<std::string, std::string>> labels)
+ : name(name), labels(labels), serialized_labels(serialize_labels(labels))
+ {
+ }
+
+ bool operator< (const MetricKey &other) const
+ {
+ if (name != other.name)
+ return name < other.name;
+ return serialized_labels < other.serialized_labels;
+ }
+
+ const std::string name;
+ const std::vector<std::pair<std::string, std::string>> labels;
+ const std::string serialized_labels;
+ };
struct Metric {
DataType data_type;
- std::string name;
- std::vector<std::pair<std::string, std::string>> labels;
+ Laziness laziness; // Only for TYPE_HISTOGRAM.
union {
std::atomic<int64_t> *location_int64;
std::atomic<double> *location_double;
};
mutable std::mutex mu;
- std::map<std::string, Type> types;
- std::vector<Metric> metrics;
+ std::map<std::string, Type> types; // Ordered the same as metrics.
+ std::map<MetricKey, Metric> metrics;
std::vector<Histogram> histograms;
+
+ friend class Histogram;
};
class Histogram {
public:
void init(const std::vector<double> &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<std::pair<std::string, std::string>> &labels) const;
+ std::string serialize(Metrics::Laziness laziness, const std::string &name, const std::vector<std::pair<std::string, std::string>> &labels) const;
private:
// Bucket <i> counts number of events where val[i - 1] < x <= val[i].