Skip to content

Commit f83d1a7

Browse files
committed
Reuse registered global OpenTelemetry
Spring Boot instrumentation will be included when applications are running with OpenTelemetry Java Agent. Signed-off-by: Yanming Zhou <[email protected]>
1 parent b6b570e commit f83d1a7

File tree

2 files changed

+52
-0
lines changed

2 files changed

+52
-0
lines changed

spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/opentelemetry/OpenTelemetryAutoConfiguration.java

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616

1717
package org.springframework.boot.actuate.autoconfigure.opentelemetry;
1818

19+
import io.opentelemetry.api.GlobalOpenTelemetry;
1920
import io.opentelemetry.api.OpenTelemetry;
2021
import io.opentelemetry.context.propagation.ContextPropagators;
2122
import io.opentelemetry.sdk.OpenTelemetrySdk;
@@ -29,23 +30,37 @@
2930
import org.springframework.beans.factory.ObjectProvider;
3031
import org.springframework.boot.autoconfigure.AutoConfiguration;
3132
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
33+
import org.springframework.boot.autoconfigure.condition.ConditionMessage;
34+
import org.springframework.boot.autoconfigure.condition.ConditionOutcome;
3235
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
3336
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
37+
import org.springframework.boot.autoconfigure.condition.SpringBootCondition;
3438
import org.springframework.boot.context.properties.EnableConfigurationProperties;
3539
import org.springframework.context.annotation.Bean;
40+
import org.springframework.context.annotation.ConditionContext;
41+
import org.springframework.context.annotation.Conditional;
3642
import org.springframework.core.env.Environment;
43+
import org.springframework.core.type.AnnotatedTypeMetadata;
3744

3845
/**
3946
* {@link EnableAutoConfiguration Auto-configuration} for OpenTelemetry.
4047
*
4148
* @author Moritz Halbritter
49+
* @author Yanming Zhou
4250
* @since 3.2.0
4351
*/
4452
@AutoConfiguration
4553
@ConditionalOnClass(OpenTelemetrySdk.class)
4654
@EnableConfigurationProperties(OpenTelemetryProperties.class)
4755
public class OpenTelemetryAutoConfiguration {
4856

57+
@Bean
58+
@ConditionalOnMissingBean(OpenTelemetry.class)
59+
@Conditional(OnRegisteredGlobalOpenTelemetryCondition.class)
60+
OpenTelemetry globalOpenTelemetry() {
61+
return GlobalOpenTelemetry.get();
62+
}
63+
4964
@Bean
5065
@ConditionalOnMissingBean(OpenTelemetry.class)
5166
OpenTelemetrySdk openTelemetry(ObjectProvider<SdkTracerProvider> tracerProvider,
@@ -72,4 +87,15 @@ private Resource toResource(Environment environment, OpenTelemetryProperties pro
7287
return builder.build();
7388
}
7489

90+
static class OnRegisteredGlobalOpenTelemetryCondition extends SpringBootCondition {
91+
92+
@Override
93+
public ConditionOutcome getMatchOutcome(ConditionContext context, AnnotatedTypeMetadata metadata) {
94+
boolean globalOpenTelemetryRegistered = GlobalOpenTelemetry.get() != OpenTelemetry.noop();
95+
return new ConditionOutcome(globalOpenTelemetryRegistered, ConditionMessage
96+
.of("GlobalOpenTelemetry is" + (globalOpenTelemetryRegistered ? "not" : "") + " NOOP"));
97+
}
98+
99+
}
100+
75101
}

spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/opentelemetry/OpenTelemetryAutoConfigurationTests.java

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,14 +16,18 @@
1616

1717
package org.springframework.boot.actuate.autoconfigure.opentelemetry;
1818

19+
import io.opentelemetry.api.GlobalOpenTelemetry;
1920
import io.opentelemetry.api.OpenTelemetry;
2021
import io.opentelemetry.api.common.AttributeKey;
22+
import io.opentelemetry.api.trace.Tracer;
23+
import io.opentelemetry.api.trace.TracerProvider;
2124
import io.opentelemetry.context.propagation.ContextPropagators;
2225
import io.opentelemetry.sdk.OpenTelemetrySdk;
2326
import io.opentelemetry.sdk.logs.SdkLoggerProvider;
2427
import io.opentelemetry.sdk.metrics.SdkMeterProvider;
2528
import io.opentelemetry.sdk.resources.Resource;
2629
import io.opentelemetry.sdk.trace.SdkTracerProvider;
30+
import org.junit.jupiter.api.BeforeEach;
2731
import org.junit.jupiter.api.Test;
2832

2933
import org.springframework.boot.autoconfigure.AutoConfiguration;
@@ -36,18 +40,26 @@
3640

3741
import static org.assertj.core.api.Assertions.assertThat;
3842
import static org.assertj.core.api.Assertions.entry;
43+
import static org.mockito.ArgumentMatchers.eq;
44+
import static org.mockito.BDDMockito.given;
3945
import static org.mockito.Mockito.mock;
4046

4147
/**
4248
* Tests for {@link OpenTelemetryAutoConfiguration}.
4349
*
4450
* @author Moritz Halbritter
51+
* @author Yanming Zhou
4552
*/
4653
class OpenTelemetryAutoConfigurationTests {
4754

4855
private final ApplicationContextRunner runner = new ApplicationContextRunner()
4956
.withConfiguration(AutoConfigurations.of(OpenTelemetryAutoConfiguration.class));
5057

58+
@BeforeEach
59+
void reset() {
60+
GlobalOpenTelemetry.resetForTest();
61+
}
62+
5163
@Test
5264
void isRegisteredInAutoConfigurationImports() {
5365
assertThat(ImportCandidates.load(AutoConfiguration.class, null).getCandidates())
@@ -62,6 +74,20 @@ void shouldProvideBeans() {
6274
});
6375
}
6476

77+
@Test
78+
void reuseRegisteredGlobalOpenTelemetry() {
79+
OpenTelemetry openTelemetry = mock(OpenTelemetry.class);
80+
TracerProvider tracerProvider = mock(TracerProvider.class);
81+
Tracer tracer = mock(Tracer.class);
82+
given(tracerProvider.get(eq("org.springframework.boot"))).willReturn(tracer);
83+
given(openTelemetry.getTracerProvider()).willReturn(tracerProvider);
84+
GlobalOpenTelemetry.set(openTelemetry);
85+
this.runner.run((context) -> {
86+
assertThat(context).doesNotHaveBean(OpenTelemetrySdk.class);
87+
assertThat(context.getBean(OpenTelemetry.class).getTracer("org.springframework.boot")).isSameAs(tracer);
88+
});
89+
}
90+
6591
@Test
6692
void shouldBackOffIfOpenTelemetryIsNotOnClasspath() {
6793
this.runner.withClassLoader(new FilteredClassLoader("io.opentelemetry")).run((context) -> {

0 commit comments

Comments
 (0)