Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add support for OTEL_RESOURCE_ATTRIBUTES, OTEL_SERVICE_NAME, OTEL_EXPORTER_OTLP_HEADERS and OTEL_EXPORTER_OTLP_PROTOCOL for spring boot starter #9950

Merged
merged 17 commits into from
Dec 21, 2023

Conversation

zeitlinger
Copy link
Member

@zeitlinger zeitlinger commented Nov 24, 2023

Fixes #8191

it's also possible to add the header in in application.yml as a yaml map.

otel:
  exporter:
    otlp:
      header:
        foo: bar

@zeitlinger zeitlinger requested a review from a team November 24, 2023 15:51
@zeitlinger zeitlinger force-pushed the spring-boot-otlp-header branch from 051663e to 01b786a Compare November 24, 2023 15:57
@zeitlinger zeitlinger changed the title add support for OTEL_EXPORTER_OTLP_HEADERS for spring boot starter add support for OTEL_EXPORTER_OTLP_HEADERS and OTEL_EXPORTER_OTLP_PROTOCOL for spring boot starter Nov 24, 2023
@zeitlinger zeitlinger force-pushed the spring-boot-otlp-header branch from 510f8c0 to 9c3e374 Compare November 27, 2023 17:51
Copy link
Member

@jeanbisutti jeanbisutti left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you please add a test for the new feature (I have not found it)?

