Document baggage propagation over gRPC

Baggage is already propagated over gRPC by the auto-configured
Micrometer observation interceptors: on the server side the
ObservationGrpcServerInterceptor hands the incoming metadata to the
tracing observation handlers, which extract the W3C baggage header as
well as the individual metadata keys listed in
management.tracing.baggage.remote-fields, and on the client side the
ObservationGrpcClientInterceptor writes them to the metadata of
outgoing calls. This was not documented, and it is easy to miss that
it requires micrometer-core on the classpath.

This commit adds an Observability section to the gRPC server
documentation, extends the gRPC client Observability section, and
mentions gRPC in the baggage section of the tracing documentation.

See gh-51597

Signed-off-by: Oleksandr Shevchenko <oleksandr.shevchenko@datarobot.com>
This commit is contained in:
Oleksandr Shevchenko
2026-09-10 15:33:57 +01:00
committed by Andy Wilkinson
parent 5b3631bfe9
commit 020584c36a
2 changed files with 20 additions and 0 deletions
@@ -242,6 +242,7 @@ The baggage is automatically propagated over the network if you're using W3C pro
If you're using B3 propagation, baggage is not automatically propagated.
To manually propagate baggage over the network, use the configprop:management.tracing.baggage.remote-fields[] configuration property (this works for W3C, too).
For the example above, setting this property to `baggage1` results in an HTTP header `baggage1: value1`.
Baggage is propagated wherever Micrometer Observation instruments the transport, for example xref:io/grpc.adoc#io.grpc.server.observability[gRPC metadata] as well as HTTP headers.
If you want to propagate the baggage to the MDC, use the configprop:management.tracing.baggage.correlation.fields[] configuration property.
For the example above, setting this property to `baggage1` results in an MDC entry named `baggage1`.
@@ -484,6 +484,21 @@ For details of how to configure an OAuth2 Resource Server to use with your gRPC
[[io.grpc.server.observability]]
=== Observability
Spring Boot provides auto-configuration of the javadoc:io.micrometer.core.instrument.binder.grpc.ObservationGrpcServerInterceptor[] whenever Micrometer is available.
This interceptor provides observability into your gRPC server applications.
When Micrometer Tracing is also available, the observation carries the trace context and any xref:actuator/tracing.adoc#actuator.micrometer-tracing.baggage[baggage] found in the incoming gRPC metadata.
This includes the W3C `baggage` header as well as the individual metadata keys listed in configprop:management.tracing.baggage.remote-fields[], so no additional interceptor is required to propagate baggage over gRPC.
NOTE: The interceptor is provided by `micrometer-core`, so it is only auto-configured when that dependency is on the classpath (for example through `spring-boot-starter-actuator`).
TIP: If you use Micrometer, but prefer to not to use it for gRPC, you can set configprop:spring.grpc.server.observation.enabled[] to `false`.
[[io.grpc.client]]
== Writing a gRPC Client Application
@@ -683,6 +698,10 @@ TIP: To disable the in-process channel factory, you can set the configprop:sprin
Spring Boot provides auto-configuration of the javadoc:io.micrometer.core.instrument.binder.grpc.ObservationGrpcClientInterceptor[] whenever Micrometer is available.
This interceptor provides observability into your gRPC client applications.
When Micrometer Tracing is also available, the trace context and the current xref:actuator/tracing.adoc#actuator.micrometer-tracing.baggage[baggage] are written to the metadata of outgoing calls, using the W3C `baggage` header as well as the individual metadata keys listed in configprop:management.tracing.baggage.remote-fields[].
NOTE: The interceptor is provided by `micrometer-core`, so it is only auto-configured when that dependency is on the classpath (for example through `spring-boot-starter-actuator`).
TIP: If you use Micrometer, but prefer to not to use it for gRPC, you can set configprop:spring.grpc.client.observation.enabled[] to `false`.