Allow customizing OTel span status on error via a callback#1443
Open
philsttr wants to merge 1 commit into
Open
Allow customizing OTel span status on error via a callback#1443philsttr wants to merge 1 commit into
philsttr wants to merge 1 commit into
Conversation
Author
|
|
Previously the OpenTelemetry bridge unconditionally set the delegate span's status to ERROR whenever an error was reported, in three places: OtelSpan.error(), OtelScopedSpan.error() and OtelSpanBuilder.start(). This left no way to treat certain exceptions as expected and avoid marking the span as errored. Introduce SpanErrorStatusHandler, a functional interface that decides the status to set on the OTel span for a given throwable. The exception is still always recorded via Span.recordException(); the handler is responsible only for the status. Its DEFAULT implementation reproduces the historical behavior (always set ERROR, using the throwable message as the description when present), so existing users see no change. A custom handler may, for example, leave the status unset for expected exceptions, in which case the span is marked OK on end, or set a custom description. The handler is configured on OtelTracer via a new constructor overload and is threaded into every span the tracer creates (nextSpan, currentSpan, startScopedSpan, spanBuilder). OtelSpan, OtelScopedSpan and OtelSpanBuilder each carry the handler through new constructor/factory variants; all existing constructors and factories default to SpanErrorStatusHandler.DEFAULT, keeping the change backward compatible. Routing all three call sites through the default also unifies a minor inconsistency where the scoped span and builder passed a possibly-null message directly to setStatus. Add SpanErrorStatusHandlerTests covering the unchanged default behavior and a custom "expected exception" handler across Span.error, ScopedSpan.error and Span.Builder.error, plus a custom-description case. Signed-off-by: Phil Clay <philsttr@users.noreply.github.com>
Author
|
New |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
In the OpenTelemetry bridge, reporting an error on a span always sets the delegate span's status to
ERROR. This happens in three places:OtelSpan.error(Throwable)OtelScopedSpan.error(Throwable)OtelSpanBuilder.start()(when an error was set on the builder)There is no hook to influence this. In practice, some exceptions are expected (e.g. a
NotFoundExceptionthat maps to a404) and I'd like for these to not cause the span to be marked as errored.Change
Introduce
SpanErrorStatusHandler, a@FunctionalInterfacethat decides the status to set on the OTel span for a given throwable:The
DEFAULTimplementation is the same as the behavior prior to this change.The exception is still always recorded via
Span.recordException(...); the handler is responsible only for the status. Leaving the status unset means the span is markedOKon end, which is how a handler treats an exception as expected.The handler is configured on
OtelTracerthrough a new constructor overload and threaded into every span the tracer creates (nextSpan,currentSpan,startScopedSpan,spanBuilder). For example, using a custom handler would look something like this:Backward compatibility
Fully backward compatible.
OtelSpan,OtelScopedSpanandOtelSpanBuildernow carry the handler via new constructor/factory variants, but all existing constructors and factories default toSpanErrorStatusHandler.DEFAULT, which reproduces today's behavior exactly. No public API is removed or changed.Routing all three call sites through the default also unifies a small existing inconsistency:
OtelScopedSpanandOtelSpanBuilderpreviously passed a possibly-null message straight tosetStatus(ERROR, message), whileOtelSpannull-checked it. Both are equivalent in the OTel SDK, so this is a harmless consolidation.Tests
Added
SpanErrorStatusHandlerTestscovering:ERRORwith the throwable message, and the exception event still recorded.OKwhile the exception event is still recorded, verified acrossSpan.error,ScopedSpan.errorandSpan.Builder.error.Out of scope
Span.BuilderAPI inmicrometer-tracing-apiis untouched; this is OTel-specific configuration only (no per-builder override).OtelTracerconstructor. Assuming this PR is merged, I might submit a follow-up Spring Boot PR to allow a customSpanErrorStatusHandlerto be auto-configured if a bean of that type is found.