Describe the bug
When using opentelemetry-spring-boot-starter to autoconfigure the OpenTelemetry Logback instrumentation (both logback-mdc-1.0 and logback-appender-1.0), a duplicate io.opentelemetry.instrumentation.logback.appender.v1_0.OpenTelemetryAppender is added if one is already defined in logback xml. However, it seems like the intention is for the autoconfiguration to reinitialize it.
Steps to reproduce
Run the ./mvnw test on the opentelemetry-logging-test.zip project, and one of the unit tests will fail showing the problem.
Or manually, you can reproduce it in another project like this:
Use opentelemetry-spring-boot-starter in a Spring Boot application.
Enable both logback-mdc-1.0 and logback-appender-1.0
otel:
metrics:
exporter: none
traces:
exporter: none
logs:
exporter: console
instrumentation:
common:
default-enabled: false
logback-appender:
enabled: true
experimental:
capture-key-value-pair-attributes: true
logback-mdc:
enabled: true
Add an io.opentelemetry.instrumentation.logback.appender.v1_0.OpenTelemetryAppender to the logback xml. Note that sometimes adding this appender in the logback xml is explicitly needed to be able to add the appender to multiple loggers (especially if those loggers have additivity=false and don't forward events to the root logger)
<appender name="opentelemetry" class="io.opentelemetry.instrumentation.logback.appender.v1_0.OpenTelemetryAppender"/>
<root level="info">
<appender-ref ref="console"/>
<appender-ref ref="opentelemetry"/>
</root>
Start the application
Expected behavior
Expect the opentelemetry-spring-boot-starter's autoconfiguration to initialize the opentelemetry appender with the configuration properties defined in the spring environment (in this case, capture-key-value-pair-attributes: true)
Actual behavior
The opentelemetry-spring-boot-starter's autoconfiguration:
- Adds a new
io.opentelemetry.instrumentation.logback.mdc.v1_0.OpenTelemetryAppender to the root logger
- Moves the existing
opentelemetry appender "beneath" the io.opentelemetry.instrumentation.logback.mdc.v1_0.OpenTelemetryAppender
- Does not find the existing
io.opentelemetry.instrumentation.logback.appender.v1_0.OpenTelemetryAppender, since it is now beneath the io.opentelemetry.instrumentation.logback.mdc.v1_0.OpenTelemetryAppender
- Adds a new
io.opentelemetry.instrumentation.logback.appender.v1_0.OpenTelemetryAppender to the root logger, an initializes it with the properties from the Spring Boot environment
So now, the configuration looks something like this:
root logger
--> io.opentelemetry.instrumentation.logback.mdc.v1_0.OpenTelemetryAppender (added by autoconfig)
--> io.opentelemetry.instrumentation.logback.appender.v1_0.OpenTelemetryAppender (existing from logback xml. NOT configured with Spring environment properties)
--> io.opentelemetry.instrumentation.logback.appender.v1_0.OpenTelemetryAppender (added by autoconfig, configured with Spring environment properties)
Note that there are now two io.opentelemetry.instrumentation.logback.appender.v1_0.OpenTelemetryAppender instances. One of them from logback xml. One of them added by autoconfig. Only the one added by autoconfig is configured with properties from the Spring environment.
Given this code, I would have expected the autoconfiguration to find and reinitialize the appender configured in the logback xml with the Spring environment properties.
Javaagent or library instrumentation version
2.25.0-alpha
Environment
JDK: Temurin 25.0.2
OS: Ubuntu 24.04
Additional context
Another observation: Later... the opentelemetry-spring-boot-starter autoconfiguration finds both io.opentelemetry.instrumentation.logback.appender.v1_0.OpenTelemetryAppender instances, and injects the OpenTelemetry object into them.
So, when injecting OpenTelemetry it does find and initialize the existing io.opentelemetry.instrumentation.logback.appender.v1_0.OpenTelemetryAppender.
But when searching for the existing io.opentelemetry.instrumentation.logback.appender.v1_0.OpenTelemetryAppender to initialize with Spring environment properties, it does not find it (if logback-mdc-1.0 instrumentation is also enabled).
If logback-mdc-1.0 instrumentation is disabled, then opentelemetry-spring-boot-starter autoconfiguration will find and reinitialize the io.opentelemetry.instrumentation.logback.appender.v1_0.OpenTelemetryAppender from the logback.xml.
Regarding how to fix this. I think the simplest fix is to make LogbackAppenderInstaller.findAppender search through subappenders, similar to OpenTelemetryAppender.install
This would allow the LogbackAppenderInstaller to find the io.opentelemetry.instrumentation.logback.appender.v1_0.OpenTelemetryAppender that it moved beneath the io.opentelemetry.instrumentation.logback.mdc.v1_0.OpenTelemetryAppender.
Tip
React with 👍 to help prioritize this issue. Please use comments to provide useful context, avoiding +1 or me too, to help us triage it. Learn more here.
Describe the bug
When using opentelemetry-spring-boot-starter to autoconfigure the OpenTelemetry Logback instrumentation (both logback-mdc-1.0 and logback-appender-1.0), a duplicate
io.opentelemetry.instrumentation.logback.appender.v1_0.OpenTelemetryAppenderis added if one is already defined in logback xml. However, it seems like the intention is for the autoconfiguration to reinitialize it.Steps to reproduce
Run the
./mvnw teston the opentelemetry-logging-test.zip project, and one of the unit tests will fail showing the problem.Or manually, you can reproduce it in another project like this:
Use opentelemetry-spring-boot-starter in a Spring Boot application.
Enable both logback-mdc-1.0 and logback-appender-1.0
Add an
io.opentelemetry.instrumentation.logback.appender.v1_0.OpenTelemetryAppenderto the logback xml. Note that sometimes adding this appender in the logback xml is explicitly needed to be able to add the appender to multiple loggers (especially if those loggers have additivity=false and don't forward events to the root logger)Start the application
Expected behavior
Expect the opentelemetry-spring-boot-starter's autoconfiguration to initialize the opentelemetry appender with the configuration properties defined in the spring environment (in this case, capture-key-value-pair-attributes: true)
Actual behavior
The opentelemetry-spring-boot-starter's autoconfiguration:
io.opentelemetry.instrumentation.logback.mdc.v1_0.OpenTelemetryAppenderto the root loggeropentelemetryappender "beneath" theio.opentelemetry.instrumentation.logback.mdc.v1_0.OpenTelemetryAppenderio.opentelemetry.instrumentation.logback.appender.v1_0.OpenTelemetryAppender, since it is now beneath theio.opentelemetry.instrumentation.logback.mdc.v1_0.OpenTelemetryAppenderio.opentelemetry.instrumentation.logback.appender.v1_0.OpenTelemetryAppenderto the root logger, an initializes it with the properties from the Spring Boot environmentSo now, the configuration looks something like this:
Note that there are now two
io.opentelemetry.instrumentation.logback.appender.v1_0.OpenTelemetryAppenderinstances. One of them from logback xml. One of them added by autoconfig. Only the one added by autoconfig is configured with properties from the Spring environment.Given this code, I would have expected the autoconfiguration to find and reinitialize the appender configured in the logback xml with the Spring environment properties.
Javaagent or library instrumentation version
2.25.0-alpha
Environment
JDK: Temurin 25.0.2
OS: Ubuntu 24.04
Additional context
Another observation: Later... the opentelemetry-spring-boot-starter autoconfiguration finds both
io.opentelemetry.instrumentation.logback.appender.v1_0.OpenTelemetryAppenderinstances, and injects theOpenTelemetryobject into them.So, when injecting
OpenTelemetryit does find and initialize the existingio.opentelemetry.instrumentation.logback.appender.v1_0.OpenTelemetryAppender.But when searching for the existing
io.opentelemetry.instrumentation.logback.appender.v1_0.OpenTelemetryAppenderto initialize with Spring environment properties, it does not find it (if logback-mdc-1.0 instrumentation is also enabled).If logback-mdc-1.0 instrumentation is disabled, then opentelemetry-spring-boot-starter autoconfiguration will find and reinitialize the
io.opentelemetry.instrumentation.logback.appender.v1_0.OpenTelemetryAppenderfrom the logback.xml.Regarding how to fix this. I think the simplest fix is to make
LogbackAppenderInstaller.findAppendersearch through subappenders, similar toOpenTelemetryAppender.installThis would allow the
LogbackAppenderInstallerto find theio.opentelemetry.instrumentation.logback.appender.v1_0.OpenTelemetryAppenderthat it moved beneath theio.opentelemetry.instrumentation.logback.mdc.v1_0.OpenTelemetryAppender.Tip
React with 👍 to help prioritize this issue. Please use comments to provide useful context, avoiding
+1orme too, to help us triage it. Learn more here.