X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=metrics.cpp;h=2874ad42a8a70260bfb038b7f9320d3aa1880cfb;hb=4194f21b1a5e4ccfe79d40024075ab9795814029;hp=ffa6b57b5dec2c9fe641e1af799b8afd2b98ba6d;hpb=fc65b01785b439f1ce0e8b04a33ad8abd5b4091e;p=nageru diff --git a/metrics.cpp b/metrics.cpp index ffa6b57..2874ad4 100644 --- a/metrics.cpp +++ b/metrics.cpp @@ -9,6 +9,26 @@ using namespace std; Metrics global_metrics; +namespace { + +string serialize_name(const string &name, const vector> &labels) +{ + if (labels.empty()) { + return "nageru_" + name; + } + + string label_str; + for (const pair &label : labels) { + if (!label_str.empty()) { + label_str += ","; + } + label_str += label.first + "=\"" + label.second + "\""; + } + return "nageru_" + name + "{" + label_str + "}"; +} + +} // namespace + void Metrics::add(const string &name, const vector> &labels, atomic *location, Metrics::Type type) { Metric metric; @@ -37,6 +57,18 @@ void Metrics::add(const string &name, const vector> &labels types[name] = type; } +void Metrics::add_histogram(const string &name, const vector> &labels, atomic *location, size_t num_elements) +{ + Histogram histogram; + histogram.name = name; + histogram.labels = labels; + histogram.location_int64 = location; + histogram.num_elements = num_elements; + + lock_guard lock(mu); + histograms.push_back(histogram); +} + string Metrics::serialize() const { stringstream ss; @@ -50,28 +82,33 @@ string Metrics::serialize() const } } for (const Metric &metric : metrics) { - string name; - if (metric.labels.empty()) { - name = "nageru_" + metric.name; - } else { - name = "nageru_" + metric.name + "{"; - bool first = true; - for (const pair &label : metric.labels) { - if (!first) { - name += ","; - } - first = false; - name += label.first + "=\"" + label.second + "\""; - } - name += "}"; - } + string name = serialize_name(metric.name, metric.labels); if (metric.data_type == DATA_TYPE_INT64) { - ss << "nageru_" << name << " " << metric.location_int64->load() << "\n"; + ss << name << " " << metric.location_int64->load() << "\n"; } else { - ss << "nageru_" << name << " " << metric.location_double->load() << "\n"; + ss << name << " " << metric.location_double->load() << "\n"; } } + for (const Histogram &histogram : histograms) { + ss << "# TYPE nageru_" << histogram.name << " histogram\n"; + + int64_t sum = 0, count = 0; + for (size_t i = 0; i < histogram.num_elements; ++i) { + char buf[16]; + snprintf(buf, sizeof(buf), "%lu", i); + vector> labels = histogram.labels; + labels.emplace_back("le", buf); + + int64_t val = histogram.location_int64[i].load(); + sum += i * val; + count += val; + ss << serialize_name(histogram.name + "_bucket", labels) << " " << count << "\n"; + } + + ss << serialize_name(histogram.name + "_sum", histogram.labels) << " " << sum << "\n"; + ss << serialize_name(histogram.name + "_count", histogram.labels) << " " << count << "\n"; + } return ss.str(); }