prom 0.1.0
Client-independent C++23 Prometheus/OpenMetrics metric abstraction
Loading...
Searching...
No Matches
registry.hpp
Go to the documentation of this file.
1#pragma once
2
21
22#include <prom/adapter.hpp>
23#include <prom/counter.hpp>
24#include <prom/error.hpp>
25#include <prom/gauge.hpp>
26#include <prom/global.hpp>
27#include <prom/histogram.hpp>
28#include <prom/info.hpp>
29#include <prom/labels.hpp>
30#include <prom/metric_base.hpp>
31#include <prom/stateset.hpp>
32#include <prom/summary.hpp>
33#include <prom/unit.hpp>
34#include <prom/untyped.hpp>
35
36#include <cmath>
37#include <cstddef>
38#include <memory>
39#include <mutex>
40#include <optional>
41#include <string>
42#include <string_view>
43#include <utility>
44#include <vector>
45
46namespace prom {
47
48class Scope;
49struct ScopeConfig;
50
59 std::string prefix{};
64 comms::DisplayInfo display{};
65};
66
72struct MetricInfo {
74 std::string name;
75 std::string help;
78 bool scoped = false;
79};
80
83[[nodiscard]] inline MetricInfo describe(const MetricCore& core) {
85 info.type = core.type;
86 if (core.scope) {
87 info.name = core.scope->full_name(core.base_name);
88 info.const_labels = core.scope->effective_labels(core.base_labels);
89 } else {
90 info.name = core.name;
91 info.const_labels = core.const_labels;
92 }
93 info.help = core.help;
94 info.unit = core.unit_view();
95 // "scoped" means the metric is actually decorated: an empty decoration (a
96 // plain registry, or an unconfigured global) leaves it reported as plain.
97 info.scoped = core.scope && core.scope->decorates();
98 return info;
99}
100
112class Registry {
113public:
114 Registry(const Registry&) = delete;
115 Registry& operator=(const Registry&) = delete;
116 Registry(Registry&&) = delete;
118 ~Registry() = default;
119
122 [[nodiscard]] static std::shared_ptr<Registry> create(AdapterPtr adapter = nullptr) {
123 return std::shared_ptr<Registry>(
124 new Registry(std::make_shared<AdapterCell>(std::move(adapter))));
125 }
126
131 [[nodiscard]] static std::shared_ptr<Registry> create(AdapterPtr adapter,
133 return std::shared_ptr<Registry>(
134 new Registry(std::make_shared<AdapterCell>(std::move(adapter)),
135 std::make_shared<detail::DecorationState>(std::move(config.prefix),
136 std::move(config.const_labels),
137 std::move(config.display))));
138 }
139
147 [[nodiscard]] static std::shared_ptr<Registry> global() {
148 static std::shared_ptr<Registry> instance(
149 new Registry(detail::global_adapter_cell(), detail::global_decoration()));
150 return instance;
151 }
152
154 [[nodiscard]] AdapterPtr adapter() const {
155 return cell_->adapter();
156 }
157
163 cell_->set_adapter(std::move(adapter));
164 }
165
166 // --- live decoration (prefix / default labels / display) ----------------
167 //
168 // Every registry carries a decoration (empty by default), so these setters
169 // reconfigure *all* metrics it has created — existing and future — which
170 // re-register on their next use. On `Registry::global()` the decoration is
171 // the process-wide one, so a prefix / label set here also reaches standalone
172 // and scoped metrics.
173
174 [[nodiscard]] std::string prefix() const {
175 return decoration_->prefix();
176 }
177 void set_prefix(std::string prefix) {
178 decoration_->set_prefix(std::move(prefix));
179 }
180
181 [[nodiscard]] Labels const_labels() const {
182 return decoration_->const_labels();
183 }
185 decoration_->set_const_labels(std::move(labels));
186 }
187 void add_const_label(std::string name, std::string value) {
188 decoration_->add_const_label(std::move(name), std::move(value));
189 }
190
191 [[nodiscard]] comms::DisplayInfo display() const {
192 return decoration_->display();
193 }
194 void set_display(comms::DisplayInfo display) {
195 decoration_->set_display(std::move(display));
196 }
197
199 [[nodiscard]] RegistryConfig config() const {
200 return RegistryConfig{
201 decoration_->prefix(), decoration_->const_labels(), decoration_->display()};
202 }
205 decoration_->configure(
206 std::move(config.prefix), std::move(config.const_labels), std::move(config.display));
207 }
208
211 [[nodiscard]] std::vector<MetricInfo> metrics() const {
212 // Collect live cores under the lock, then describe() after releasing it
213 // (keeps the lock hold short and avoids any reentrancy on describe()).
214 std::vector<std::shared_ptr<MetricCore>> live;
215 {
216 const std::scoped_lock lock(mutex_);
217 for (auto it = metrics_.begin(); it != metrics_.end();) {
218 if (auto core = it->lock()) {
219 live.push_back(std::move(core));
220 ++it;
221 } else {
222 it = metrics_.erase(it);
223 }
224 }
225 }
226 std::vector<MetricInfo> out;
227 out.reserve(live.size());
228 for (const auto& core : live) {
229 out.push_back(describe(*core));
230 }
231 return out;
232 }
233
238 [[nodiscard]] static std::shared_ptr<Scope> scope(std::string_view name);
239 [[nodiscard]] static std::shared_ptr<Scope> scope(std::string_view name, ScopeConfig config);
240
241 // --- throwing factories -------------------------------------------------
242
243 [[nodiscard]] Counter counter(const CounterSpec& spec) {
244 return unwrap(try_counter(spec));
245 }
246 [[nodiscard]] Gauge gauge(const GaugeSpec& spec) {
247 return unwrap(try_gauge(spec));
248 }
249 [[nodiscard]] Histogram histogram(const HistogramSpec& spec) {
250 return unwrap(try_histogram(spec));
251 }
252 [[nodiscard]] Summary summary(const SummarySpec& spec) {
253 return unwrap(try_summary(spec));
254 }
255 [[nodiscard]] Untyped untyped(const UntypedSpec& spec) {
256 return unwrap(try_untyped(spec));
257 }
258 [[nodiscard]] Info info(const InfoSpec& spec) {
259 return unwrap(try_info(spec));
260 }
261 [[nodiscard]] StateSet stateset(const StateSetSpec& spec) {
262 return unwrap(try_stateset(spec));
263 }
264
265 // --- noexcept fallible mirrors -----------------------------------------
266
267 [[nodiscard]] expected<Counter> try_counter(const CounterSpec& spec) noexcept {
268 return build<Counter>(MetricType::Counter,
269 spec.name,
270 spec.help,
271 spec.labels,
272 spec.unit,
273 spec.display,
274 {},
275 {},
276 {});
277 }
278
279 [[nodiscard]] expected<Gauge> try_gauge(const GaugeSpec& spec) noexcept {
280 return build<Gauge>(MetricType::Gauge,
281 spec.name,
282 spec.help,
283 spec.labels,
284 spec.unit,
285 spec.display,
286 {},
287 {},
288 {});
289 }
290
291 [[nodiscard]] expected<Histogram> try_histogram(const HistogramSpec& spec) noexcept {
292 std::vector<double> buckets = spec.buckets;
293 if (buckets.empty()) {
295 }
296 if (const auto err = validate_buckets(buckets)) {
297 return std::unexpected(*err);
298 }
299 return build<Histogram>(MetricType::Histogram,
300 spec.name,
301 spec.help,
302 spec.labels,
303 spec.unit,
304 spec.display,
305 std::move(buckets),
306 {},
307 {});
308 }
309
310 [[nodiscard]] expected<Summary> try_summary(const SummarySpec& spec) noexcept {
311 std::vector<double> quantiles = spec.quantiles;
312 if (quantiles.empty()) {
314 }
315 if (const auto err = validate_quantiles(quantiles)) {
316 return std::unexpected(*err);
317 }
318 return build<Summary>(MetricType::Summary,
319 spec.name,
320 spec.help,
321 spec.labels,
322 spec.unit,
323 spec.display,
324 {},
325 std::move(quantiles),
326 {});
327 }
328
329 [[nodiscard]] expected<Untyped> try_untyped(const UntypedSpec& spec) noexcept {
330 return build<Untyped>(MetricType::Untyped,
331 spec.name,
332 spec.help,
333 spec.labels,
334 spec.unit,
335 spec.display,
336 {},
337 {},
338 {});
339 }
340
341 [[nodiscard]] expected<Info> try_info(const InfoSpec& spec) noexcept {
342 return build<Info>(
343 MetricType::Info, spec.name, spec.help, spec.labels, Unit{}, spec.display, {}, {}, {});
344 }
345
346 [[nodiscard]] expected<StateSet> try_stateset(const StateSetSpec& spec) noexcept {
347 if (spec.states.empty()) {
348 return std::unexpected(Error{ErrorCode::EmptyStateSet, std::string(spec.name)});
349 }
350 return build<StateSet>(MetricType::StateSet,
351 spec.name,
352 spec.help,
353 spec.labels,
354 Unit{},
355 spec.display,
356 {},
357 {},
358 spec.states);
359 }
360
361private:
362 template <class Metric>
363 [[nodiscard]] expected<Metric> build(const MetricType type,
364 const std::string_view name,
365 const std::string_view help,
366 const Labels& labels,
367 const Unit& unit,
368 const comms::DisplayInfo& display,
369 std::vector<double> buckets,
370 std::vector<double> quantiles,
371 std::vector<std::string> states) noexcept {
373 return std::unexpected(Error{ErrorCode::InvalidMetricName, std::string(name)});
374 }
375 for (const auto& [label_name, value] : labels.view()) {
376 if (!is_valid_label_name(label_name)) {
377 return std::unexpected(Error{ErrorCode::InvalidLabelName, label_name});
378 }
379 }
380
381 auto core = std::make_shared<MetricCore>();
382 core->type = type;
383 core->help = std::string(help);
384 core->buckets = std::move(buckets);
385 core->quantiles = std::move(quantiles);
386 core->states = std::move(states);
387 core->source = cell_;
388 if (!unit.empty()) {
389 core->has_unit = true;
390 core->unit_from_dimval = unit.from_dimval;
391 core->unit_name = std::string(unit.name);
392 core->unit_kind = std::string(unit.kind);
393 core->unit_symbol = std::string(unit.symbol);
394 }
395
396 // Resolve the effective name / labels / display from the registry's live
397 // decoration, keeping the base values so the metric can re-resolve when
398 // the decoration changes (same machinery as a Scope). The decoration is
399 // empty by default, in which case the effective values equal the spec's.
400 core->scope = decoration_;
401 core->base_name = std::string(name);
402 core->base_labels = labels;
403 core->base_display = display;
404 const std::uint64_t decoration_version = decoration_->version();
405 core->name = decoration_->full_name(name);
406 core->const_labels = decoration_->effective_labels(labels);
407 core->display = decoration_->effective_display(display);
408
409 // Register eagerly against the current adapter so the family exists at
410 // creation and `metrics()` can list it before first use. A later
411 // adapter swap bumps the cell version, and a decoration change bumps the
412 // scope version; either triggers re-registration on next use.
413 const std::uint64_t adapter_version = cell_->version();
414 const AdapterPtr adapter = cell_->adapter();
415 const MetricHandle handle = adapter->register_metric(core->build_meta());
416 core->bound.store(std::make_shared<const MetricCore::Bound>(
417 MetricCore::Bound{.adapter = adapter,
418 .handle = handle,
419 .adapter_version = adapter_version,
420 .scope_version = decoration_version}));
421 track(core);
422 return Metric{std::move(core)};
423 }
424
426 void track(const std::shared_ptr<MetricCore>& core) const noexcept {
427 const std::scoped_lock lock(mutex_);
428 metrics_.push_back(core);
429 }
430
431 template <class Metric>
432 [[nodiscard]] static Metric unwrap(expected<Metric> result) {
433 if (!result) {
434 throw Exception(std::move(result.error()));
435 }
436 return std::move(*result);
437 }
438
439 [[nodiscard]] static std::optional<Error>
440 validate_buckets(const std::vector<double>& buckets) noexcept {
441 if (buckets.empty()) {
442 return Error{ErrorCode::InvalidBuckets, "no buckets"};
443 }
444 for (std::size_t i = 0; i < buckets.size(); ++i) {
445 if (!std::isfinite(buckets[i])) {
446 return Error{ErrorCode::InvalidBuckets, "non-finite bound"};
447 }
448 if (i > 0 && buckets[i] <= buckets[i - 1]) {
449 return Error{ErrorCode::InvalidBuckets, "bounds not strictly increasing"};
450 }
451 }
452 return std::nullopt;
453 }
454
455 [[nodiscard]] static std::optional<Error>
456 validate_quantiles(const std::vector<double>& quantiles) noexcept {
457 for (const double q : quantiles) {
458 if (!std::isfinite(q) || q <= 0.0 || q >= 1.0) {
459 return Error{ErrorCode::InvalidQuantiles, "quantile outside (0, 1)"};
460 }
461 }
462 return std::nullopt;
463 }
464
466 explicit Registry(std::shared_ptr<AdapterCell> cell) noexcept
467 : Registry(std::move(cell), std::make_shared<detail::DecorationState>()) {}
468
471 Registry(std::shared_ptr<AdapterCell> cell,
472 std::shared_ptr<detail::DecorationState> decoration) noexcept
473 : cell_(std::move(cell)), decoration_(std::move(decoration)) {}
474
475 std::shared_ptr<AdapterCell> cell_;
476 mutable std::mutex mutex_;
477 mutable std::vector<std::weak_ptr<MetricCore>> metrics_;
478 // The live prefix / labels / display applied to every metric this registry
479 // creates. Set once at construction (never null), so reads need no lock.
480 std::shared_ptr<detail::DecorationState> decoration_;
481};
482
483// --- free helpers bound to Registry::global() -------------------------------
484//
485// These let a library create metrics without holding or passing a Registry:
486// auto c = prom::counter({.name = "requests_total", .help = "..."});
487// Each delegates to the process-wide Registry::global(), which registers
488// against whatever adapter is installed on the global cell at the time of the
489// call (a NullAdapter until a backend is installed).
490
491[[nodiscard]] inline Counter counter(const CounterSpec& spec) {
492 return Registry::global()->counter(spec);
493}
494[[nodiscard]] inline Gauge gauge(const GaugeSpec& spec) {
495 return Registry::global()->gauge(spec);
496}
497[[nodiscard]] inline Histogram histogram(const HistogramSpec& spec) {
498 return Registry::global()->histogram(spec);
499}
500[[nodiscard]] inline Summary summary(const SummarySpec& spec) {
501 return Registry::global()->summary(spec);
502}
503[[nodiscard]] inline Untyped untyped(const UntypedSpec& spec) {
504 return Registry::global()->untyped(spec);
505}
506[[nodiscard]] inline Info info(const InfoSpec& spec) {
507 return Registry::global()->info(spec);
508}
509[[nodiscard]] inline StateSet stateset(const StateSetSpec& spec) {
510 return Registry::global()->stateset(spec);
511}
512
513[[nodiscard]] inline expected<Counter> try_counter(const CounterSpec& spec) noexcept {
514 return Registry::global()->try_counter(spec);
515}
516[[nodiscard]] inline expected<Gauge> try_gauge(const GaugeSpec& spec) noexcept {
517 return Registry::global()->try_gauge(spec);
518}
519[[nodiscard]] inline expected<Histogram> try_histogram(const HistogramSpec& spec) noexcept {
520 return Registry::global()->try_histogram(spec);
521}
522[[nodiscard]] inline expected<Summary> try_summary(const SummarySpec& spec) noexcept {
523 return Registry::global()->try_summary(spec);
524}
525[[nodiscard]] inline expected<Untyped> try_untyped(const UntypedSpec& spec) noexcept {
526 return Registry::global()->try_untyped(spec);
527}
528[[nodiscard]] inline expected<Info> try_info(const InfoSpec& spec) noexcept {
529 return Registry::global()->try_info(spec);
530}
531[[nodiscard]] inline expected<StateSet> try_stateset(const StateSetSpec& spec) noexcept {
532 return Registry::global()->try_stateset(spec);
533}
534
535} // namespace prom
::prometheus::Gauge * gauge
Definition adapter.cpp:61
::prometheus::Histogram::BucketBoundaries buckets
Definition adapter.cpp:65
::prometheus::Summary * summary
Definition adapter.cpp:63
::prometheus::Counter * counter
Definition adapter.cpp:60
std::string name
Metric name (state-set label key).
Definition adapter.cpp:68
::prometheus::Summary::Quantiles quantiles
Definition adapter.cpp:66
prom::MetricType type
Definition adapter.cpp:53
::prometheus::Histogram * histogram
Definition adapter.cpp:62
A counter.
Definition counter.hpp:28
A gauge.
Definition gauge.hpp:24
A histogram.
Definition histogram.hpp:32
An info metric: a single sample whose labels carry the payload (build version, commit,...
Definition info.hpp:25
An immutable-by-convention set of labels, kept sorted by name with duplicates collapsed last-wins.
Definition labels.hpp:55
MetricType type() const noexcept
The metric kind.
Definition metric_base.hpp:385
std::string_view name() const noexcept
The metric's fully-qualified name.
Definition metric_base.hpp:380
Creates registered metrics against a single adapter cell.
Definition registry.hpp:112
RegistryConfig config() const
A snapshot of the whole decoration.
Definition registry.hpp:199
Registry & operator=(Registry &&)=delete
Info info(const InfoSpec &spec)
Definition registry.hpp:258
static std::shared_ptr< Registry > global()
The process-wide registry, sharing the global adapter cell and the global decoration.
Definition registry.hpp:147
Registry(const Registry &)=delete
void set_const_labels(Labels labels)
Definition registry.hpp:184
Untyped untyped(const UntypedSpec &spec)
Definition registry.hpp:255
static std::shared_ptr< Scope > scope(std::string_view name)
Get-or-create the process-wide, named Scope (a per-library metrics instance with a shared prefix / de...
Definition scope.hpp:355
comms::DisplayInfo display() const
Definition registry.hpp:191
void configure(RegistryConfig config)
Replace the whole decoration at once (single reconfiguration).
Definition registry.hpp:204
expected< Gauge > try_gauge(const GaugeSpec &spec) noexcept
Definition registry.hpp:279
expected< Info > try_info(const InfoSpec &spec) noexcept
Definition registry.hpp:341
static std::shared_ptr< Registry > create(AdapterPtr adapter, RegistryConfig config)
Create a decorating registry: every metric built from it gets config's prefix, default constant label...
Definition registry.hpp:131
StateSet stateset(const StateSetSpec &spec)
Definition registry.hpp:261
expected< Summary > try_summary(const SummarySpec &spec) noexcept
Definition registry.hpp:310
Registry(Registry &&)=delete
expected< Histogram > try_histogram(const HistogramSpec &spec) noexcept
Definition registry.hpp:291
void set_prefix(std::string prefix)
Definition registry.hpp:177
expected< StateSet > try_stateset(const StateSetSpec &spec) noexcept
Definition registry.hpp:346
Gauge gauge(const GaugeSpec &spec)
Definition registry.hpp:246
Registry & operator=(const Registry &)=delete
Labels const_labels() const
Definition registry.hpp:181
Summary summary(const SummarySpec &spec)
Definition registry.hpp:252
Counter counter(const CounterSpec &spec)
Definition registry.hpp:243
static std::shared_ptr< Registry > create(AdapterPtr adapter=nullptr)
Create a registry with its own cell holding adapter (a fresh NullAdapter when null).
Definition registry.hpp:122
expected< Counter > try_counter(const CounterSpec &spec) noexcept
Definition registry.hpp:267
AdapterPtr adapter() const
The adapter this registry binds metrics to.
Definition registry.hpp:154
std::vector< MetricInfo > metrics() const
Snapshots describing every (still-alive) metric created from this registry, including declared-but-un...
Definition registry.hpp:211
void set_display(comms::DisplayInfo display)
Definition registry.hpp:194
void set_adapter(AdapterPtr adapter) const
Install adapter (or reset to a fresh NullAdapter when null) as this registry's backend.
Definition registry.hpp:162
expected< Untyped > try_untyped(const UntypedSpec &spec) noexcept
Definition registry.hpp:329
void add_const_label(std::string name, std::string value)
Definition registry.hpp:187
std::string prefix() const
Definition registry.hpp:174
~Registry()=default
Histogram histogram(const HistogramSpec &spec)
Definition registry.hpp:249
A state set: each declared state is a boolean, exposed as one series per state with value 0 or 1.
Definition stateset.hpp:27
A summary. Like a histogram but tracks quantiles instead of fixed buckets.
Definition summary.hpp:29
An untyped metric: just a settable value.
Definition untyped.hpp:24
Counter — a monotonically increasing cumulative metric, and its designated-initializable CounterSpec.
Error model for prom: ErrorCode, Error, expected, Exception.
Gauge — a value that can move in both directions, and GaugeSpec.
The process-wide adapter cell and its install/swap semantics.
Histogram — bucketed observation distribution, and HistogramSpec.
The backend boundary: MetricMeta, MetricState/MetricHandle, and the pure-virtual Adapter interface.
Info — static key/value metadata exposed as an *_info series.
Label vocabulary: Label, the sorted/deduped Labels set, name validation, and an std::hash<Labels> spe...
MetricCore (the shared per-series state) and the CRTP MetricBase that gives every metric type value s...
std::shared_ptr< DecorationState > global_decoration()
The process-wide decoration shared by Registry::global(), every standalone metric,...
Definition metric_base.hpp:238
Definition adapter.hpp:24
@ EmptyStateSet
A state set was declared with no states.
@ InvalidLabelName
A label name is invalid or uses the reserved __ prefix.
@ InvalidMetricName
Name violates [a-zA-Z_][a-zA-Z0-9_]*.
@ InvalidQuantiles
Summary quantiles fall outside the open interval (0, 1).
@ InvalidBuckets
Histogram buckets are unsorted, empty, or non-finite.
StateSet stateset(const StateSetSpec &spec)
Definition registry.hpp:509
MetricType
The OpenMetrics / Prometheus metric kinds prom understands.
Definition unit.hpp:15
@ Summary
Quantile summary of observations.
@ Info
Static key/value metadata (exposed as *_info).
@ Untyped
A bare value with no semantic constraints.
@ Counter
Monotonically increasing cumulative value.
@ Gauge
Value that can go up and down.
@ StateSet
A set of mutually-related boolean states.
@ Histogram
Bucketed distribution of observations.
constexpr bool is_valid_metric_name(std::string_view name) noexcept
A metric name is valid when it matches Prometheus's [a-zA-Z_][a-zA-Z0-9_]*.
Definition labels.hpp:28
constexpr bool is_valid_label_name(const std::string_view name) noexcept
A label name follows the metric-name charset but additionally rejects the __ prefix,...
Definition labels.hpp:44
constexpr std::array< double, 3 > default_summary_quantiles
Default quantiles applied when a summary spec leaves quantiles empty.
Definition summary.hpp:16
std::expected< T, Error > expected
std::expected<T, Error> — the result type of the Registry::try_* family.
Definition error.hpp:66
expected< StateSet > try_stateset(const StateSetSpec &spec) noexcept
Definition registry.hpp:531
std::shared_ptr< Adapter > AdapterPtr
Shared ownership of an Adapter.
Definition fwd.hpp:38
expected< Histogram > try_histogram(const HistogramSpec &spec) noexcept
Definition registry.hpp:519
MetricInfo describe(const MetricCore &core)
Build a MetricInfo from a core, applying scope decoration for a scoped metric's effective name and co...
Definition registry.hpp:83
expected< Gauge > try_gauge(const GaugeSpec &spec) noexcept
Definition registry.hpp:516
expected< Counter > try_counter(const CounterSpec &spec) noexcept
Definition registry.hpp:513
Info info(const InfoSpec &spec)
Definition registry.hpp:506
expected< Summary > try_summary(const SummarySpec &spec) noexcept
Definition registry.hpp:522
expected< Untyped > try_untyped(const UntypedSpec &spec) noexcept
Definition registry.hpp:525
Untyped untyped(const UntypedSpec &spec)
Definition registry.hpp:503
std::shared_ptr< MetricState > MetricHandle
Opaque, backend-owned handle to a registered metric family or a labeled child series.
Definition fwd.hpp:34
constexpr std::array< double, 11 > default_histogram_buckets
The default bucket bounds applied when a histogram spec leaves buckets empty — the canonical Promethe...
Definition histogram.hpp:17
expected< Info > try_info(const InfoSpec &spec) noexcept
Definition registry.hpp:528
StateSet — a set of mutually-related boolean states, and StateSetSpec.
Declarative description of a counter, for Registry::counter / Counter::Counter.
Definition counter.hpp:17
A validation failure: a machine code plus a human message.
Definition error.hpp:57
Declarative description of a gauge.
Definition gauge.hpp:14
Declarative description of a histogram.
Definition histogram.hpp:21
Declarative description of an info metric.
Definition info.hpp:16
Shared, reference-counted state behind every metric handle.
Definition metric_base.hpp:289
Unit unit_view() const
Build a non-owning view of the currently-known unit.
Definition metric_base.hpp:348
std::string help
Definition metric_base.hpp:294
std::string base_name
Definition metric_base.hpp:327
Labels base_labels
Definition metric_base.hpp:328
Labels const_labels
Definition metric_base.hpp:295
std::string name
Definition metric_base.hpp:293
MetricType type
Definition metric_base.hpp:290
std::shared_ptr< ScopeState > scope
Definition metric_base.hpp:326
A read-only snapshot describing one registered metric, returned by the enumeration APIs (Registry::me...
Definition registry.hpp:72
Labels const_labels
Definition registry.hpp:76
MetricType type
Definition registry.hpp:73
std::string name
Definition registry.hpp:74
bool scoped
Definition registry.hpp:78
std::string help
Definition registry.hpp:75
Unit unit
Definition registry.hpp:77
The decoration a Registry applies to every metric created through it: a name prefix,...
Definition registry.hpp:57
Labels const_labels
Merged into every metric's constant labels; a metric's own labels win on a name collision.
Definition registry.hpp:62
std::string prefix
Prepended to every metric name (e.g. "svc_").
Definition registry.hpp:59
comms::DisplayInfo display
Default display metadata; per-metric display fields override these.
Definition registry.hpp:64
The configuration a Scope applies to every metric created through it.
Definition scope.hpp:44
Declarative description of a state set.
Definition stateset.hpp:17
Declarative description of a summary.
Definition summary.hpp:19
OpenMetrics unit suffix plus optional dimensional metadata.
Definition unit.hpp:53
Declarative description of an untyped metric.
Definition untyped.hpp:14
Summary — streaming quantile summary, and SummarySpec.
Metric kinds (MetricType) and the OpenMetrics Unit descriptor.
Untyped — a bare value with no semantic constraints, and UntypedSpec.