userver: userver/utils/statistics/fmt.hpp Source File
⚠️ This is the documentation for an old userver version. Click here to switch to the latest version.
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages Concepts
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
15#include <userver/utils/fmt_compat.hpp>
16#include <userver/utils/overloaded.hpp>
17#include <userver/utils/statistics/labels.hpp>
18#include <userver/utils/statistics/metric_value.hpp>
19#include <userver/utils/statistics/rate.hpp>
20
21template <>
22struct fmt::formatter<USERVER_NAMESPACE::utils::statistics::LabelView> {
23 constexpr static auto parse(format_parse_context& ctx) { return ctx.begin(); }
24
25 template <typename FormatContext>
26 auto format(USERVER_NAMESPACE::utils::statistics::LabelView value,
27 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,
37 FormatContext& ctx) const {
38 return formatter<USERVER_NAMESPACE::utils::statistics::LabelView>::format(
39 USERVER_NAMESPACE::utils::statistics::LabelView{value}, ctx);
40 }
41};
42
43template <>
44struct fmt::formatter<USERVER_NAMESPACE::utils::statistics::LabelsSpan> {
45 constexpr static auto parse(format_parse_context& ctx) { return ctx.begin(); }
46
47 template <typename FormatContext>
48 auto format(USERVER_NAMESPACE::utils::statistics::LabelsSpan value,
49 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> {
56 public:
57 constexpr auto parse(format_parse_context& ctx) {
58 return rate_format_.parse(ctx);
59 }
60
61 template <typename FormatCtx>
62 auto format(const USERVER_NAMESPACE::utils::statistics::Rate& rate,
63 FormatCtx& ctx) const {
64 return rate_format_.format(rate.value, ctx);
65 }
66
67 private:
68 fmt::formatter<USERVER_NAMESPACE::utils::statistics::Rate::ValueType>
69 rate_format_;
70};
71
72template <>
73struct fmt::formatter<USERVER_NAMESPACE::utils::statistics::HistogramView> {
74 // NOLINTNEXTLINE(readability-convert-member-functions-to-static)
75 constexpr auto parse(format_parse_context& ctx) { return ctx.begin(); }
76
77 template <typename FormatCtx>
78 auto format(USERVER_NAMESPACE::utils::statistics::HistogramView histogram,
79 FormatCtx& ctx) const {
80 const auto bucket_count = histogram.GetBucketCount();
81 for (std::size_t i = 0; i < bucket_count; ++i) {
82 ctx.advance_to(fmt::format_to(ctx.out(), "[{}]={}",
83 histogram.GetUpperBoundAt(i),
84 histogram.GetValueAt(i)));
85 ctx.advance_to(fmt::format_to(ctx.out(), ","));
86 }
87 ctx.advance_to(
88 fmt::format_to(ctx.out(), "[inf]={}", histogram.GetValueAtInf()));
89 return ctx.out();
90 }
91};
92
93template <>
94class fmt::formatter<USERVER_NAMESPACE::utils::statistics::MetricValue> {
95 public:
96 constexpr auto parse(format_parse_context& ctx) {
97 // To avoid including heavy <algorithm> header.
98 const auto max = [](auto a, auto b) { return a > b ? a : b; };
99 return max(int_format_.parse(ctx),
100 max(float_format_.parse(ctx),
101 max(rate_format_.parse(ctx), histogram_format_.parse(ctx))));
102 }
103
104 template <typename FormatContext>
105 auto format(USERVER_NAMESPACE::utils::statistics::MetricValue value,
106 FormatContext& ctx) const {
107 return value.Visit(USERVER_NAMESPACE::utils::Overloaded{
108 [&](std::int64_t x) { return int_format_.format(x, ctx); },
109 [&](USERVER_NAMESPACE::utils::statistics::Rate x) {
110 return rate_format_.format(x.value, ctx);
111 },
112 [&](double x) { return float_format_.format(x, ctx); },
113 [&](USERVER_NAMESPACE::utils::statistics::HistogramView x) {
114 return histogram_format_.format(x, ctx);
115 }});
116 }
117
118 private:
119 // TODO use fmt::formatter<std::variant> when fmt 9 becomes available.
120 fmt::formatter<std::int64_t> int_format_;
121 fmt::formatter<USERVER_NAMESPACE::utils::statistics::Rate::ValueType>
122 rate_format_;
123 fmt::formatter<double> float_format_;
124 fmt::formatter<USERVER_NAMESPACE::utils::statistics::HistogramView>
125 histogram_format_;
126};