mirror of
https://github.com/XRPLF/clio.git
synced 2026-07-29 01:50:29 +00:00
138 lines
3.6 KiB
C++
138 lines
3.6 KiB
C++
#pragma once
|
|
|
|
#include "util/Assert.hpp"
|
|
#include "util/prometheus/MetricBase.hpp"
|
|
#include "util/prometheus/OStream.hpp"
|
|
#include "util/prometheus/impl/HistogramImpl.hpp"
|
|
|
|
#include <cstdint>
|
|
#include <memory>
|
|
#include <string>
|
|
#include <type_traits>
|
|
#include <utility>
|
|
#include <vector>
|
|
|
|
namespace util::prometheus {
|
|
|
|
/**
|
|
* @brief A Prometheus histogram metric with a generic value type
|
|
*
|
|
* @tparam NumberType The number type of the histogram
|
|
*/
|
|
template <SomeNumberType NumberType>
|
|
class AnyHistogram : public MetricBase {
|
|
public:
|
|
using ValueType = NumberType;
|
|
using Buckets = std::vector<NumberType>;
|
|
|
|
/**
|
|
* @brief Construct a new Histogram object
|
|
*
|
|
* @tparam ImplType The type of the implementation of the histogram
|
|
* @param name The name of the metric
|
|
* @param labelsString The labels of the metric in serialized format, e.g.
|
|
* {name="value",name2="value2"}
|
|
* @param buckets The buckets of the histogram
|
|
* @param impl The implementation of the histogram (has default value and need to be specified
|
|
* only for testing)
|
|
*/
|
|
template <impl::SomeHistogramImpl ImplType = impl::HistogramImpl<ValueType>>
|
|
requires std::same_as<ValueType, typename std::remove_cvref_t<ImplType>::ValueType>
|
|
AnyHistogram(
|
|
std::string name,
|
|
std::string labelsString,
|
|
Buckets const& buckets,
|
|
ImplType&& impl = ImplType{}
|
|
)
|
|
: MetricBase(std::move(name), std::move(labelsString))
|
|
, pimpl_(std::make_unique<Model<ImplType>>(std::forward<ImplType>(impl)))
|
|
{
|
|
ASSERT(!buckets.empty(), "Histogram must have at least one bucket.");
|
|
ASSERT(
|
|
std::is_sorted(buckets.begin(), buckets.end()), "Buckets for histogra must be sorted."
|
|
);
|
|
pimpl_->setBuckets(buckets);
|
|
}
|
|
|
|
/**
|
|
* @brief Add a value to the histogram
|
|
*
|
|
* @param value The value to add
|
|
*/
|
|
void
|
|
observe(ValueType const value)
|
|
{
|
|
pimpl_->observe(value);
|
|
}
|
|
|
|
/**
|
|
* @brief Serialize the metric to a string in Prometheus format
|
|
*
|
|
* @param stream The stream to serialize into
|
|
*/
|
|
void
|
|
serializeValue(OStream& stream) const override
|
|
{
|
|
pimpl_->serializeValue(name(), labelsString(), stream);
|
|
}
|
|
|
|
private:
|
|
struct Concept {
|
|
virtual ~Concept() = default;
|
|
|
|
virtual void observe(NumberType) = 0;
|
|
|
|
virtual void
|
|
setBuckets(Buckets const& buckets) = 0;
|
|
|
|
virtual void
|
|
serializeValue(
|
|
std::string const& name,
|
|
std::string const& labelsString,
|
|
OStream&
|
|
) const = 0;
|
|
};
|
|
|
|
template <impl::SomeHistogramImpl ImplType>
|
|
requires std::same_as<NumberType, typename std::remove_cvref_t<ImplType>::ValueType>
|
|
struct Model : Concept {
|
|
template <typename SomeImplType>
|
|
requires std::same_as<SomeImplType, ImplType>
|
|
Model(SomeImplType&& impl) : impl_(std::forward<SomeImplType>(impl))
|
|
{
|
|
}
|
|
|
|
void
|
|
observe(NumberType value) override
|
|
{
|
|
impl_.observe(value);
|
|
}
|
|
|
|
void
|
|
setBuckets(Buckets const& buckets) override
|
|
{
|
|
impl_.setBuckets(buckets);
|
|
}
|
|
|
|
void
|
|
serializeValue(
|
|
std::string const& name,
|
|
std::string const& labelsString,
|
|
OStream& stream
|
|
) const override
|
|
{
|
|
impl_.serializeValue(name, labelsString, stream);
|
|
}
|
|
|
|
private:
|
|
ImplType impl_;
|
|
};
|
|
|
|
std::unique_ptr<Concept> pimpl_;
|
|
};
|
|
|
|
using HistogramInt = AnyHistogram<std::int64_t>;
|
|
using HistogramDouble = AnyHistogram<double>;
|
|
|
|
} // namespace util::prometheus
|