userver: utils::statistics::MonotonicByLabelStorage< Labels, Metric > Class Template Reference
Loading...
Searching...
No Matches
utils::statistics::MonotonicByLabelStorage< Labels, Metric > Class Template Referencefinal

#include <userver/utils/statistics/by_label_storage.hpp>

Detailed Description

template<typename Labels, typename Metric>
requires impl::LabelsAggregate<Labels>
class utils::statistics::MonotonicByLabelStorage< Labels, Metric >

Thread-safe monotonic storage of metrics indexed by label values.

See Statistics and Metrics .

Labels must be an aggregate type where all fields are convertible to std::string_view, by at least one of:

  • a (possibly explicit) conversion operator to std::string_view;
  • an ADL-found std::string_view ToStringView(const Field&) function.

This includes std::string_view itself, utils::Required<std::string_view>, std::string, utils::StrongTypedef, code-generated enums, etc.

Label names are taken from Labels field names.

Items can only be added, never removed.

Warning
Avoid storing high-cardinality values as labels, especially when the client input can directly customize label values. This can lead to security issues where clients can cause metrics quota exhaustion or crashes due to OOM errors.

Usage of MonotonicByLabelStorage

Define a labels struct with std::string_view fields:

struct RequestLabels {
utils::Required<std::string_view> source;
std::string_view status{"ok"};
};

Use utils::Required for fields without adequate defaults to make sure they are always provided.

Declare a utils::statistics::MetricTag for the storage:

// Needs to be `inline` if defined in a header.
kRequestsMetric{"my-service.requests"};

Write to the storage via Emplace:

auto& storage = metrics_storage.GetMetric(kRequestsMetric);
++storage[{.source = "frontend"}];
storage[{.source = "backend", .status = "error"}].Add(utils::statistics::Rate{3});

Usage of MonotonicByLabelStorage with a group of per-label metrics

Any dumpable type is supported as Metric. When multiple metrics have the same labels, declare a struct with metrics and create a storage of structs instead of creating multiple storages.

Define the metric struct and its DumpMetric:

struct EndpointMetrics {
RateCounter requests;
RateCounter errors;
};
[[maybe_unused]] void DumpMetric(utils::statistics::Writer& writer, const EndpointMetrics& m) {
writer["requests"] = m.requests;
writer["errors"] = m.errors;
}

Define the labels struct:

struct EndpointLabels {
utils::Required<std::string_view> endpoint;
};

Declare a utils::statistics::MetricTag for the storage:

// Needs to be `inline` if defined in a header.
kEndpointMetric{"my-service.endpoints"};

Write to the storage:

auto& storage = metrics_storage.GetMetric(kEndpointMetric);
auto& search = storage[{.endpoint = "/search"}];
++search.requests;
auto& order = storage[{.endpoint = "/order"}];
++order.requests;
++order.errors;

MonotonicByLabelStorage is also composable the other way around, it can be included in larger metric structures as a field.

Usage of MonotonicByLabelStorage with enum labels

An enum can be used as a label as long as it has ToStringView defined. Usage example:

enum class RequestType : std::uint8_t { kRead, kWrite };
[[maybe_unused]] std::string_view ToStringView(RequestType type) {
switch (type) {
case RequestType::kRead:
return "read";
case RequestType::kWrite:
return "write";
}
UINVARIANT(false, "Unknown RequestType");
}
struct TypedRequestLabels {
utils::Required<RequestType> type;
};
// Needs to be `inline` if defined in a header.
kTypedRequestsMetric{"my-service.typed-requests"};
auto& storage = metrics_storage.GetMetric(kTypedRequestsMetric);
++storage[{.type = RequestType::kRead}];
Template Parameters
LabelsAn aggregate type whose fields are convertible to std::string_view.
MetricThe metric type. Must support DumpMetric(Writer&, const Metric&).

Definition at line 247 of file by_label_storage.hpp.

Public Member Functions

 MonotonicByLabelStorage ()=default
 Create an empty storage.
 
 MonotonicByLabelStorage (MonotonicByLabelStorage &&)=delete
 
MonotonicByLabelStorageoperator= (MonotonicByLabelStorage &&)=delete
 
Metric & operator[] (const Labels &labels)
 Get or create a default-constructed metric for the given label values.
 
template<typename... Args>
requires std::constructible_from<Metric, Args...>
Metric & Emplace (const Labels &labels, Args &&... args)
 Get or create a metric for the given label values.
 
Metric * GetIfExists (const Labels &labels)
 Find a metric by label values without creating it.
 
void VisitAll (std::invocable< const Labels &, const Metric & > auto func) const
 Visit all stored metrics.
 

Member Function Documentation

◆ Emplace()

template<typename Labels, typename Metric>
template<typename... Args>
requires std::constructible_from<Metric, Args...>
Metric & utils::statistics::MonotonicByLabelStorage< Labels, Metric >::Emplace ( const Labels & labels,
Args &&... args )
inline

Get or create a metric for the given label values.

Parameters
labelsLabel values.
argsArguments forwarded to Metric constructor on first insertion.
Returns
Reference to the metric, valid until the storage's destruction.

Definition at line 270 of file by_label_storage.hpp.

◆ GetIfExists()

template<typename Labels, typename Metric>
Metric * utils::statistics::MonotonicByLabelStorage< Labels, Metric >::GetIfExists ( const Labels & labels)
inline

Find a metric by label values without creating it.

Returns
Pointer to the metric (valid until the storage's destruction), or nullptr if not found.

Definition at line 279 of file by_label_storage.hpp.

◆ operator[]()

template<typename Labels, typename Metric>
Metric & utils::statistics::MonotonicByLabelStorage< Labels, Metric >::operator[] ( const Labels & labels)
inline

Get or create a default-constructed metric for the given label values.

Parameters
labelsLabel values.
Returns
Reference to the metric, valid until the storage's destruction.

Definition at line 258 of file by_label_storage.hpp.

◆ VisitAll()

template<typename Labels, typename Metric>
void utils::statistics::MonotonicByLabelStorage< Labels, Metric >::VisitAll ( std::invocable< const Labels &, const Metric & > auto func) const
inline

Visit all stored metrics.

Requires that all fields of Labels are constructible from std::string_view.

Parameters
funcCallable accepting (const Labels&, const Metric&).

Definition at line 293 of file by_label_storage.hpp.

Friends And Related Symbol Documentation

◆ DumpMetric

template<typename Labels, typename Metric>
void DumpMetric ( Writer & writer,
const MonotonicByLabelStorage< Labels, Metric > & storage )
friend

Dump all metrics to a Writer, using label names from Labels fields.

Definition at line 301 of file by_label_storage.hpp.

◆ ResetMetric

template<typename Labels, typename Metric>
void ResetMetric ( MonotonicByLabelStorage< Labels, Metric > & storage)
friend

Reset all metrics (only available if Metric has ADL-found ResetMetric).

Definition at line 320 of file by_label_storage.hpp.


The documentation for this class was generated from the following file: