SpringBoot OtlpAutoConfiguration should check for presence of anyio.opentelemetry.sdk.trace.export.SpanExporter instance for conditional bean creation This OtlpAutoConfiguration is not full proof for scenarios where interface is used for @Bean creation. Its injectingOtlpHttpSpanExporter even though OtlpGrpcSpanExporter bean exists.

 @Bean
  public SpanExporter otlpExporter() {
    return OtlpGrpcSpanExporter.builder().setEndpoint(otlpGrpcSpanExporterEndpoint).build();
  }

Comment From: mhalbritter

I'm not sure if I understand.

org.springframework.boot.actuate.autoconfigure.tracing.otlp.OtlpAutoConfiguration#otlpHttpSpanExporter backs off if there is a OtlpHttpSpanExporter or a OtlpGrpcSpanExporter bean already defined.

What is the problem you are observing? Could you maybe create a small sample which helps me to understand the problem?

Comment From: mhalbritter

Is the problem that this auto-configuration doesn't back off if you're defining a SpanExporter (instead of OtlpHttpSpanExporter) yourself?

Comment From: amithkumarg

Is the problem that this auto-configuration doesn't back off if you're defining a SpanExporter (instead of OtlpHttpSpanExporter) yourself?

Yes that's right, using Interface SpanExporter instead of (OtlpGrpcSpanExporter or OtlpHttpSpanExporter).

Comment From: quaff

It should be @ConditionalOnMissingBean(SpanExporter.class)

Comment From: philwebb

The current auto-configuration is designed to provide a OtlpHttpSpanExporter unless a user-defined OtlpHttpSpanExporter or OtlpGrpcSpanExporter is provided. All other SpanExporter beans are added to the SpanProcessor (see OpenTelemetryAutoConfiguration).

@amithkumarg In your case I think the problem is your @Bean definition method. You currently have:

@Bean
public SpanExporter otlpExporter() {
    return OtlpGrpcSpanExporter.builder().setEndpoint(otlpGrpcSpanExporterEndpoint).build();
}

It's best practice to always return the most specific type from a @Bean method. This allow Spring to reason about the instances that will be created when the method is actually invoked.

If you change the method to the following, I believe things will work as designed:

@Bean
public OtlpGrpcSpanExporter otlpExporter() {
    return OtlpGrpcSpanExporter.builder().setEndpoint(otlpGrpcSpanExporterEndpoint).build();
}

Comment From: amithkumarg

Yes, that's how I made it work, but good information with Best Practices when declaring Spring Bean, use specific type instead of interface