Hi,
I'm trying to ignore calls to the /actuator endpoint from OpenTelemetry tracing in my project that uses spring-boot-starter-parent==3.2.4.
Looking at OpenTelemetryAutoConfiguration.java it appears that I could just define my own Sampler Bean, but this doesn't seem to be working.
Below is the configuration class I have.
/**
* Configure the Sprint Boot 3 built in tracing via
* {@link org.springframework.boot.actuate.autoconfigure.tracing.OpenTelemetryAutoConfiguration}.
*/
@Configuration
public class OtelConfiguration {
private final TracingProperties tracingProperties;
public OtelConfiguration(final TracingProperties tracingProperties) {
this.tracingProperties = tracingProperties;
}
/**
* Do not trace any requests to the /actuator endpoint.
*/
@Bean
public Sampler otelSampler() {
final Sampler rootSampler = Sampler.traceIdRatioBased(this.tracingProperties.getSampling().getProbability());
@SuppressWarnings("deprecation")
final Sampler filterActuator = RuleBasedRoutingSampler.builder(SpanKind.SERVER, rootSampler)
.drop(SemanticAttributes.HTTP_URL, "^/actuator")
.build();
return Sampler.parentBased(filterActuator);
}
/**
* Configure OpenTelemetry tracing to generate AWS X-Ray compatible trace IDs and gather AWS resource information.
*/
@Bean
public SdkTracerProvider sdkTracerProvider(final Resource resource,
final SpanProcessors spanProcessors,
final Sampler sampler,
final ObjectProvider<SdkTracerProviderBuilderCustomizer> customizers) {
final SdkTracerProviderBuilder builder = SdkTracerProvider.builder().setSampler(sampler).setResource(resource);
spanProcessors.forEach(builder::addSpanProcessor);
customizers.orderedStream().forEach((customizer) -> customizer.customize(builder));
builder.setIdGenerator(AwsXrayIdGenerator.getInstance());
builder.setResource(
Resource.getDefault()
.merge(BeanstalkResource.get())
.merge(Ec2Resource.get())
.merge(EcsResource.get())
.merge(EksResource.get()));
return builder.build();
}
/**
* Configure OpenTelemetry tracing to propagate both the standard W3C TraceContext and AWS X-Ray trace IDs to
* downstream resources.
*/
@Bean
public ContextPropagators contextPropagators() {
return ContextPropagators.create(
TextMapPropagator.composite(
W3CTraceContextPropagator.getInstance(), AwsXrayPropagator.getInstance()));
}
}
But looking at the logs, you can see my request to /actuator/health was still traced.
2024-04-08T11:34:53.616Z TRACE 1 --- [or-http-epoll-3] [ ] i.m.t.o.b.Slf4JBaggageEventListener : Got scope attached event [ScopeAttached{context: [span: SdkSpan{traceId=6613d65d45a7c113ed3b1297dd4c0796, spanId=f93816cd5717dbaa, parentSpanContext=ImmutableSpanContext{traceId=00000000000000000000000000000000, spanId=0000000000000000, traceFlags=00, traceState=ArrayBasedTraceState{entries=[]}, remote=false, valid=false}, name=<unspecified span name>, kind=SERVER, attributes=null, status=ImmutableStatusData{statusCode=UNSET, description=}, totalRecordedEvents=0, totalRecordedLinks=0, startEpochNanos=1712576093573578409, endEpochNanos=0}] [baggage: {}]}]
2024-04-08T11:34:53.619Z TRACE 1 --- [or-http-epoll-3] [ ] i.m.t.otel.bridge.Slf4JEventListener : Got scope changed event [ScopeAttached{context: [span: SdkSpan{traceId=6613d65d45a7c113ed3b1297dd4c0796, spanId=f93816cd5717dbaa, parentSpanContext=ImmutableSpanContext{traceId=00000000000000000000000000000000, spanId=0000000000000000, traceFlags=00, traceState=ArrayBasedTraceState{entries=[]}, remote=false, valid=false}, name=<unspecified span name>, kind=SERVER, attributes=null, status=ImmutableStatusData{statusCode=UNSET, description=}, totalRecordedEvents=0, totalRecordedLinks=0, startEpochNanos=1712576093573578409, endEpochNanos=0}] [baggage: ScopeAttached{context: [span: SdkSpan{traceId=6613d65d45a7c113ed3b1297dd4c0796, spanId=f93816cd5717dbaa, parentSpanContext=ImmutableSpanContext{traceId=00000000000000000000000000000000, spanId=0000000000000000, traceFlags=00, traceState=ArrayBasedTraceState{entries=[]}, remote=false, valid=false}, name=<unspecified span name>, kind=SERVER, attributes=null, status=ImmutableStatusData{statusCode=UNSET, description=}, totalRecordedEvents=0, totalRecordedLinks=0, startEpochNanos=1712576093573578409, endEpochNanos=0}] [baggage: {}]}]}]
2024-04-08T11:34:53.620Z TRACE 1 --- [or-http-epoll-3] [6613d65d45a7c113ed3b1297dd4c0796-f93816cd5717dbaa] i.m.t.o.b.Slf4JBaggageEventListener : Got scope closed event [io.micrometer.tracing.otel.bridge.EventPublishingContextWrapper$ScopeClosedEvent@5448345]
2024-04-08T11:34:53.621Z TRACE 1 --- [or-http-epoll-3] [6613d65d45a7c113ed3b1297dd4c0796-f93816cd5717dbaa] i.m.t.otel.bridge.Slf4JEventListener : Got scope closed event [io.micrometer.tracing.otel.bridge.EventPublishingContextWrapper$ScopeClosedEvent@5448345]
2024-04-08T11:34:53.621Z TRACE 1 --- [or-http-epoll-3] [ ] i.m.t.o.b.Slf4JBaggageEventListener : Got scope restored event [ScopeRestored{context: [span: null] [baggage: null]}]
2024-04-08T11:34:53.622Z TRACE 1 --- [or-http-epoll-3] [ ] i.m.t.otel.bridge.Slf4JEventListener : Got scope restored event [ScopeRestored{context: [span: null] [baggage: null]}]
2024-04-08T11:34:57.709Z TRACE 1 --- [_WorkerThread-1] [ ] i.m.t.o.b.Slf4JBaggageEventListener : Got scope attached event [ScopeAttached{context: [span: null] [baggage: null]}]
2024-04-08T11:34:57.710Z TRACE 1 --- [_WorkerThread-1] [ ] i.m.t.otel.bridge.Slf4JEventListener : Got scope changed event [ScopeAttached{context: [span: null] [baggage: null]}]
2024-04-08T11:34:57.711Z TRACE 1 --- [_WorkerThread-1] [ ] i.m.t.o.b.Slf4JBaggageEventListener : Got scope closed event [io.micrometer.tracing.otel.bridge.EventPublishingContextWrapper$ScopeClosedEvent@7e3696b2]
2024-04-08T11:34:57.712Z TRACE 1 --- [_WorkerThread-1] [ ] i.m.t.otel.bridge.Slf4JEventListener : Got scope closed event [io.micrometer.tracing.otel.bridge.EventPublishingContextWrapper$ScopeClosedEvent@7e3696b2]
2024-04-08T11:34:57.713Z TRACE 1 --- [_WorkerThread-1] [ ] i.m.t.o.b.Slf4JBaggageEventListener : Got scope restored event [ScopeRestored{context: [span: null] [baggage: null]}]
2024-04-08T11:34:57.713Z TRACE 1 --- [_WorkerThread-1] [ ] i.m.t.otel.bridge.Slf4JEventListener : Got scope restored event [ScopeRestored{context: [span: null] [baggage: null]}]
2024-04-08T11:34:58.113Z info TracesExporter {"kind": "exporter", "data_type": "traces", "name": "logging", "resource spans": 1, "spans": 1}
2024-04-08T11:34:58.114Z info ResourceSpans #0
Resource SchemaURL:
Resource attributes:
-> service.name: Str(unknown_service:java)
-> telemetry.sdk.language: Str(java)
-> telemetry.sdk.name: Str(opentelemetry)
-> telemetry.sdk.version: Str(1.36.0)
ScopeSpans #0
ScopeSpans SchemaURL:
InstrumentationScope org.springframework.boot 3.2.4
Span #0
Trace ID : 6613d65d45a7c113ed3b1297dd4c0796
Parent ID :
ID : f93816cd5717dbaa
Name : http get /actuator/health
Kind : Server
Start time : 2024-04-08 11:34:53.573578409 +0000 UTC
End time : 2024-04-08 11:34:53.623421549 +0000 UTC
Status code : Unset
Status message :
Attributes:
-> exception: Str(none)
-> http.url: Str(/actuator/health)
-> method: Str(GET)
-> outcome: Str(SUCCESS)
-> status: Str(200)
-> uri: Str(/actuator/health)
{"kind": "exporter", "data_type": "traces", "name": "logging"}
I know the configuration is being picked up, as I can see the AWS X-Ray trace header being propagated when I call a downstream service, so the SdkTracerProvider and ContextPropagators Beans are working as expected, it's just the Sampler that isn't.
Looking through the tests I can see that creating your own Sampler is supported, so I'm sure I'm just doing something wrong somewhere, but I'm at a bit of a loss as to where...
Any help would be greatly appreciated!
Thanks in advance.
Comment From: wilkinsona
If you are looking for some help then, thanks for getting in touch, but it feels like this is a question that would be better suited to Stack Overflow. As mentioned in the guidelines for contributing, we prefer to use GitHub issues only for bugs and enhancements. Feel free to update this issue with a link to the re-posted question (so that other people can find it). Otherwise, this feels like a duplicate of https://github.com/spring-projects/spring-boot/issues/34801.