userver: userver/utils/statistics/metric_value.hpp Source File
Loading...
Searching...
No Matches
metric_value.hpp
Go to the documentation of this file.
1#pragma once
2
3/// @file userver/utils/statistics/metric_value.hpp
4/// @brief @copybrief utils::statistics::MetricValue
5
6#include <cstdint>
7#include <type_traits>
8#include <variant>
9
10#include <fmt/format.h>
11
12#include <userver/utils/statistics/histogram_view.hpp>
13#include <userver/utils/statistics/rate.hpp>
14
15USERVER_NAMESPACE_BEGIN
16
17namespace utils::statistics {
18
19/// @ingroup userver_universal
20///
21/// @brief The value of a metric.
22///
23/// Cheap to copy, expected to be passed around by value.
24class MetricValue final {
25public:
26 using RawType = std::variant<std::int64_t, double, Rate, HistogramView>;
27
28 /// Creates an unspecified metric value.
29 constexpr MetricValue() noexcept : value_(std::int64_t{0}) {}
30
31 /// Constructs MetricValue for tests.
32 /// @{
33 constexpr /*implicit*/ MetricValue(std::int64_t value) noexcept : value_(value) {}
34
35 constexpr /*implicit*/ MetricValue(double value) noexcept : value_(value) {}
36
37 constexpr /*implicit*/ MetricValue(Rate value) noexcept : value_(value) {}
38
39 constexpr /*implicit*/ MetricValue(HistogramView value) noexcept : value_(value) {}
40 /// @}
41
42 // trivially copyable
43 MetricValue(const MetricValue&) = default;
44 MetricValue& operator=(const MetricValue&) = default;
45
46 friend bool operator==(const MetricValue& lhs, const MetricValue& rhs) noexcept { return lhs.value_ == rhs.value_; }
47
48 friend bool operator!=(const MetricValue& lhs, const MetricValue& rhs) noexcept { return lhs.value_ != rhs.value_; }
49
50 /// @brief Retrieve the value of an integer metric.
51 /// @throws std::exception on type mismatch.
52 std::int64_t AsInt() const { return std::get<std::int64_t>(value_); }
53
54 /// @brief Retrieve the value of a floating-point metric.
55 /// @throws std::exception on type mismatch.
56 double AsFloat() const { return std::get<double>(value_); }
57
58 /// @brief Retrieve the value of a Rate metric.
59 /// @throws std::exception on type mismatch.
60 Rate AsRate() const { return std::get<Rate>(value_); }
61
62 /// @brief Returns whether metric is Rate metric.
63 bool IsRate() const noexcept { return std::holds_alternative<Rate>(value_); }
64
65 /// @brief Retrieve the value of a HistogramView metric.
66 /// @throws std::exception on type mismatch.
67 HistogramView AsHistogram() const { return std::get<HistogramView>(value_); }
68
69 /// @brief Returns whether metric is HistogramView metric.
70 bool IsHistogram() const noexcept { return std::holds_alternative<HistogramView>(value_); }
71
72 /// @brief Calls @p visitor with either a `std::int64_t` or a `double` value.
73 /// @returns Whatever @p visitor returns.
74 template <typename VisitorFunc>
75 decltype(auto) Visit(VisitorFunc visitor) const {
76 return std::visit(visitor, value_);
77 }
78
79 /// @cond
80 explicit MetricValue(RawType value) noexcept : value_(value) {}
81 /// @endcond
82
83private:
84 RawType value_;
85};
86
87} // namespace utils::statistics
88
89USERVER_NAMESPACE_END
90
91template <>
92class fmt::formatter<USERVER_NAMESPACE::utils::statistics::MetricValue> {
93public:
94 constexpr auto parse(format_parse_context& ctx) { return ctx.begin(); }
95
96 template <typename FormatContext>
97 auto format(USERVER_NAMESPACE::utils::statistics::MetricValue value, FormatContext& ctx) const {
98 return value.Visit([&ctx](auto x) { return fmt::format_to(ctx.out(), "{}", x); });
99 }
100};