From 97e6586f71c0d1320c2e069d4274f8c6c1fd6d0c Mon Sep 17 00:00:00 2001 From: Pratik Mankawde <3397372+pratikmankawde@users.noreply.github.com> Date: Tue, 21 Jul 2026 21:07:20 +0100 Subject: [PATCH] fix(telemetry): captureContext() captures the guard's own span, not ambient MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit SpanGuard is unscoped (never pushed onto the thread-local context stack), so RuntimeContext::GetCurrent() returned an unrelated ambient span. Build the captured context from impl_->span so captureContext() is correct for every caller regardless of scoping — childSpan(name, ctx) then parents explicitly to this span across threads. Matches getTraceBytes()'s own-context behavior. Co-Authored-By: Claude Opus 4.8 (1M context) --- src/libxrpl/telemetry/SpanGuard.cpp | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/libxrpl/telemetry/SpanGuard.cpp b/src/libxrpl/telemetry/SpanGuard.cpp index 825402ff63..0b3a35d170 100644 --- a/src/libxrpl/telemetry/SpanGuard.cpp +++ b/src/libxrpl/telemetry/SpanGuard.cpp @@ -294,9 +294,15 @@ SpanGuard::linkedSpan(std::string_view name, SpanContext const& linkCtx) SpanContext SpanGuard::captureContext() const { - if (!impl_) + if (!impl_ || !impl_->span) return {}; - auto ctx = opentelemetry::context::RuntimeContext::GetCurrent(); + // Capture THIS guard's own span, not the thread's ambient span. A + // SpanGuard is unscoped (never pushed onto the thread-local stack), so + // RuntimeContext::GetCurrent() would return an unrelated ambient span. + // Building the context from impl_->span makes captureContext() correct + // for every caller regardless of scoping, and lets childSpan(name, ctx) + // parent explicitly to this span across threads. + auto ctx = opentelemetry::context::Context{}.SetValue(otel_trace::kSpanKey, impl_->span); return SpanContext(std::make_shared(std::move(ctx))); }