mirror of
https://github.com/XRPLF/rippled.git
synced 2026-09-29 00:08:10 +00:00
beast::insight::Event documents itself as carrying "a millisecond time, or
other integral value", but both backends assumed the first case: the OTel
bridge declared every instrument with unit `ms` and StatsD tagged every
sample `|ms`. One Event does not measure time -- ServerHandler's "size"
records the serialized RPC response length -- so it exported as
rpc_size_milliseconds and inherited the millisecond bucket ladder. A quarter
of its samples landed above that ladder's top edge, and since Prometheus
returns the second-highest edge for a quantile in the `+Inf` bucket, its p95
panel showed a flat 5.00 kB rather than a measurement.
Adds beast::insight::Unit (Millis, Bytes) plus otelUnitCode(), carried on
EventImpl and selectable at makeEvent(). Naming the unit at creation is what
lets a backend pick the export unit and, through it, the bucket ladder.
- Collector gains a virtual makeEvent(name, Unit) whose default delegates to
the millisecond overload, so a collector that cannot act on a unit keeps
working unchanged. NullCollector and the Groups wrapper override it.
- The Groups override matters most: call sites reach a collector through a
Group, so forwarding only the prefixed name would silently drop the unit.
A test covers that hop specifically.
- Event gains notify(std::uint64_t) for non-duration samples, replacing
ServerHandler's `Event::value_type{response.size()}` -- wrapping a byte
count in a std::chrono::milliseconds compiles but reads as a duration to
everything downstream.
- EventImpl::value_type stays std::chrono::milliseconds. Widening it would
change the wire value of every existing StatsD timer, and metrics needing
finer resolution use the OTel-native microsecond instruments.
The StatsD collector deliberately keeps emitting `|ms`: that path is retired
here (its UDP port is commented out of the compose file and the integration
test fails if anything listens on 8125), so changing its wire format would
alter a legacy contract with no consumer and no way to verify it.
The exported name does not change yet -- OTelEventImpl still hardcodes its
unit. That follows with the unit-keyed histogram views.
169 lines
3.6 KiB
C++
169 lines
3.6 KiB
C++
#include <xrpl/beast/insight/NullCollector.h>
|
|
|
|
#include <xrpl/beast/insight/Collector.h>
|
|
#include <xrpl/beast/insight/Counter.h>
|
|
#include <xrpl/beast/insight/CounterImpl.h>
|
|
#include <xrpl/beast/insight/Event.h>
|
|
#include <xrpl/beast/insight/EventImpl.h>
|
|
#include <xrpl/beast/insight/Gauge.h>
|
|
#include <xrpl/beast/insight/GaugeImpl.h>
|
|
#include <xrpl/beast/insight/Hook.h>
|
|
#include <xrpl/beast/insight/HookImpl.h>
|
|
#include <xrpl/beast/insight/Meter.h>
|
|
#include <xrpl/beast/insight/MeterImpl.h>
|
|
#include <xrpl/beast/insight/Unit.h>
|
|
|
|
#include <memory>
|
|
#include <string>
|
|
|
|
namespace beast::insight {
|
|
|
|
namespace detail {
|
|
|
|
class NullHookImpl : public HookImpl
|
|
{
|
|
public:
|
|
explicit NullHookImpl() = default;
|
|
|
|
NullHookImpl&
|
|
operator=(NullHookImpl const&) = delete;
|
|
};
|
|
|
|
//------------------------------------------------------------------------------
|
|
|
|
class NullCounterImpl : public CounterImpl
|
|
{
|
|
public:
|
|
explicit NullCounterImpl() = default;
|
|
|
|
void
|
|
increment(value_type) override
|
|
{
|
|
}
|
|
|
|
NullCounterImpl&
|
|
operator=(NullCounterImpl const&) = delete;
|
|
};
|
|
|
|
//------------------------------------------------------------------------------
|
|
|
|
class NullEventImpl : public EventImpl
|
|
{
|
|
public:
|
|
/**
|
|
* @param unit What the samples would measure. Recorded even though
|
|
* nothing is collected, so a caller can still read back the
|
|
* unit it asked for -- which is what makes the null collector
|
|
* usable for testing the unit plumbing.
|
|
*/
|
|
explicit NullEventImpl(Unit unit = Unit::Millis) : EventImpl(unit)
|
|
{
|
|
}
|
|
|
|
void
|
|
notify(value_type const&) override
|
|
{
|
|
}
|
|
|
|
NullEventImpl&
|
|
operator=(NullEventImpl const&) = delete;
|
|
};
|
|
|
|
//------------------------------------------------------------------------------
|
|
|
|
class NullGaugeImpl : public GaugeImpl
|
|
{
|
|
public:
|
|
explicit NullGaugeImpl() = default;
|
|
|
|
void
|
|
set(value_type) override
|
|
{
|
|
}
|
|
|
|
void
|
|
increment(difference_type) override
|
|
{
|
|
}
|
|
|
|
NullGaugeImpl&
|
|
operator=(NullGaugeImpl const&) = delete;
|
|
};
|
|
|
|
//------------------------------------------------------------------------------
|
|
|
|
class NullMeterImpl : public MeterImpl
|
|
{
|
|
public:
|
|
explicit NullMeterImpl() = default;
|
|
|
|
void
|
|
increment(value_type) override
|
|
{
|
|
}
|
|
|
|
NullMeterImpl&
|
|
operator=(NullMeterImpl const&) = delete;
|
|
};
|
|
|
|
//------------------------------------------------------------------------------
|
|
|
|
class NullCollectorImp : public NullCollector
|
|
{
|
|
private:
|
|
public:
|
|
NullCollectorImp() = default;
|
|
|
|
~NullCollectorImp() override = default;
|
|
|
|
Hook
|
|
makeHook(HookImpl::HandlerType const&) override
|
|
{
|
|
return Hook(std::make_shared<detail::NullHookImpl>());
|
|
}
|
|
|
|
Counter
|
|
makeCounter(std::string const&) override
|
|
{
|
|
return Counter(std::make_shared<detail::NullCounterImpl>());
|
|
}
|
|
|
|
using Collector::makeEvent;
|
|
|
|
Event
|
|
makeEvent(std::string const&) override
|
|
{
|
|
return Event(std::make_shared<detail::NullEventImpl>());
|
|
}
|
|
|
|
Event
|
|
makeEvent(std::string const&, Unit unit) override
|
|
{
|
|
return Event(std::make_shared<detail::NullEventImpl>(unit));
|
|
}
|
|
|
|
Gauge
|
|
makeGauge(std::string const&) override
|
|
{
|
|
return Gauge(std::make_shared<detail::NullGaugeImpl>());
|
|
}
|
|
|
|
Meter
|
|
makeMeter(std::string const&) override
|
|
{
|
|
return Meter(std::make_shared<detail::NullMeterImpl>());
|
|
}
|
|
};
|
|
|
|
} // namespace detail
|
|
|
|
//------------------------------------------------------------------------------
|
|
|
|
std::shared_ptr<Collector>
|
|
NullCollector::make()
|
|
{
|
|
return std::make_shared<detail::NullCollectorImp>();
|
|
}
|
|
|
|
} // namespace beast::insight
|