mirror of
https://github.com/XRPLF/clio.git
synced 2025-11-04 20:05:51 +00:00
@@ -18,6 +18,7 @@
|
||||
"editable": true,
|
||||
"fiscalYearStartMonth": 0,
|
||||
"graphTooltip": 0,
|
||||
"id": 1,
|
||||
"links": [],
|
||||
"liveNow": false,
|
||||
"panels": [
|
||||
@@ -85,9 +86,11 @@
|
||||
"fields": "",
|
||||
"values": false
|
||||
},
|
||||
"textMode": "auto"
|
||||
"showPercentChange": false,
|
||||
"textMode": "auto",
|
||||
"wideLayout": true
|
||||
},
|
||||
"pluginVersion": "10.2.0",
|
||||
"pluginVersion": "10.4.0",
|
||||
"targets": [
|
||||
{
|
||||
"datasource": {
|
||||
@@ -105,6 +108,372 @@
|
||||
"title": "Service state",
|
||||
"type": "stat"
|
||||
},
|
||||
{
|
||||
"datasource": {
|
||||
"type": "prometheus",
|
||||
"uid": "PBFA97CFB590B2093"
|
||||
},
|
||||
"fieldConfig": {
|
||||
"defaults": {
|
||||
"color": {
|
||||
"mode": "thresholds"
|
||||
},
|
||||
"mappings": [
|
||||
{
|
||||
"options": {
|
||||
"0": {
|
||||
"color": "blue",
|
||||
"index": 0,
|
||||
"text": "No"
|
||||
},
|
||||
"1": {
|
||||
"color": "green",
|
||||
"index": 1,
|
||||
"text": "Yes"
|
||||
}
|
||||
},
|
||||
"type": "value"
|
||||
}
|
||||
],
|
||||
"thresholds": {
|
||||
"mode": "absolute",
|
||||
"steps": [
|
||||
{
|
||||
"color": "green",
|
||||
"value": null
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"overrides": []
|
||||
},
|
||||
"gridPos": {
|
||||
"h": 8,
|
||||
"w": 3,
|
||||
"x": 3,
|
||||
"y": 0
|
||||
},
|
||||
"id": 14,
|
||||
"options": {
|
||||
"colorMode": "value",
|
||||
"graphMode": "area",
|
||||
"justifyMode": "auto",
|
||||
"orientation": "auto",
|
||||
"reduceOptions": {
|
||||
"calcs": [
|
||||
"lastNotNull"
|
||||
],
|
||||
"fields": "",
|
||||
"values": false
|
||||
},
|
||||
"showPercentChange": false,
|
||||
"textMode": "auto",
|
||||
"wideLayout": true
|
||||
},
|
||||
"pluginVersion": "10.4.0",
|
||||
"targets": [
|
||||
{
|
||||
"datasource": {
|
||||
"type": "prometheus",
|
||||
"uid": "PBFA97CFB590B2093"
|
||||
},
|
||||
"editorMode": "code",
|
||||
"expr": "read_only",
|
||||
"instant": false,
|
||||
"legendFormat": "__auto",
|
||||
"range": true,
|
||||
"refId": "A"
|
||||
}
|
||||
],
|
||||
"title": "Read only",
|
||||
"type": "stat"
|
||||
},
|
||||
{
|
||||
"datasource": {
|
||||
"type": "prometheus",
|
||||
"uid": "PBFA97CFB590B2093"
|
||||
},
|
||||
"fieldConfig": {
|
||||
"defaults": {
|
||||
"color": {
|
||||
"mode": "thresholds"
|
||||
},
|
||||
"mappings": [
|
||||
{
|
||||
"options": {
|
||||
"0": {
|
||||
"color": "blue",
|
||||
"index": 0,
|
||||
"text": "No"
|
||||
},
|
||||
"1": {
|
||||
"color": "green",
|
||||
"index": 1,
|
||||
"text": "Yes"
|
||||
}
|
||||
},
|
||||
"type": "value"
|
||||
}
|
||||
],
|
||||
"thresholds": {
|
||||
"mode": "absolute",
|
||||
"steps": [
|
||||
{
|
||||
"color": "green",
|
||||
"value": null
|
||||
},
|
||||
{
|
||||
"color": "red",
|
||||
"value": 80
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"overrides": []
|
||||
},
|
||||
"gridPos": {
|
||||
"h": 8,
|
||||
"w": 3,
|
||||
"x": 6,
|
||||
"y": 0
|
||||
},
|
||||
"id": 15,
|
||||
"options": {
|
||||
"colorMode": "value",
|
||||
"graphMode": "area",
|
||||
"justifyMode": "auto",
|
||||
"orientation": "auto",
|
||||
"reduceOptions": {
|
||||
"calcs": [
|
||||
"lastNotNull"
|
||||
],
|
||||
"fields": "",
|
||||
"values": false
|
||||
},
|
||||
"showPercentChange": false,
|
||||
"textMode": "auto",
|
||||
"wideLayout": true
|
||||
},
|
||||
"pluginVersion": "10.4.0",
|
||||
"targets": [
|
||||
{
|
||||
"datasource": {
|
||||
"type": "prometheus",
|
||||
"uid": "PBFA97CFB590B2093"
|
||||
},
|
||||
"editorMode": "code",
|
||||
"expr": "etl_writing",
|
||||
"instant": false,
|
||||
"legendFormat": "__auto",
|
||||
"range": true,
|
||||
"refId": "A"
|
||||
}
|
||||
],
|
||||
"title": "Writing data to DB",
|
||||
"type": "stat"
|
||||
},
|
||||
{
|
||||
"datasource": {
|
||||
"type": "prometheus",
|
||||
"uid": "PBFA97CFB590B2093"
|
||||
},
|
||||
"fieldConfig": {
|
||||
"defaults": {
|
||||
"color": {
|
||||
"mode": "thresholds"
|
||||
},
|
||||
"mappings": [
|
||||
{
|
||||
"options": {
|
||||
"0": {
|
||||
"color": "green",
|
||||
"index": 0,
|
||||
"text": "No"
|
||||
},
|
||||
"1": {
|
||||
"color": "red",
|
||||
"index": 1,
|
||||
"text": "Yes"
|
||||
}
|
||||
},
|
||||
"type": "value"
|
||||
}
|
||||
],
|
||||
"thresholds": {
|
||||
"mode": "absolute",
|
||||
"steps": [
|
||||
{
|
||||
"color": "green",
|
||||
"value": null
|
||||
},
|
||||
{
|
||||
"color": "red",
|
||||
"value": 80
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"overrides": []
|
||||
},
|
||||
"gridPos": {
|
||||
"h": 8,
|
||||
"w": 3,
|
||||
"x": 9,
|
||||
"y": 0
|
||||
},
|
||||
"id": 16,
|
||||
"options": {
|
||||
"colorMode": "value",
|
||||
"graphMode": "area",
|
||||
"justifyMode": "auto",
|
||||
"orientation": "auto",
|
||||
"reduceOptions": {
|
||||
"calcs": [
|
||||
"lastNotNull"
|
||||
],
|
||||
"fields": "",
|
||||
"values": false
|
||||
},
|
||||
"showPercentChange": false,
|
||||
"textMode": "auto",
|
||||
"wideLayout": true
|
||||
},
|
||||
"pluginVersion": "10.4.0",
|
||||
"targets": [
|
||||
{
|
||||
"datasource": {
|
||||
"type": "prometheus",
|
||||
"uid": "PBFA97CFB590B2093"
|
||||
},
|
||||
"editorMode": "code",
|
||||
"expr": "etl_amendment_blocked",
|
||||
"instant": false,
|
||||
"legendFormat": "__auto",
|
||||
"range": true,
|
||||
"refId": "A"
|
||||
}
|
||||
],
|
||||
"title": "Amendment blocked",
|
||||
"type": "stat"
|
||||
},
|
||||
{
|
||||
"datasource": {
|
||||
"type": "prometheus",
|
||||
"uid": "PBFA97CFB590B2093"
|
||||
},
|
||||
"fieldConfig": {
|
||||
"defaults": {
|
||||
"color": {
|
||||
"mode": "palette-classic"
|
||||
},
|
||||
"custom": {
|
||||
"axisBorderShow": false,
|
||||
"axisCenteredZero": false,
|
||||
"axisColorMode": "text",
|
||||
"axisLabel": "",
|
||||
"axisPlacement": "auto",
|
||||
"barAlignment": 0,
|
||||
"drawStyle": "line",
|
||||
"fillOpacity": 0,
|
||||
"gradientMode": "none",
|
||||
"hideFrom": {
|
||||
"legend": false,
|
||||
"tooltip": false,
|
||||
"viz": false
|
||||
},
|
||||
"insertNulls": false,
|
||||
"lineInterpolation": "linear",
|
||||
"lineWidth": 1,
|
||||
"pointSize": 5,
|
||||
"scaleDistribution": {
|
||||
"type": "linear"
|
||||
},
|
||||
"showPoints": "auto",
|
||||
"spanNulls": false,
|
||||
"stacking": {
|
||||
"group": "A",
|
||||
"mode": "none"
|
||||
},
|
||||
"thresholdsStyle": {
|
||||
"mode": "off"
|
||||
}
|
||||
},
|
||||
"mappings": [],
|
||||
"thresholds": {
|
||||
"mode": "absolute",
|
||||
"steps": [
|
||||
{
|
||||
"color": "green",
|
||||
"value": null
|
||||
},
|
||||
{
|
||||
"color": "red",
|
||||
"value": 80
|
||||
}
|
||||
]
|
||||
},
|
||||
"unit": "s"
|
||||
},
|
||||
"overrides": []
|
||||
},
|
||||
"gridPos": {
|
||||
"h": 8,
|
||||
"w": 12,
|
||||
"x": 12,
|
||||
"y": 0
|
||||
},
|
||||
"id": 13,
|
||||
"options": {
|
||||
"legend": {
|
||||
"calcs": [],
|
||||
"displayMode": "list",
|
||||
"placement": "bottom",
|
||||
"showLegend": true
|
||||
},
|
||||
"tooltip": {
|
||||
"mode": "single",
|
||||
"sort": "none"
|
||||
}
|
||||
},
|
||||
"targets": [
|
||||
{
|
||||
"datasource": {
|
||||
"type": "prometheus",
|
||||
"uid": "PBFA97CFB590B2093"
|
||||
},
|
||||
"editorMode": "code",
|
||||
"exemplar": false,
|
||||
"expr": "timestamp(etl_last_publish_seconds) - etl_last_publish_seconds",
|
||||
"format": "time_series",
|
||||
"instant": false,
|
||||
"legendFormat": "ledger age",
|
||||
"range": true,
|
||||
"refId": "A"
|
||||
}
|
||||
],
|
||||
"title": "Ledger Age",
|
||||
"transformations": [
|
||||
{
|
||||
"id": "filterByValue",
|
||||
"options": {
|
||||
"filters": [
|
||||
{
|
||||
"config": {
|
||||
"id": "lower",
|
||||
"options": {
|
||||
"value": 31500000
|
||||
}
|
||||
},
|
||||
"fieldName": "ledger age"
|
||||
}
|
||||
],
|
||||
"match": "all",
|
||||
"type": "include"
|
||||
}
|
||||
}
|
||||
],
|
||||
"type": "timeseries"
|
||||
},
|
||||
{
|
||||
"datasource": {
|
||||
"type": "prometheus",
|
||||
@@ -166,9 +535,9 @@
|
||||
},
|
||||
"gridPos": {
|
||||
"h": 8,
|
||||
"w": 9,
|
||||
"x": 3,
|
||||
"y": 0
|
||||
"w": 12,
|
||||
"x": 0,
|
||||
"y": 8
|
||||
},
|
||||
"id": 2,
|
||||
"options": {
|
||||
@@ -263,7 +632,7 @@
|
||||
"h": 8,
|
||||
"w": 12,
|
||||
"x": 12,
|
||||
"y": 0
|
||||
"y": 8
|
||||
},
|
||||
"id": 9,
|
||||
"options": {
|
||||
@@ -358,7 +727,7 @@
|
||||
"h": 8,
|
||||
"w": 12,
|
||||
"x": 0,
|
||||
"y": 8
|
||||
"y": 16
|
||||
},
|
||||
"id": 11,
|
||||
"options": {
|
||||
@@ -453,7 +822,7 @@
|
||||
"h": 8,
|
||||
"w": 12,
|
||||
"x": 12,
|
||||
"y": 8
|
||||
"y": 16
|
||||
},
|
||||
"id": 6,
|
||||
"options": {
|
||||
@@ -550,7 +919,7 @@
|
||||
"h": 8,
|
||||
"w": 12,
|
||||
"x": 0,
|
||||
"y": 16
|
||||
"y": 24
|
||||
},
|
||||
"id": 10,
|
||||
"options": {
|
||||
@@ -645,7 +1014,7 @@
|
||||
"h": 8,
|
||||
"w": 12,
|
||||
"x": 12,
|
||||
"y": 16
|
||||
"y": 24
|
||||
},
|
||||
"id": 8,
|
||||
"options": {
|
||||
@@ -740,7 +1109,7 @@
|
||||
"h": 8,
|
||||
"w": 12,
|
||||
"x": 0,
|
||||
"y": 24
|
||||
"y": 32
|
||||
},
|
||||
"id": 4,
|
||||
"options": {
|
||||
@@ -839,7 +1208,7 @@
|
||||
"h": 8,
|
||||
"w": 12,
|
||||
"x": 12,
|
||||
"y": 24
|
||||
"y": 32
|
||||
},
|
||||
"id": 12,
|
||||
"options": {
|
||||
@@ -973,7 +1342,7 @@
|
||||
"h": 8,
|
||||
"w": 12,
|
||||
"x": 0,
|
||||
"y": 32
|
||||
"y": 40
|
||||
},
|
||||
"id": 5,
|
||||
"options": {
|
||||
@@ -1081,7 +1450,7 @@
|
||||
"h": 8,
|
||||
"w": 12,
|
||||
"x": 12,
|
||||
"y": 32
|
||||
"y": 40
|
||||
},
|
||||
"id": 3,
|
||||
"options": {
|
||||
@@ -1186,9 +1555,9 @@
|
||||
},
|
||||
"gridPos": {
|
||||
"h": 8,
|
||||
"w": 10,
|
||||
"w": 12,
|
||||
"x": 0,
|
||||
"y": 40
|
||||
"y": 48
|
||||
},
|
||||
"id": 7,
|
||||
"options": {
|
||||
@@ -1222,7 +1591,7 @@
|
||||
}
|
||||
],
|
||||
"refresh": "5s",
|
||||
"schemaVersion": 38,
|
||||
"schemaVersion": 39,
|
||||
"tags": [],
|
||||
"templating": {
|
||||
"list": []
|
||||
@@ -1235,6 +1604,6 @@
|
||||
"timezone": "",
|
||||
"title": "Clio",
|
||||
"uid": "aeaae84e-c194-47b2-ad65-86e45eebb815",
|
||||
"version": 3,
|
||||
"version": 1,
|
||||
"weekStart": ""
|
||||
}
|
||||
|
||||
@@ -276,7 +276,7 @@ ETLService::ETLService(
|
||||
{
|
||||
startSequence_ = config.maybeValue<uint32_t>("start_sequence");
|
||||
finishSequence_ = config.maybeValue<uint32_t>("finish_sequence");
|
||||
state_.isReadOnly = config.valueOr("read_only", state_.isReadOnly);
|
||||
state_.isReadOnly = config.valueOr("read_only", static_cast<bool>(state_.isReadOnly));
|
||||
extractorThreads_ = config.valueOr<uint32_t>("extractor_threads", extractorThreads_);
|
||||
txnThreshold_ = config.valueOr<size_t>("txn_threshold", txnThreshold_);
|
||||
}
|
||||
|
||||
@@ -212,8 +212,8 @@ public:
|
||||
boost::json::object result;
|
||||
|
||||
result["etl_sources"] = loadBalancer_->toJson();
|
||||
result["is_writer"] = state_.isWriting.load();
|
||||
result["read_only"] = state_.isReadOnly;
|
||||
result["is_writer"] = static_cast<int>(state_.isWriting);
|
||||
result["read_only"] = static_cast<int>(state_.isReadOnly);
|
||||
auto last = ledgerPublisher_.getLastPublish();
|
||||
if (last.time_since_epoch().count() != 0)
|
||||
result["last_publish_age_seconds"] = std::to_string(ledgerPublisher_.lastPublishAgeSeconds());
|
||||
|
||||
@@ -19,6 +19,10 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "util/prometheus/Bool.hpp"
|
||||
#include "util/prometheus/Label.hpp"
|
||||
#include "util/prometheus/Prometheus.hpp"
|
||||
|
||||
#include <atomic>
|
||||
|
||||
namespace etl {
|
||||
@@ -33,9 +37,19 @@ struct SystemState {
|
||||
* In strict read-only mode, the process will never attempt to become the ETL writer, and will only publish ledgers
|
||||
* as they are written to the database.
|
||||
*/
|
||||
bool isReadOnly = false;
|
||||
util::prometheus::Bool isReadOnly = PrometheusService::boolMetric(
|
||||
"read_only",
|
||||
util::prometheus::Labels{},
|
||||
"Whether the process is in strict read-only mode"
|
||||
);
|
||||
|
||||
/** @brief Whether the process is writing to the database. */
|
||||
util::prometheus::Bool isWriting = PrometheusService::boolMetric(
|
||||
"etl_writing",
|
||||
util::prometheus::Labels{},
|
||||
"Whether the process is writing to the database"
|
||||
);
|
||||
|
||||
std::atomic_bool isWriting = false; /**< @brief Whether the process is writing to the database. */
|
||||
std::atomic_bool isStopping = false; /**< @brief Whether the software is stopping. */
|
||||
std::atomic_bool writeConflict = false; /**< @brief Whether a write conflict was detected. */
|
||||
|
||||
@@ -46,7 +60,11 @@ struct SystemState {
|
||||
* arrived from rippled and therefore can't extract the ledger diff. When this happens, Clio can't proceed with ETL
|
||||
* and should log this error and only handle RPC requests.
|
||||
*/
|
||||
std::atomic_bool isAmendmentBlocked = false;
|
||||
util::prometheus::Bool isAmendmentBlocked = PrometheusService::boolMetric(
|
||||
"etl_amendment_blocked",
|
||||
util::prometheus::Labels{},
|
||||
"Whether clio detected an amendment block"
|
||||
);
|
||||
};
|
||||
|
||||
} // namespace etl
|
||||
|
||||
@@ -25,6 +25,8 @@
|
||||
#include "etl/SystemState.hpp"
|
||||
#include "util/Assert.hpp"
|
||||
#include "util/log/Logger.hpp"
|
||||
#include "util/prometheus/Counter.hpp"
|
||||
#include "util/prometheus/Prometheus.hpp"
|
||||
|
||||
#include <boost/asio/io_context.hpp>
|
||||
#include <boost/asio/strand.hpp>
|
||||
@@ -75,8 +77,11 @@ class LedgerPublisher {
|
||||
std::chrono::time_point<ripple::NetClock> lastCloseTime_;
|
||||
mutable std::shared_mutex closeTimeMtx_;
|
||||
|
||||
std::chrono::time_point<std::chrono::system_clock> lastPublish_;
|
||||
mutable std::shared_mutex publishTimeMtx_;
|
||||
std::reference_wrapper<util::prometheus::CounterInt> lastPublishSeconds_ = PrometheusService::counterInt(
|
||||
"etl_last_publish_seconds",
|
||||
{},
|
||||
"Seconds since epoch of the last published ledger"
|
||||
);
|
||||
|
||||
std::optional<uint32_t> lastPublishedSequence_;
|
||||
mutable std::shared_mutex lastPublishedSeqMtx_;
|
||||
@@ -232,8 +237,8 @@ public:
|
||||
std::chrono::time_point<std::chrono::system_clock>
|
||||
getLastPublish() const
|
||||
{
|
||||
std::shared_lock const lck(publishTimeMtx_);
|
||||
return lastPublish_;
|
||||
return std::chrono::time_point<std::chrono::system_clock>{std::chrono::seconds{lastPublishSeconds_.get().value()
|
||||
}};
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -273,8 +278,9 @@ private:
|
||||
void
|
||||
setLastPublishTime()
|
||||
{
|
||||
std::scoped_lock const lck(publishTimeMtx_);
|
||||
lastPublish_ = std::chrono::system_clock::now();
|
||||
using namespace std::chrono;
|
||||
auto const nowSeconds = duration_cast<seconds>(system_clock::now().time_since_epoch()).count();
|
||||
lastPublishSeconds_.get().set(nowSeconds);
|
||||
}
|
||||
|
||||
void
|
||||
|
||||
89
src/util/prometheus/Bool.hpp
Normal file
89
src/util/prometheus/Bool.hpp
Normal 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
|
||||
@@ -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
|
||||
*/
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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
|
||||
*
|
||||
|
||||
@@ -97,6 +97,7 @@ target_sources(
|
||||
util/BatchingTests.cpp
|
||||
util/LedgerUtilsTests.cpp
|
||||
# Prometheus support
|
||||
util/prometheus/BoolTests.cpp
|
||||
util/prometheus/CounterTests.cpp
|
||||
util/prometheus/GaugeTests.cpp
|
||||
util/prometheus/HistogramTests.cpp
|
||||
|
||||
@@ -19,7 +19,6 @@
|
||||
|
||||
#include "util/TerminationHandler.hpp"
|
||||
#include "util/TestGlobals.hpp"
|
||||
#include "util/prometheus/Prometheus.hpp"
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
@@ -33,7 +32,6 @@ int
|
||||
main(int argc, char* argv[])
|
||||
{
|
||||
util::setTerminationHandler();
|
||||
PrometheusService::init();
|
||||
testing::InitGoogleTest(&argc, argv);
|
||||
TestGlobals::instance().parse(argc, argv);
|
||||
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
#include "etl/impl/AmendmentBlock.hpp"
|
||||
#include "util/FakeAmendmentBlockAction.hpp"
|
||||
#include "util/Fixtures.hpp"
|
||||
#include "util/MockPrometheus.hpp"
|
||||
|
||||
#include <boost/asio/io_context.hpp>
|
||||
#include <gtest/gtest.h>
|
||||
@@ -32,8 +33,7 @@
|
||||
using namespace testing;
|
||||
using namespace etl;
|
||||
|
||||
class AmendmentBlockHandlerTest : public NoLoggerFixture {
|
||||
protected:
|
||||
struct AmendmentBlockHandlerTest : util::prometheus::WithPrometheus, NoLoggerFixture {
|
||||
using AmendmentBlockHandlerType = impl::AmendmentBlockHandler<FakeAmendmentBlockAction>;
|
||||
|
||||
boost::asio::io_context ioc_;
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
#include "etl/impl/FakeDiffProvider.hpp"
|
||||
#include "util/Fixtures.hpp"
|
||||
#include "util/MockCache.hpp"
|
||||
#include "util/MockPrometheus.hpp"
|
||||
#include "util/async/context/BasicExecutionContext.hpp"
|
||||
#include "util/config/Config.hpp"
|
||||
|
||||
@@ -43,7 +44,7 @@ namespace {
|
||||
|
||||
constexpr auto SEQ = 30;
|
||||
|
||||
struct CacheLoaderTest : MockBackendTest {
|
||||
struct CacheLoaderTest : util::prometheus::WithPrometheus, MockBackendTest {
|
||||
void
|
||||
SetUp() override
|
||||
{
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
#include "etl/impl/CursorProvider.hpp"
|
||||
#include "etl/impl/FakeDiffProvider.hpp"
|
||||
#include "util/Fixtures.hpp"
|
||||
#include "util/MockPrometheus.hpp"
|
||||
|
||||
#include <gmock/gmock.h>
|
||||
#include <gtest/gtest.h>
|
||||
@@ -36,7 +37,7 @@ namespace {
|
||||
|
||||
constexpr auto SEQ = 30;
|
||||
|
||||
struct CursorProviderTest : MockBackendTestNaggy {
|
||||
struct CursorProviderTest : util::prometheus::WithPrometheus, MockBackendTestNaggy {
|
||||
DiffProvider diffProvider;
|
||||
};
|
||||
struct ParametrizedCursorProviderTest : CursorProviderTest, WithParamInterface<std::size_t> {};
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
#include "util/MockExtractionDataPipe.hpp"
|
||||
#include "util/MockLedgerFetcher.hpp"
|
||||
#include "util/MockNetworkValidatedLedgers.hpp"
|
||||
#include "util/MockPrometheus.hpp"
|
||||
|
||||
#include <gmock/gmock.h>
|
||||
#include <gtest/gtest.h>
|
||||
@@ -34,8 +35,7 @@
|
||||
using namespace testing;
|
||||
using namespace etl;
|
||||
|
||||
class ETLExtractorTest : public NoLoggerFixture {
|
||||
protected:
|
||||
struct ETLExtractorTest : util::prometheus::WithPrometheus, NoLoggerFixture {
|
||||
using ExtractionDataPipeType = MockExtractionDataPipe;
|
||||
using LedgerFetcherType = MockLedgerFetcher;
|
||||
using ExtractorType = etl::impl::Extractor<ExtractionDataPipeType, MockNetworkValidatedLedgers, LedgerFetcherType>;
|
||||
@@ -48,7 +48,6 @@ protected:
|
||||
|
||||
std::unique_ptr<ExtractorType> extractor_;
|
||||
|
||||
public:
|
||||
void
|
||||
SetUp() override
|
||||
{
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
#include "etl/impl/GrpcSource.hpp"
|
||||
#include "util/Fixtures.hpp"
|
||||
#include "util/MockBackend.hpp"
|
||||
#include "util/MockPrometheus.hpp"
|
||||
#include "util/MockXrpLedgerAPIService.hpp"
|
||||
#include "util/TestObject.hpp"
|
||||
#include "util/config/Config.hpp"
|
||||
@@ -39,7 +40,9 @@
|
||||
|
||||
using namespace etl::impl;
|
||||
|
||||
struct GrpcSourceTests : NoLoggerFixture, unittests::util::WithMockXrpLedgerAPIService {
|
||||
struct GrpcSourceTests : NoLoggerFixture,
|
||||
util::prometheus::WithPrometheus,
|
||||
unittests::util::WithMockXrpLedgerAPIService {
|
||||
GrpcSourceTests()
|
||||
: WithMockXrpLedgerAPIService("localhost:50051")
|
||||
, mockBackend_(std::make_shared<testing::StrictMock<MockBackend>>(util::Config{}))
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
#include "etl/impl/LedgerPublisher.hpp"
|
||||
#include "util/Fixtures.hpp"
|
||||
#include "util/MockCache.hpp"
|
||||
#include "util/MockPrometheus.hpp"
|
||||
#include "util/MockSubscriptionManager.hpp"
|
||||
#include "util/TestObject.hpp"
|
||||
#include "util/config/Config.hpp"
|
||||
@@ -49,7 +50,10 @@ static auto constexpr LEDGERHASH = "4BC50C9B0D8515D3EAAE1E74B29A95804346C491EE1A
|
||||
static auto constexpr SEQ = 30;
|
||||
static auto constexpr AGE = 800;
|
||||
|
||||
class ETLLedgerPublisherTest : public MockBackendTest, public SyncAsioContextTest, public MockSubscriptionManagerTest {
|
||||
struct ETLLedgerPublisherTest : util::prometheus::WithPrometheus,
|
||||
MockBackendTest,
|
||||
SyncAsioContextTest,
|
||||
MockSubscriptionManagerTest {
|
||||
void
|
||||
SetUp() override
|
||||
{
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
#include "util/MockExtractionDataPipe.hpp"
|
||||
#include "util/MockLedgerLoader.hpp"
|
||||
#include "util/MockLedgerPublisher.hpp"
|
||||
#include "util/MockPrometheus.hpp"
|
||||
#include "util/StringUtils.hpp"
|
||||
|
||||
#include <gmock/gmock.h>
|
||||
@@ -46,8 +47,7 @@ constexpr static auto RAW_HEADER =
|
||||
"3E2232B33EF57CECAC2816E3122816E31A0A00F8377CD95DFA484CFAE282656A58"
|
||||
"CE5AA29652EFFD80AC59CD91416E4E13DBBE";
|
||||
|
||||
class ETLTransformerTest : public MockBackendTest {
|
||||
protected:
|
||||
struct ETLTransformerTest : util::prometheus::WithPrometheus, MockBackendTest {
|
||||
using DataType = FakeFetchResponse;
|
||||
using ExtractionDataPipeType = MockExtractionDataPipe;
|
||||
using LedgerLoaderType = MockLedgerLoader;
|
||||
@@ -64,7 +64,6 @@ protected:
|
||||
|
||||
std::unique_ptr<TransformerType> transformer_;
|
||||
|
||||
public:
|
||||
void
|
||||
SetUp() override
|
||||
{
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "util/Fixtures.hpp"
|
||||
#include "util/MockPrometheus.hpp"
|
||||
#include "util/MockWsBase.hpp"
|
||||
#include "web/interface/ConnectionBase.hpp"
|
||||
|
||||
@@ -33,7 +34,7 @@
|
||||
|
||||
// Base class for feed tests, providing easy way to access the received feed
|
||||
template <typename TestedFeed>
|
||||
class FeedBaseTest : public SyncAsioContextTest, public MockBackendTest {
|
||||
class FeedBaseTest : public util::prometheus::WithPrometheus, public SyncAsioContextTest, public MockBackendTest {
|
||||
protected:
|
||||
std::shared_ptr<web::ConnectionBase> sessionPtr;
|
||||
std::shared_ptr<TestedFeed> testFeedPtr;
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
#include "feed/FeedTestUtil.hpp"
|
||||
#include "feed/SubscriptionManager.hpp"
|
||||
#include "util/Fixtures.hpp"
|
||||
#include "util/MockPrometheus.hpp"
|
||||
#include "util/MockWsBase.hpp"
|
||||
#include "util/TestObject.hpp"
|
||||
#include "web/interface/ConnectionBase.hpp"
|
||||
@@ -52,7 +53,9 @@ namespace json = boost::json;
|
||||
using namespace feed;
|
||||
using namespace feed::impl;
|
||||
|
||||
class SubscriptionManagerTest : public MockBackendTest, public SyncAsioContextTest {
|
||||
class SubscriptionManagerTest : public util::prometheus::WithPrometheus,
|
||||
public MockBackendTest,
|
||||
public SyncAsioContextTest {
|
||||
protected:
|
||||
std::shared_ptr<SubscriptionManager> SubscriptionManagerPtr;
|
||||
std::shared_ptr<web::ConnectionBase> session;
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
#include "rpc/RPCHelpers.hpp"
|
||||
#include "rpc/common/Types.hpp"
|
||||
#include "util/Fixtures.hpp"
|
||||
#include "util/MockPrometheus.hpp"
|
||||
#include "util/TestObject.hpp"
|
||||
|
||||
#include <boost/asio/impl/spawn.hpp>
|
||||
@@ -57,7 +58,7 @@ constexpr static auto INDEX1 = "E6DBAFC99223B42257915A63DFC6B0C032D4070F9A574B25
|
||||
constexpr static auto INDEX2 = "E6DBAFC99223B42257915A63DFC6B0C032D4070F9A574B255AD97466726FC322";
|
||||
constexpr static auto TXNID = "E6DBAFC99223B42257915A63DFC6B0C032D4070F9A574B255AD97466726FC321";
|
||||
|
||||
class RPCHelpersTest : public MockBackendTest, public SyncAsioContextTest {
|
||||
class RPCHelpersTest : public util::prometheus::WithPrometheus, public MockBackendTest, public SyncAsioContextTest {
|
||||
void
|
||||
SetUp() override
|
||||
{
|
||||
|
||||
@@ -25,7 +25,6 @@
|
||||
#include "rpc/common/Types.hpp"
|
||||
#include "rpc/handlers/Subscribe.hpp"
|
||||
#include "util/Fixtures.hpp"
|
||||
#include "util/MockPrometheus.hpp"
|
||||
#include "util/MockWsBase.hpp"
|
||||
#include "util/TestObject.hpp"
|
||||
#include "web/interface/ConnectionBase.hpp"
|
||||
@@ -62,7 +61,7 @@ constexpr static auto PAYS20XRPGETS10USDBOOKDIR = "7B1767D41DBCE79D9585CF9D0262A
|
||||
constexpr static auto INDEX1 = "1B8590C01B0006EDFA9ED60296DD052DC5E90F99659B25014D08E1BC983515BC";
|
||||
constexpr static auto INDEX2 = "E6DBAFC99223B42257915A63DFC6B0C032D4070F9A574B255AD97466726FC321";
|
||||
|
||||
class RPCSubscribeHandlerTest : public util::prometheus::WithPrometheus, public HandlerBaseTest {
|
||||
class RPCSubscribeHandlerTest : public HandlerBaseTest {
|
||||
protected:
|
||||
void
|
||||
SetUp() override
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
#include "util/MockCounters.hpp"
|
||||
#include "util/MockETLService.hpp"
|
||||
#include "util/MockLoadBalancer.hpp"
|
||||
#include "util/MockPrometheus.hpp"
|
||||
#include "util/MockSubscriptionManager.hpp"
|
||||
#include "util/log/Logger.hpp"
|
||||
|
||||
@@ -349,6 +350,7 @@ protected:
|
||||
*/
|
||||
template <template <typename> typename MockType = ::testing::NiceMock>
|
||||
struct HandlerBaseTestBase : public MockBackendTestBase<MockType>,
|
||||
public util::prometheus::WithPrometheus,
|
||||
public SyncAsioContextTest,
|
||||
public MockETLServiceTest {
|
||||
protected:
|
||||
|
||||
@@ -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"
|
||||
@@ -81,6 +82,10 @@ using MockHistogramImplDouble = MockHistogramImpl<double>;
|
||||
struct MockPrometheusImpl : PrometheusInterface {
|
||||
MockPrometheusImpl() : PrometheusInterface(true, true)
|
||||
{
|
||||
EXPECT_CALL(*this, boolMetric)
|
||||
.WillRepeatedly([this](std::string name, Labels labels, std::optional<std::string>) -> Bool {
|
||||
return Bool{getMetric<GaugeInt>(std::move(name), std::move(labels))};
|
||||
});
|
||||
EXPECT_CALL(*this, counterInt)
|
||||
.WillRepeatedly([this](std::string name, Labels labels, std::optional<std::string>) -> CounterInt& {
|
||||
return getMetric<CounterInt>(std::move(name), std::move(labels));
|
||||
@@ -109,6 +114,7 @@ struct MockPrometheusImpl : PrometheusInterface {
|
||||
);
|
||||
}
|
||||
|
||||
MOCK_METHOD(Bool, boolMetric, (std::string, Labels, std::optional<std::string>), (override));
|
||||
MOCK_METHOD(CounterInt&, counterInt, (std::string, Labels, std::optional<std::string>), (override));
|
||||
MOCK_METHOD(CounterDouble&, counterDouble, (std::string, Labels, std::optional<std::string>), (override));
|
||||
MOCK_METHOD(GaugeInt&, gaugeInt, (std::string, Labels, std::optional<std::string>), (override));
|
||||
@@ -252,7 +258,7 @@ struct WithPrometheus : virtual ::testing::Test {
|
||||
|
||||
~WithPrometheus() override
|
||||
{
|
||||
PrometheusService::init();
|
||||
PrometheusService::replaceInstance(nullptr);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
63
unittests/util/prometheus/BoolTests.cpp
Normal file
63
unittests/util/prometheus/BoolTests.cpp
Normal file
@@ -0,0 +1,63 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
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.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#include "util/prometheus/Bool.hpp"
|
||||
#include "util/prometheus/Gauge.hpp"
|
||||
|
||||
#include <gmock/gmock.h>
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
using namespace util::prometheus;
|
||||
using testing::StrictMock;
|
||||
|
||||
struct BoolTests : public testing::Test {
|
||||
struct MockImpl {
|
||||
MOCK_METHOD(void, set, (int64_t), ());
|
||||
MOCK_METHOD(int64_t, value, (), ());
|
||||
};
|
||||
StrictMock<MockImpl> impl_;
|
||||
AnyBool<StrictMock<MockImpl>> bool_{impl_};
|
||||
};
|
||||
|
||||
TEST_F(BoolTests, Set)
|
||||
{
|
||||
EXPECT_CALL(impl_, set(1));
|
||||
bool_ = true;
|
||||
|
||||
EXPECT_CALL(impl_, set(0));
|
||||
bool_ = false;
|
||||
}
|
||||
|
||||
TEST_F(BoolTests, Get)
|
||||
{
|
||||
EXPECT_CALL(impl_, value()).WillOnce(testing::Return(1));
|
||||
EXPECT_TRUE(bool_);
|
||||
|
||||
EXPECT_CALL(impl_, value()).WillOnce(testing::Return(0));
|
||||
EXPECT_FALSE(bool_);
|
||||
}
|
||||
|
||||
TEST_F(BoolTests, DefaultValues)
|
||||
{
|
||||
GaugeInt gauge{"test", ""};
|
||||
Bool realBool{gauge};
|
||||
EXPECT_FALSE(realBool);
|
||||
}
|
||||
@@ -70,6 +70,13 @@ TEST_F(AnyCounterTests, operatorAdd)
|
||||
counter += 42;
|
||||
}
|
||||
|
||||
TEST_F(AnyCounterTests, set)
|
||||
{
|
||||
EXPECT_CALL(mockCounterImpl, value()).WillOnce(::testing::Return(4));
|
||||
EXPECT_CALL(mockCounterImpl, set(42));
|
||||
counter.set(42);
|
||||
}
|
||||
|
||||
TEST_F(AnyCounterTests, reset)
|
||||
{
|
||||
EXPECT_CALL(mockCounterImpl, set(0));
|
||||
@@ -82,6 +89,20 @@ TEST_F(AnyCounterTests, value)
|
||||
EXPECT_EQ(counter.value(), 42);
|
||||
}
|
||||
|
||||
struct AnyCounterDeathTest : AnyCounterTests {};
|
||||
|
||||
TEST_F(AnyCounterDeathTest, setLowerValue)
|
||||
{
|
||||
testing::Mock::AllowLeak(&mockCounterImpl);
|
||||
EXPECT_DEATH(
|
||||
{
|
||||
EXPECT_CALL(mockCounterImpl, value()).WillOnce(::testing::Return(50));
|
||||
counter.set(42);
|
||||
},
|
||||
".*"
|
||||
);
|
||||
}
|
||||
|
||||
struct CounterIntTests : ::testing::Test {
|
||||
CounterInt counter{"test_counter", R"(label1="value1",label2="value2")"};
|
||||
};
|
||||
|
||||
@@ -128,10 +128,22 @@ TEST_F(GaugeIntTests, multithreadAddAndSubstract)
|
||||
);
|
||||
}
|
||||
|
||||
TEST_F(GaugeIntTests, DefaultValue)
|
||||
{
|
||||
GaugeInt realGauge{"some_gauge", ""};
|
||||
EXPECT_EQ(realGauge.value(), 0);
|
||||
}
|
||||
|
||||
struct GaugeDoubleTests : ::testing::Test {
|
||||
GaugeDouble gauge{"test_Gauge", R"(label1="value1",label2="value2")"};
|
||||
};
|
||||
|
||||
TEST_F(GaugeDoubleTests, DefaultValue)
|
||||
{
|
||||
GaugeDouble realGauge{"some_gauge", ""};
|
||||
EXPECT_EQ(realGauge.value(), 0.);
|
||||
}
|
||||
|
||||
TEST_F(GaugeDoubleTests, operatorAdd)
|
||||
{
|
||||
++gauge;
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
#include "rpc/Errors.hpp"
|
||||
#include "util/Fixtures.hpp"
|
||||
#include "util/MockETLService.hpp"
|
||||
#include "util/MockPrometheus.hpp"
|
||||
#include "util/MockRPCEngine.hpp"
|
||||
#include "util/Taggable.hpp"
|
||||
#include "util/config/Config.hpp"
|
||||
@@ -65,7 +66,9 @@ struct MockWsBase : public web::ConnectionBase {
|
||||
}
|
||||
};
|
||||
|
||||
class WebRPCServerHandlerTest : public MockBackendTest, public SyncAsioContextTest {
|
||||
class WebRPCServerHandlerTest : public util::prometheus::WithPrometheus,
|
||||
public MockBackendTest,
|
||||
public SyncAsioContextTest {
|
||||
protected:
|
||||
void
|
||||
SetUp() override
|
||||
|
||||
Reference in New Issue
Block a user