userver: userver/utils/statistics/fmt.hpp Source File
Loading...
Searching...
No Matches
fmt.hpp
Go to the documentation of this file.
1#pragma once
2
3/// @file userver/utils/statistics/fmt.hpp
4/// @brief fmt formatters for various statistics types
5///
6/// - utils::statistics::LabelView
7/// - utils::statistics::Label
8/// - utils::statistics::LabelsSpan
9/// - utils::statistics::MetricValue
10
11#include <variant>
12
13#include <fmt/format.h>
14#include <fmt/ranges.h>
15
16#include <userver/utils/fmt_compat.hpp>
17#include <userver/utils/overloaded.hpp>
18#include <userver/utils/statistics/labels.hpp>
19#include <userver/utils/statistics/metric_value.hpp>
20#include <userver/utils/statistics/rate.hpp>
21
22template <>
23struct fmt::formatter<USERVER_NAMESPACE::utils::statistics::LabelView> {
24 constexpr static auto parse(format_parse_context& ctx) { return ctx.begin(); }
25
26 template <typename FormatContext>
27 auto format(USERVER_NAMESPACE::utils::statistics::LabelView value, FormatContext& ctx) const {
28 return fmt::format_to(ctx.out(), "{}={}", value.Name(), value.Value());
29 }
30};
31
32template <>
33struct fmt::formatter<USERVER_NAMESPACE::utils::statistics::Label>
34 : public fmt::formatter<USERVER_NAMESPACE::utils::statistics::LabelView> {
35 template <typename FormatContext>
36 auto format(const USERVER_NAMESPACE::utils::statistics::Label& value, FormatContext& ctx) const {
37 return formatter<USERVER_NAMESPACE::utils::statistics::LabelView>::format(
38 USERVER_NAMESPACE::utils::statistics::LabelView{value},
39 ctx
40 );
41 }
42};
43
44template <>
45struct fmt::formatter<USERVER_NAMESPACE::utils::statistics::LabelsSpan> {
46 constexpr static auto parse(format_parse_context& ctx) { return ctx.begin(); }
47
48 template <typename FormatContext>
49 auto format(USERVER_NAMESPACE::utils::statistics::LabelsSpan value, FormatContext& ctx) const {
50 return fmt::format_to(ctx.out(), "{}", fmt::join(value, ";"));
51 }
52};
53
54template <>
55class fmt::formatter<USERVER_NAMESPACE::utils::statistics::Rate> {
56public:
57 constexpr auto parse(format_parse_context& ctx) { return rate_format_.parse(ctx); }
58
59 template <typename FormatCtx>
60 auto format(const USERVER_NAMESPACE::utils::statistics::Rate& rate, FormatCtx& ctx) const {
61 return rate_format_.format(rate.value, ctx);
62 }
63
64private:
65 fmt::formatter<USERVER_NAMESPACE::utils::statistics::Rate::ValueType> rate_format_;
66};
67
68template <>
69struct fmt::formatter<USERVER_NAMESPACE::utils::statistics::HistogramView> {
70 // NOLINTNEXTLINE(readability-convert-member-functions-to-static)
71 constexpr auto parse(format_parse_context& ctx) { return ctx.begin(); }
72
73 template <typename FormatCtx>
74 auto format(USERVER_NAMESPACE::utils::statistics::HistogramView histogram, FormatCtx& ctx) const {
75 const auto bucket_count = histogram.GetBucketCount();
76 for (std::size_t i = 0; i < bucket_count; ++i) {
77 ctx.advance_to(fmt::format_to(ctx.out(), "[{}]={}", histogram.GetUpperBoundAt(i), histogram.GetValueAt(i)));
78 ctx.advance_to(fmt::format_to(ctx.out(), ","));
79 }
80 ctx.advance_to(fmt::format_to(ctx.out(), "[inf]={}", histogram.GetValueAtInf()));
81 return ctx.out();
82 }
83};
84
85template <>
86class fmt::formatter<USERVER_NAMESPACE::utils::statistics::MetricValue> {
87public:
88 constexpr auto parse(format_parse_context& ctx) {
89 // To avoid including heavy <algorithm> header.
90 const auto max = [](auto a, auto b) { return a > b ? a : b; };
91 return max(
92 int_format_.parse(ctx),
93 max(float_format_.parse(ctx), max(rate_format_.parse(ctx), histogram_format_.parse(ctx)))
94 );
95 }
96
97 template <typename FormatContext>
98 auto format(USERVER_NAMESPACE::utils::statistics::MetricValue value, FormatContext& ctx) const {
99 return value.Visit(USERVER_NAMESPACE::utils::Overloaded{
100 [&](std::int64_t x) { return int_format_.format(x, ctx); },
101 [&](USERVER_NAMESPACE::utils::statistics::Rate x) { return rate_format_.format(x.value, ctx); },
102 [&](double x) { return float_format_.format(x, ctx); },
103 [&](USERVER_NAMESPACE::utils::statistics::HistogramView x) { return histogram_format_.format(x, ctx); }
104 });
105 }
106
107private:
108 // TODO use fmt::formatter<std::variant> when fmt 9 becomes available.
109 fmt::formatter<std::int64_t> int_format_;
110 fmt::formatter<USERVER_NAMESPACE::utils::statistics::Rate::ValueType> rate_format_;
111 fmt::formatter<double> float_format_;
112 fmt::formatter<USERVER_NAMESPACE::utils::statistics::HistogramView> histogram_format_;
113};