Clio  develop
The XRP Ledger API server.
Loading...
Searching...
No Matches
Histogram.hpp
1//------------------------------------------------------------------------------
2/*
3 This file is part of clio: https://github.com/XRPLF/clio
4 Copyright (c) 2023, the clio developers.
5
6 Permission to use, copy, modify, and distribute this software for any
7 purpose with or without fee is hereby granted, provided that the above
8 copyright notice and this permission notice appear in all copies.
9
10 THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11 WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13 ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15 ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16 OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17*/
18//==============================================================================
19
20#pragma once
21
22#include "util/Assert.hpp"
23#include "util/prometheus/MetricBase.hpp"
24#include "util/prometheus/OStream.hpp"
25#include "util/prometheus/impl/HistogramImpl.hpp"
26
27#include <cstdint>
28#include <memory>
29#include <string>
30#include <type_traits>
31#include <utility>
32#include <vector>
33
34namespace util::prometheus {
35
41template <SomeNumberType NumberType>
42class AnyHistogram : public MetricBase {
43public:
44 using ValueType = NumberType;
45 using Buckets = std::vector<NumberType>;
46
58 template <impl::SomeHistogramImpl ImplType = impl::HistogramImpl<ValueType>>
59 requires std::same_as<ValueType, typename std::remove_cvref_t<ImplType>::ValueType>
61 std::string name,
62 std::string labelsString,
63 Buckets const& buckets,
64 ImplType&& impl = ImplType{}
65 )
66 : MetricBase(std::move(name), std::move(labelsString))
67 , pimpl_(std::make_unique<Model<ImplType>>(std::forward<ImplType>(impl)))
68 {
69 ASSERT(!buckets.empty(), "Histogram must have at least one bucket.");
70 ASSERT(
71 std::is_sorted(buckets.begin(), buckets.end()), "Buckets for histogra must be sorted."
72 );
73 pimpl_->setBuckets(buckets);
74 }
75
81 void
82 observe(ValueType const value)
83 {
84 pimpl_->observe(value);
85 }
86
92 void
93 serializeValue(OStream& stream) const override
94 {
95 pimpl_->serializeValue(name(), labelsString(), stream);
96 }
97
98private:
99 struct Concept {
100 virtual ~Concept() = default;
101
102 virtual void observe(NumberType) = 0;
103
104 virtual void
105 setBuckets(Buckets const& buckets) = 0;
106
107 virtual void
108 serializeValue(
109 std::string const& name,
110 std::string const& labelsString,
111 OStream&
112 ) const = 0;
113 };
114
115 template <impl::SomeHistogramImpl ImplType>
116 requires std::same_as<NumberType, typename std::remove_cvref_t<ImplType>::ValueType>
117 struct Model : Concept {
118 template <typename SomeImplType>
119 requires std::same_as<SomeImplType, ImplType>
120 Model(SomeImplType&& impl) : impl_(std::forward<SomeImplType>(impl))
121 {
122 }
123
124 void
125 observe(NumberType value) override
126 {
127 impl_.observe(value);
128 }
129
130 void
131 setBuckets(Buckets const& buckets) override
132 {
133 impl_.setBuckets(buckets);
134 }
135
136 void
137 serializeValue(
138 std::string const& name,
139 std::string const& labelsString,
140 OStream& stream
141 ) const override
142 {
143 impl_.serializeValue(name, labelsString, stream);
144 }
145
146 private:
147 ImplType impl_;
148 };
149
150 std::unique_ptr<Concept> pimpl_;
151};
152
153using HistogramInt = AnyHistogram<std::int64_t>;
154using HistogramDouble = AnyHistogram<double>;
155
156} // namespace util::prometheus
A Prometheus histogram metric with a generic value type.
Definition Histogram.hpp:42
AnyHistogram(std::string name, std::string labelsString, Buckets const &buckets, ImplType &&impl=ImplType{})
Construct a new Histogram object.
Definition Histogram.hpp:60
void observe(ValueType const value)
Add a value to the histogram.
Definition Histogram.hpp:82
void serializeValue(OStream &stream) const override
Serialize the metric to a string in Prometheus format.
Definition Histogram.hpp:93
Base class for a Prometheus metric containing a name and labels.
Definition MetricBase.hpp:31
MetricBase(std::string name, std::string labelsString)
Construct a new MetricBase object.
Definition MetricBase.cpp:30
std::string const & name() const
Get the name of the metric.
Definition MetricBase.cpp:67
std::string const & labelsString() const
Get the labels of the metric in serialized format, e.g. {name="value",name2="value2"}...
Definition MetricBase.cpp:73
A stream that can optionally compress its data.
Definition OStream.hpp:31