- PerfLogImp::rpcEnd(): return after the requestId-not-found UNREACHABLE
so a stale (now - epoch) duration is no longer recorded to the counter
and histogram in release builds.
- MetricsRegistry peer-version gauge: compare versions numerically via
BuildInfo::encodeSoftwareVersion() instead of a lexicographic string
compare, stripping the non-digit prefix so peer 'rippled-X.Y.Z' lines
up with our bare 'X.Y.Z'. Fixes every peer counting as higher-version.
- MetricsRegistry::stop(): call Shutdown() before ForceFlush() before
reset() so the reader thread stops before teardown and no gauge
callback fires during shutdown.
- MetricsRegistry::start(): extract initExporterAndProvider() and
initSyncInstruments() helpers to keep each function under the line
limit; no behavior change.
- time_in_current_state_seconds: read NetworkOPs::getServerStateDurationUs()
(a lightweight accessor over StateAccounting) and convert microseconds
to seconds, replacing the hardcoded 0.0.
Give developers direct access to the full OpenTelemetry metrics API,
symmetric with getTracer(), so all seven OTel instrument types
(including UpDownCounter, sync Gauge, and the observable variants) are
reachable — not just the four beast::insight models.
- Telemetry: build and own the metrics pipeline (OTLP HTTP metric
exporter + PeriodicExportingMetricReader + SpanMetrics histogram view)
alongside the tracer, sharing the same resource attributes and TLS
config. Register it globally via metrics::Provider::SetMeterProvider
and expose Telemetry::getMeter(). Metrics enable with [telemetry];
the metrics endpoint is derived from the trace endpoint.
- beast OTelCollector: no longer owns a pipeline. It fetches the global
Meter, becoming a thin shim over the shared provider (legacy path
during beast deprecation). This also resolves the review note that the
metric exporter ignored [telemetry] use_tls — TLS now comes from the
shared telemetry pipeline.
- Add a libxrpl unit test covering getMeter() on the enabled (global
provider) and disabled (noop) paths, exercising an UpDownCounter.
Design: docs/superpowers/specs/2026-07-07-direct-otel-metrics-api-design.md
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- cmake: keep the opentelemetry-cpp umbrella target for the beast metrics
link and document why. The reviewer suggested linking individual
component targets to avoid over-linking, but the OTel Conan package
under-declares inter-component dependencies (the OTLP client references
sdk::common symbols without a declared edge), so naming components
directly reorders the static link into an unresolvable state. Verified
by building xrpl_tests both ways.
- OTelCollector.h: add usage examples, thread-safety and limitations
@note blocks to the class doc.
- OTelCollector.cpp: correct the @param name docs on the instrument
Impl constructors to describe the already-formatName()'d value.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Soften the "non-reversible" wording in Redaction.h. XRP account
addresses are a public, enumerable set, so an unsalted hash is
obfuscation (keeps plaintext out of traces/dashboards), not a
secrecy guarantee. Document why a salt is intentionally omitted:
it would break cross-node/restart correlation, the reason for
hashing rather than dropping the attribute.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The native OTel metrics path hard-coded service.name="xrpld" and stamped
no network attribute, while traces stamped a configurable service.name
and xrpl.network.type. Metrics therefore could not be filtered by service
or network. Align the two paths:
- OTelCollector::New / OTelCollectorImp gain serviceName + networkType
params. service.name uses the configured value (default "xrpld" when
unset, preserving today's behavior); xrpl.network.type is stamped when
provided. The key is a string literal because beast/insight sits below
the telemetry module and cannot include its SpanNames const.
- CollectorManager reads service_name from [insight], falling back to the
[telemetry] value, and receives the network type from the caller.
- Application derives the network type once via the shared
telemetry::networkTypeFromId, now declared in Telemetry.h and moved out
of an anonymous namespace so the trace and metric paths reuse a single
0/1/2 -> mainnet/testnet/devnet mapping (no duplication).
Dashboards (5 system-* files): add $service_name, $deployment_environment,
$xrpl_network_type template variables and wire them into every panel query
that filters by $node.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>