10#include <userver/utils/statistics/histogram_view.hpp>
11#include <userver/utils/statistics/labels.hpp>
12#include <userver/utils/statistics/rate.hpp>
14USERVER_NAMESPACE_BEGIN
16namespace utils::statistics {
25template <
class Metric>
26constexpr auto HasDumpMetricWriter()
noexcept
27 ->
decltype(DumpMetric(std::declval<Writer&>(),
28 std::declval<
const Metric&>()),
33template <
class Metric,
class... Args>
34constexpr auto HasDumpMetricWriter(Args...)
noexcept {
35 return std::is_arithmetic_v<Metric>;
91 Writer(Writer&& other) =
delete;
92 Writer(
const Writer&) =
delete;
93 Writer& operator=(Writer&&) =
delete;
94 Writer& operator=(
const Writer&) =
delete;
99 [[nodiscard]] Writer
operator[](std::string_view path) &;
102 [[nodiscard]] Writer
operator[](std::string_view path) &&;
108 if constexpr (std::is_arithmetic_v<T> ||
109 std::is_same_v<std::decay_t<T>, Rate> ||
110 std::is_same_v<std::decay_t<T>, HistogramView> ||
111 std::is_same_v<std::decay_t<T>, MetricValue>) {
115 static_assert(kHasWriterSupport<T>,
116 "Cast the metric to an arithmetic type or provide a "
117 "`void DumpMetric(utils::statistics::Writer& writer, "
118 "const Metric& value)` function for the `Metric` type");
119 DumpMetric(*
this, value);
127 auto new_writer = MakeChild();
128 new_writer.AppendLabelsSpan(labels);
135 ValueWithLabels(value, LabelsSpan{il});
141 ValueWithLabels(value, LabelsSpan{&label, &label + 1});
147 explicit operator bool()
const noexcept {
return !!state_; }
150 explicit Writer(impl::WriterState* state)
noexcept;
151 explicit Writer(impl::WriterState& state, LabelsSpan labels);
155 using ULongLong =
unsigned long long;
157 using PathSizeType = std::uint16_t;
158 using LabelsSizeType = std::uint8_t;
160 void Write(
unsigned long long value);
161 void Write(
long long value);
162 void Write(
double value);
163 void Write(
Rate value);
164 void Write(HistogramView value);
165 void Write(MetricValue value);
167 void Write(
float value) { Write(
static_cast<
double>(value)); }
169 void Write(
unsigned long value) { Write(
static_cast<ULongLong>(value)); }
170 void Write(
long value) { Write(
static_cast<
long long>(value)); }
171 void Write(
unsigned int value) { Write(
static_cast<
long long>(value)); }
172 void Write(
int value) { Write(
static_cast<
long long>(value)); }
173 void Write(
unsigned short value) { Write(
static_cast<
long long>(value)); }
174 void Write(
short value) { Write(
static_cast<
long long>(value)); }
179 Writer(Writer& other, MoveTag)
noexcept;
181 Writer MoveOut()
noexcept {
return Writer{*
this, MoveTag{}}; }
183 void ResetState()
noexcept;
184 void ValidateUsage();
186 void AppendPath(std::string_view path);
187 void AppendLabelsSpan(LabelsSpan labels);
189 impl::WriterState* state_;
190 const PathSizeType initial_path_size_;
191 PathSizeType current_path_size_;
192 const LabelsSizeType initial_labels_size_;
193 LabelsSizeType current_labels_size_;
196template <
class Metric>
197void DumpMetric(Writer& writer,
const std::atomic<Metric>& m) {
198 static_assert(std::atomic<Metric>::is_always_lock_free,
"std::atomic misuse");