Export etl metrics to prometheus (#1256)

Fixes #1248.
This commit is contained in:
Sergey Kuznetsov
2024-03-14 11:37:31 +00:00
committed by GitHub
parent 010538d6fe
commit e83dfcbcc3
28 changed files with 708 additions and 51 deletions

View File

@@ -0,0 +1,89 @@
//------------------------------------------------------------------------------
/*
This file is part of clio: https://github.com/XRPLF/clio
Copyright (c) 2024, the clio developers.
Permission to use, copy, modify, and distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
//==============================================================================
#pragma once
#include "util/Assert.hpp"
#include "util/prometheus/Gauge.hpp"
#include <cstdint>
#include <functional>
namespace util::prometheus {
template <typename T>
concept SomeBoolImpl = requires(T a) {
{
a.set(0)
} -> std::same_as<void>;
{
a.value()
} -> std::same_as<int64_t>;
};
/**
* @brief A wrapped to provide bool interface for a Prometheus metric
* @note Prometheus does not have a native bool type, so we use a counter with a value of 0 or 1
*/
template <SomeBoolImpl ImplType>
class AnyBool {
std::reference_wrapper<ImplType> impl_;
public:
/**
* @brief Construct a bool metric
*
* @param impl The implementation of the metric
*/
explicit AnyBool(ImplType& impl) : impl_(impl)
{
}
/**
* @brief Set the value of the bool metric
*
* @param value The value to set
* @return A reference to the metric
*/
AnyBool&
operator=(bool value)
{
impl_.get().set(value ? 1 : 0);
return *this;
}
/**
* @brief Get the value of the bool metric
*
* @return The value of the metric
*/
operator bool() const
{
auto const value = impl_.get().value();
ASSERT(value == 0 || value == 1, "Invalid value for bool: {}", value);
return value == 1;
}
};
/**
* @brief Alias for Prometheus bool metric with GaugeInt implementation
*/
using Bool = AnyBool<GaugeInt>;
} // namespace util::prometheus

View File

@@ -83,6 +83,18 @@ struct AnyCounter : MetricBase, impl::AnyCounterBase<NumberType> {
return *this;
}
/**
* @brief Set the value of the counter
*
* @param value The value to set the counter to
*/
void
set(ValueType value)
{
ASSERT(value >= this->value(), "Cannot decrease a counter {}", this->name());
this->pimpl_->set(value);
}
/**
* @brief Reset the counter to zero
*/

View File

@@ -21,6 +21,7 @@
#include "util/Assert.hpp"
#include "util/config/Config.hpp"
#include "util/prometheus/Bool.hpp"
#include "util/prometheus/Counter.hpp"
#include "util/prometheus/Gauge.hpp"
#include "util/prometheus/Histogram.hpp"
@@ -52,6 +53,13 @@ convertBaseTo(MetricBase& metricBase)
} // namespace
Bool
PrometheusImpl::boolMetric(std::string name, Labels labels, std::optional<std::string> description)
{
auto& metric = gaugeInt(std::move(name), std::move(labels), std::move(description));
return Bool{metric};
}
CounterInt&
PrometheusImpl::counterInt(std::string name, Labels labels, std::optional<std::string> description)
{
@@ -175,6 +183,12 @@ PrometheusService::init(util::Config const& config)
instance_ = std::make_unique<util::prometheus::PrometheusImpl>(enabled, compressReply);
}
util::prometheus::Bool
PrometheusService::boolMetric(std::string name, util::prometheus::Labels labels, std::optional<std::string> description)
{
return instance().boolMetric(std::move(name), std::move(labels), std::move(description));
}
util::prometheus::CounterInt&
PrometheusService::counterInt(std::string name, util::prometheus::Labels labels, std::optional<std::string> description)
{

View File

@@ -20,6 +20,7 @@
#pragma once
#include "util/config/Config.hpp"
#include "util/prometheus/Bool.hpp"
#include "util/prometheus/Counter.hpp"
#include "util/prometheus/Gauge.hpp"
#include "util/prometheus/Histogram.hpp"
@@ -54,6 +55,18 @@ public:
virtual ~PrometheusInterface() = default;
/**
* @brief Get a bool based metric. It will be created if it doesn't exist
* @note Prometheus does not have a native bool type, so we use a counter with a value of 0 or 1
*
* @param name The name of the metric
* @param labels The labels of the metric
* @param description The description of the metric
* @return The bool object
*/
virtual Bool
boolMetric(std::string name, Labels labels, std::optional<std::string> description = std::nullopt) = 0;
/**
* @brief Get an integer based counter metric. It will be created if it doesn't exist
*
@@ -176,6 +189,9 @@ class PrometheusImpl : public PrometheusInterface {
public:
using PrometheusInterface::PrometheusInterface;
Bool
boolMetric(std::string name, Labels labels, std::optional<std::string> description = std::nullopt) override;
CounterInt&
counterInt(std::string name, Labels labels, std::optional<std::string> description) override;
@@ -242,6 +258,22 @@ public:
*/
void static init(util::Config const& config = util::Config{});
/**
* @brief Get a bool based metric. It will be created if it doesn't exist
* @note Prometheus does not have a native bool type, so we use a counter with a value of 0 or 1
*
* @param name The name of the metric
* @param labels The labels of the metric
* @param description The description of the metric
* @return The bool object
*/
static util::prometheus::Bool
boolMetric(
std::string name,
util::prometheus::Labels labels,
std::optional<std::string> description = std::nullopt
);
/**
* @brief Get an integer based counter metric. It will be created if it doesn't exist
*