WebClient Observations are missing error #32389
Labels
in: web
Issues in web modules (web, webmvc, webflux, websocket)
status: backported
An issue that has been backported to maintenance branches
theme: observability
An issue related to observability and tracing
type: bug
A general bug
Milestone
I'm using
WebClient
in a setup withorg.springframework:spring-webflux:6.1.4
io.micrometer:micrometer-tracing-bridge-otel:1.2.3
io.opentelemetry:opentelemetry-exporter-zipkin:1.31.0
and am missing status/error metadata in the spans that show up in Zipkin.
When a HTTP GET request fails, the outcome in zipkin is a
http get
span with (among others) the tags:exception
:WebClientRequestException
outcome
:UNKNOWN
status
:CLIENT_ERROR
otel.library.name
,otel.library.version
,otel.scope.name
, andotel.scope.version
What is missing is both:
error
(Convention for Zipkin to mark the span in red)otel.status_code
(fromio.opentelemetry.exporter.zipkin.OtelToZipkinSpanTransformer
)Working backwards, the
OtelToZipkinSpanTransformer
would set both of these, if there was a statusset on the OpenTelemetry Span /
SpanData
, which was not the case in debugging.These would be set in
io.micrometer.tracing.otel.bridge.OtelSpan::error
, which is an implementation ofio.micrometer.tracing.Span
. Going further back, that method is called byio.micrometer.tracing.handler.TracingObservationHandler
,either when the
ERROR
tag is set, or whenonError
is called.That should be called by
io.micrometer.observation.SimpleObservation#notifyOnError
, which is an implementation detail ofio.micrometer.observation.SimpleObservation#error
.But it turns out
WebClient
doesn't call that function! Instead, atspring-framework/spring-webflux/src/main/java/org/springframework/web/reactive/function/client/DefaultWebClient.java
Line 474 in 7f0ab22
it only calls
org.springframework.web.reactive.function.client.ClientRequestObservationContext#setError
, whereasSimpleObservation both sets the error in the contex and dispatches the notification:
To me this last part seems like the best place to fix this issue, i.e. to replace
.doOnError(observationContext::setError)
with something like.doOnError(e -> observation.error(e))
.The text was updated successfully, but these errors were encountered: