X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=metrics.cpp;h=5079acb2064e5515a1a549af00c35924edcc57dd;hb=96cb6414f85e0ef4d660b7bd56267303e80fcd05;hp=3fadb72907d9afdc5e2574269c57badd539eba6f;hpb=1836dccf699779d9092a75755cec96cea1734a2a;p=nageru diff --git a/metrics.cpp b/metrics.cpp index 3fadb72..5079acb 100644 --- a/metrics.cpp +++ b/metrics.cpp @@ -63,10 +63,11 @@ void Metrics::add(const string &name, const vector> &labels types[name] = type; } -void Metrics::add(const string &name, const vector> &labels, Histogram *location) +void Metrics::add(const string &name, const vector> &labels, Histogram *location, Laziness laziness) { Metric metric; metric.data_type = DATA_TYPE_HISTOGRAM; + metric.laziness = laziness; metric.location_histogram = location; lock_guard lock(mu); @@ -75,6 +76,22 @@ void Metrics::add(const string &name, const vector> &labels types[name] = TYPE_HISTOGRAM; } +void Metrics::remove(const string &name, const vector> &labels) +{ + lock_guard lock(mu); + + auto it = metrics.find(MetricKey(name, labels)); + assert(it != metrics.end()); + + // If this is the last metric with this name, remove the type as well. + if (!((it != metrics.begin() && prev(it)->first.name == name) || + (it != metrics.end() && next(it)->first.name == name))) { + types.erase(name); + } + + metrics.erase(it); +} + string Metrics::serialize() const { stringstream ss; @@ -102,9 +119,15 @@ string Metrics::serialize() const if (metric.data_type == DATA_TYPE_INT64) { ss << name << " " << metric.location_int64->load() << "\n"; } else if (metric.data_type == DATA_TYPE_DOUBLE) { - ss << name << " " << metric.location_double->load() << "\n"; + double val = metric.location_double->load(); + if (isnan(val)) { + // Prometheus can't handle “-nan”. + ss << name << " NaN\n"; + } else { + ss << name << " " << val << "\n"; + } } else { - ss << metric.location_histogram->serialize(key_and_metric.first.name, key_and_metric.first.labels); + ss << metric.location_histogram->serialize(metric.laziness, key_and_metric.first.name, key_and_metric.first.labels); } } @@ -153,8 +176,22 @@ void Histogram::count_event(double val) sum = sum + val; } -string Histogram::serialize(const string &name, const vector> &labels) const +string Histogram::serialize(Metrics::Laziness laziness, const string &name, const vector> &labels) const { + // Check if the histogram is empty and should not be serialized. + if (laziness == Metrics::PRINT_WHEN_NONEMPTY && count_after_last_bucket.load() == 0) { + bool empty = true; + for (size_t bucket_idx = 0; bucket_idx < num_buckets; ++bucket_idx) { + if (buckets[bucket_idx].count.load() != 0) { + empty = false; + break; + } + } + if (empty) { + return ""; + } + } + stringstream ss; ss.imbue(locale("C")); ss.precision(20);