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
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};