@@ -51,6 +53,12 @@ public class OpenTelemetryAutoConfiguration {

public OpenTelemetryAutoConfiguration() {}

@Bean
@ConfigurationPropertiesBinding
public MapConverter mapConverter() {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could this bean be moved to the OpenTelemetrySdkConfig class? I don't follow how it works. mapConverter bean does not seem to be injected into the OTel code and I don't see how Spring coud reuse this bean. Could you please add a comment?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't follow where the mapConverter bean is injected and used. Is the mapConverter bean really used (are the tests green without this bean)? The parsing is not done in the OtlpExporterUtil class?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This test fails when the converter is removed:

https://github.com/zeitlinger/opentelemetry-java-instrumentation/blob/4bf15ad6529789eb848f609bf78ae2c96fc04103/instrumentation/spring/spring-boot-autoconfigure/src/test/java/io/opentelemetry/instrumentation/spring/autoconfigure/exporters/otlp/OtlpSpanExporterAutoConfigurationTest.java#L109

This is the error message:

Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'otelOtlpSpanExporter' defined in io.opentelemetry.instrumentation.spring.autoconfigure.exporters.otlp.OtlpSpanExporterAutoConfiguration: Unsatisfied dependency expressed through method 'otelOtlpSpanExporter' parameter 0; nested exception is org.springframework.boot.context.properties.ConfigurationPropertiesBindException: Error creating bean with name 'otel.exporter.otlp-io.opentelemetry.instrumentation.spring.autoconfigure.exporters.otlp.OtlpExporterProperties': Could not bind properties to 'OtlpExporterProperties' : prefix=otel.exporter.otlp, ignoreInvalidFields=false, ignoreUnknownFields=true; nested exception is org.springframework.boot.context.properties.bind.BindException: Failed to bind properties under 'otel.exporter.otlp.headers' to java.util.Map<java.lang.String, java.lang.String>

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I got it now.

Could you please update the code to:

  • Move the mapConverter bean to an autoconfiguration only related to OTLP (just realized that it's OTLP specific)
  • Only create the mapConverter bean when OTLP is enabled
  • Perhaps add a comment to explain that the mapConverter bean is necessary for the OtlpExporterProperties component?

Thank you!

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I added comments in the different places.

I tried to make the converter local, but that doesn't work:

for bean 'mapConverter' since there is already [Root bean: class [null]; scope=; abstract=false; lazyInit=null; autowireMode=3; dependencyCheck=0;

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you please give the piece of code you have added and the stack trace?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@jeanbisutti I've added support for OTEL_RESOURCE_ATTRIBUTES and OTEL_SERVICE_NAME as well now.

And I've figured out a way to make the converter conditional:

    @Bean
    @ConfigurationPropertiesBinding
    @ConditionalOnBean({OtelResourceAutoConfiguration.class, OtlpLoggerExporterAutoConfiguration.class,
        OtlpSpanExporterAutoConfiguration.class, OtlpMetricExporterAutoConfiguration.class})
    public MapConverter mapConverter() {
      // needed for otlp exporter headers and OtelResourceProperties
      return new MapConverter();
    }

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The mapConverter bean is still in the OpenTelemetryAutoConfiguration class whose responsibility is to instantiate an OpenTelemetry bean.

You could create the mapConverter bean with an OTLP-related autoconfiguration.

OtlpLoggerExporterAutoConfiguration, OtlpLoggerExporterAutoConfiguration, OtlpSpanExporterAutoConfiguration are examples of autoconfiguration.

The autoconfiguration classes have to be declared in the spring.factories (<Spring Boot 2.7) org.springframework.boot.autoconfigure.AutoConfiguration.imports (>=Spring Boot 2.7) files.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it's also used to parse otel.resource.attributes - which can be seen in the javadoc of the class

}

return builder.build();
@ConditionalOnMissingBean({OtlpGrpcSpanExporter.class, OtlpHttpSpanExporter.class})
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What about if the user adds another type of span exporter (for logging by example)?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

see below

}

return builder.build();
@ConditionalOnMissingBean({OtlpGrpcMetricExporter.class, OtlpHttpMetricExporter.class})
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What about if the user adds another type of span exporter (for logging by example)?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@zeitlinger
Copy link
Member Author

Could you please add a test for the new feature (I have not found it)?

can you help me decide which test style would fit here?
unit tests with spring don't give much safaty. maybe a smoke test?

@jeanbisutti
Copy link
Member

You have two possibilities:

Personally, I'd prefer the first option in this case because the smoke tests could become difficult to read if we check to many features (only one Spring Boot app for the smoke tests).

@zeitlinger zeitlinger force-pushed the spring-boot-otlp-header branch from a279c92 to 4bf15ad Compare December 12, 2023 12:13
@zeitlinger
Copy link
Member Author

Personally, I'd prefer the first option in this case because the smoke tests could become difficult to read if we check to many features (only one Spring Boot app for the smoke tests).

thanks for the help - and I agree.

@zeitlinger
Copy link
Member Author

@jeanbisutti can you have another look?

@jeanbisutti
Copy link
Member

@jeanbisutti can you have another look?

@zeitlinger Done

Copy link
Member

@trask trask left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thx! can you add doc for this?

@zeitlinger
Copy link
Member Author

thx! can you add doc for this?

done

@zeitlinger zeitlinger changed the title add support for OTEL_EXPORTER_OTLP_HEADERS and OTEL_EXPORTER_OTLP_PROTOCOL for spring boot starter add support for OTEL_RESOURCE_ATTRIBUTES, OTEL_SERVICE_NAME, OTEL_EXPORTER_OTLP_HEADERS and OTEL_EXPORTER_OTLP_PROTOCOL for spring boot starter Dec 13, 2023
@zeitlinger
Copy link
Member Author

@jeanbisutti final review?

@zeitlinger
Copy link
Member Author

@jeanbisutti all done 😄

| Otlp Logs Exporter | otel.exporter.otlp.logs.enabled | `true` | OtlpGrpcLogRecordExporter |
| Jaeger Exporter | otel.exporter.jaeger.enabled | `true` | JaegerGrpcSpanExporter |
| Zipkin Exporter | otel.exporter.zipkin.enabled | `true` | ZipkinSpanExporter |
| Logging Exporter | otel.exporter.logging.enabled | `false` | LoggingSpanExporter |
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why the default value of the otel.exporter.logging.enabled property has been changed from true to false?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it's not changed, the doc was wrong

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

oh, right, we should change it for 2.0, similar to #10055

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is the exporter for console logging, not otlp logging

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

oh, right, thx!

Copy link
Member

@jeanbisutti jeanbisutti left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks!


`unknown_service:java` will be used as the service-name if no value has been specified to the
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It would be great to keep this information to help users diagnose this issue

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@trask trask added this to the v2.0 milestone Dec 14, 2023
@zeitlinger
Copy link
Member Author

@jeanbisutti ready for approval 😄

@jeanbisutti
Copy link
Member

@jeanbisutti ready for approval 😄

@zeitlinger I have approved

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Align spring boot starter configuration properties with SDK autoconfigure properties
3 participants