From 5ba1edf6480d9fefc7c7fd587ce0728c0ce1d550 Mon Sep 17 00:00:00 2001 From: Pratik Mankawde <3397372+pratikmankawde@users.noreply.github.com> Date: Thu, 3 Sep 2026 16:47:25 +0100 Subject: [PATCH] fix(telemetry): use metrics_endpoint verbatim in initMetrics initMetrics() held its own copy of the suffix-swap: take tracesEndpoint, replace a trailing /v1/traces with /v1/metrics. Any other URL shape sent metrics to the traces path. metrics_endpoint is now a config key of its own, so use it as given. Application::startTelemetry() still reads the key itself for MetricsRegistry, which builds its own exporter. Telemetry exposes no accessor for the Setup it parsed, and re-parsing would re-run the mTLS validation and cert-file checks at a later point in startup, so the second read stays. The comment above it no longer claims the URL is derived from the traces one. Also corrects 05-configuration-reference.md: the sample configs carry metrics_endpoint where exporter used to sit, not a comment. --- OpenTelemetryPlan/05-configuration-reference.md | 11 ++++------- src/libxrpl/telemetry/Telemetry.cpp | 16 +++------------- src/xrpld/app/main/Application.cpp | 5 +++-- 3 files changed, 10 insertions(+), 22 deletions(-) diff --git a/OpenTelemetryPlan/05-configuration-reference.md b/OpenTelemetryPlan/05-configuration-reference.md index a5dec3fc52..10bdfa87cd 100644 --- a/OpenTelemetryPlan/05-configuration-reference.md +++ b/OpenTelemetryPlan/05-configuration-reference.md @@ -113,13 +113,10 @@ the corresponding subsystems are instrumented: | `trace_validator` | Future | Validator list / manifest update tracing | | `trace_amendment` | Future | Amendment voting tracing | -> **`exporter` is not read, so do not set it.** Both shipped sample configs -> (`docker/telemetry/xrpld-telemetry.cfg`, -> `docker/telemetry/xrpld-telemetry-mainnet.cfg`) used to carry -> `exporter=otlp_http`; the line had no effect and has since been replaced with -> a comment saying so. OTLP/HTTP is the only transport that exists (§2.2.1), and -> `endpoint` / `metrics_endpoint` are the only transport knobs, until the §2.2.2 -> gRPC work lands. +> **`exporter` is not read, so do not set it.** No shipped sample config +> carries it. OTLP/HTTP is the only transport that exists (§2.2.1), so +> `traces_endpoint` and `metrics_endpoint` are the only transport knobs until +> the §2.2.2 gRPC work lands. --- diff --git a/src/libxrpl/telemetry/Telemetry.cpp b/src/libxrpl/telemetry/Telemetry.cpp index 32682b0354..7b54b76c8d 100644 --- a/src/libxrpl/telemetry/Telemetry.cpp +++ b/src/libxrpl/telemetry/Telemetry.cpp @@ -529,21 +529,11 @@ public: void initMetrics() { - // Derive the metrics endpoint from the trace endpoint by swapping - // the trailing "/v1/traces" path for "/v1/metrics". Any other URL - // shape is used as-is. - std::string metricsEndpoint = setup_.tracesEndpoint; - constexpr std::string_view tracesPath{"/v1/traces"}; - if (metricsEndpoint.ends_with(tracesPath)) - { - metricsEndpoint.replace( - metricsEndpoint.size() - tracesPath.size(), tracesPath.size(), "/v1/metrics"); - } - // Configure OTLP HTTP metric exporter, honoring the same TLS - // options as the trace exporter. + // options as the trace exporter. The URL is used verbatim: metrics + // have their own config key and are not derived from traces. otlp_http::OtlpHttpMetricExporterOptions metricExporterOpts; - metricExporterOpts.url = metricsEndpoint; + metricExporterOpts.url = setup_.metricsEndpoint; if (setup_.useTls) { metricExporterOpts.ssl_ca_cert_path = setup_.tlsCertPath; diff --git a/src/xrpld/app/main/Application.cpp b/src/xrpld/app/main/Application.cpp index 30e44bd5df..0615edb543 100644 --- a/src/xrpld/app/main/Application.cpp +++ b/src/xrpld/app/main/Application.cpp @@ -1720,8 +1720,9 @@ ApplicationImp::startTelemetry() const // Start tracing first so subsequent startup/early activity can be traced. telemetry_->start(); - // Start the metrics pipeline after telemetry; the endpoint uses the - // same base URL but the /v1/metrics path. + // Start the metrics pipeline after telemetry. metrics_endpoint is a full + // URL of its own, read again here because Telemetry does not expose the + // Setup it parsed. if (metricsRegistry_) { auto const& section = config_->section("telemetry");