LogIt++
Header-only, macro-first C++ logging library
Loading...
Searching...
No Matches
PrometheusRegistry.hpp
Go to the documentation of this file.
1#pragma once
2#ifndef LOGIT_CPP_HEADER_LOGIT_CPP_LOGIT_LOGGERS_PROMETHEUS_PROMETHEUSREGISTRY_HPP_INCLUDED
3#define LOGIT_CPP_HEADER_LOGIT_CPP_LOGIT_LOGGERS_PROMETHEUS_PROMETHEUSREGISTRY_HPP_INCLUDED
4
7
9
10#include <cstddef>
11#include <exception>
12#include <functional>
13#include <string>
14#include <utility>
15#include <vector>
16
17namespace logit {
18
22 public:
24 explicit PrometheusRegistry(std::string metric_prefix = std::string())
25 : m_metric_prefix(std::move(metric_prefix)) {}
26
28 void set_metric_prefix(const std::string& metric_prefix) {
30 }
31
33 const std::string& metric_prefix() const {
34 return m_metric_prefix;
35 }
36
39 const std::string& name,
40 const std::string& help,
41 std::function<double()> value_fn,
42 std::vector<PrometheusLabel> labels = {}) {
45 name,
46 help,
47 std::move(value_fn),
48 std::move(labels));
49 }
50
53 const std::string& name,
54 const std::string& help,
55 std::function<double()> value_fn,
56 std::vector<PrometheusLabel> labels = {}) {
59 name,
60 help,
61 std::move(value_fn),
62 std::move(labels));
63 }
64
66 void collect(std::vector<PrometheusMetricFamily>& out) const {
67 std::vector<PrometheusMetricFamily> collected;
68 std::exception_ptr first_exception;
69
70 for (std::size_t i = 0; i < m_entries.size(); ++i) {
71 const Entry& entry = m_entries[i];
72 const std::string full_name = m_metric_prefix + entry.name;
73 double value = 0.0;
74
75 try {
76 value = entry.value_fn();
77 } catch (...) {
78 if (!first_exception) {
79 first_exception = std::current_exception();
80 }
81 continue;
82 }
83
85 find_family(collected, full_name, entry.type);
86 if (family == nullptr) {
88 mf.name = full_name;
89 mf.help = entry.help;
90 mf.type = entry.type;
91 collected.push_back(std::move(mf));
92 family = &collected.back();
93 }
94
95 PrometheusSample sample;
96 sample.name = full_name;
97 sample.value = value;
98 sample.labels = entry.labels;
99 family->samples.push_back(std::move(sample));
100 }
101
102 out.insert(out.end(), collected.begin(), collected.end());
103 if (first_exception) {
104 std::rethrow_exception(first_exception);
105 }
106 }
107
108 private:
109 struct Entry {
111 std::string name;
112 std::string help;
113 std::function<double()> value_fn;
114 std::vector<PrometheusLabel> labels;
115 };
116
117 std::string m_metric_prefix;
118 std::vector<Entry> m_entries;
119
122 const std::string& name,
123 const std::string& help,
124 std::function<double()> value_fn,
125 std::vector<PrometheusLabel> labels) {
126 for (std::size_t i = 0; i < m_entries.size(); ++i) {
127 Entry& entry = m_entries[i];
128 if (entry.name == name && labels_equal(entry.labels, labels)) {
129 entry.type = type;
130 entry.help = help;
131 entry.value_fn = std::move(value_fn);
132 entry.labels = std::move(labels);
133 return;
134 }
135 }
136
137 Entry entry;
138 entry.type = type;
139 entry.name = name;
140 entry.help = help;
141 entry.value_fn = std::move(value_fn);
142 entry.labels = std::move(labels);
143 m_entries.push_back(std::move(entry));
144 }
145
146 static bool labels_equal(
147 const std::vector<PrometheusLabel>& lhs,
148 const std::vector<PrometheusLabel>& rhs) {
149 if (lhs.size() != rhs.size()) {
150 return false;
151 }
152 for (std::size_t i = 0; i < lhs.size(); ++i) {
153 if (lhs[i].name != rhs[i].name || lhs[i].value != rhs[i].value) {
154 return false;
155 }
156 }
157 return true;
158 }
159
161 std::vector<PrometheusMetricFamily>& families,
162 const std::string& name,
164 for (std::size_t i = 0; i < families.size(); ++i) {
165 if (families[i].name == name && families[i].type == type) {
166 return &families[i];
167 }
168 }
169 return nullptr;
170 }
171 };
172
173} // namespace logit
174
175#endif // LOGIT_CPP_HEADER_LOGIT_CPP_LOGIT_LOGGERS_PROMETHEUS_PROMETHEUSREGISTRY_HPP_INCLUDED
Defines Prometheus text exposition format types and configuration.
Stores custom gauge and counter callbacks for Prometheus collection.
void collect(std::vector< PrometheusMetricFamily > &out) const
Appends current registry metrics to the output vector.
void set_metric_prefix(const std::string &metric_prefix)
Sets prefix applied to metrics collected by this registry.
static PrometheusMetricFamily * find_family(std::vector< PrometheusMetricFamily > &families, const std::string &name, PrometheusMetricType type)
PrometheusRegistry(std::string metric_prefix=std::string())
Constructs registry with an optional metric prefix.
static bool labels_equal(const std::vector< PrometheusLabel > &lhs, const std::vector< PrometheusLabel > &rhs)
void set_counter(const std::string &name, const std::string &help, std::function< double()> value_fn, std::vector< PrometheusLabel > labels={})
Registers or replaces a counter metric callback.
const std::string & metric_prefix() const
Returns prefix applied to metrics collected by this registry.
void set_metric(PrometheusMetricType type, const std::string &name, const std::string &help, std::function< double()> value_fn, std::vector< PrometheusLabel > labels)
void set_gauge(const std::string &name, const std::string &help, std::function< double()> value_fn, std::vector< PrometheusLabel > labels={})
Registers or replaces a gauge metric callback.
The primary namespace for the LogIt++ library.
PrometheusMetricType
Prometheus metric type identifiers.
A group of related samples sharing a name, help, and type.
std::vector< PrometheusSample > samples
Samples in this family.
std::string name
Metric family name.
PrometheusMetricType type
Metric type.
std::vector< PrometheusLabel > labels
A single metric sample with optional labels and timestamp.
std::string name
Full metric name (including suffixes).
std::vector< PrometheusLabel > labels
Labels for this sample.