Skip to content

Commit 17f1cf1

Browse files
committed
Allow reusing 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 5db3cac commit 17f1cf1

File tree

3 files changed

+63
-0
lines changed

3 files changed

+63
-0
lines changed

spring-boot-project/spring-boot-opentelemetry/src/main/java/org/springframework/boot/opentelemetry/autoconfigure/OpenTelemetryProperties.java

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,16 +25,30 @@
2525
* Configuration properties for OpenTelemetry.
2626
*
2727
* @author Moritz Halbritter
28+
* @author Yanming Zhou
2829
* @since 4.0.0
2930
*/
3031
@ConfigurationProperties("management.opentelemetry")
3132
public class OpenTelemetryProperties {
3233

34+
/**
35+
* Whether to reuse registered global OpenTelemetry.
36+
*/
37+
private boolean reuseRegisteredGlobal;
38+
3339
/**
3440
* Resource attributes.
3541
*/
3642
private Map<String, String> resourceAttributes = new HashMap<>();
3743

44+
public boolean isReuseRegisteredGlobal() {
45+
return this.reuseRegisteredGlobal;
46+
}
47+
48+
public void setReuseRegisteredGlobal(boolean reuseRegisteredGlobal) {
49+
this.reuseRegisteredGlobal = reuseRegisteredGlobal;
50+
}
51+
3852
public Map<String, String> getResourceAttributes() {
3953
return this.resourceAttributes;
4054
}

spring-boot-project/spring-boot-opentelemetry/src/main/java/org/springframework/boot/opentelemetry/autoconfigure/OpenTelemetrySdkAutoConfiguration.java

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

1717
package org.springframework.boot.opentelemetry.autoconfigure;
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;
@@ -33,17 +34,25 @@
3334
import org.springframework.beans.factory.ObjectProvider;
3435
import org.springframework.boot.autoconfigure.AutoConfiguration;
3536
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
37+
import org.springframework.boot.autoconfigure.condition.ConditionMessage;
38+
import org.springframework.boot.autoconfigure.condition.ConditionOutcome;
39+
import org.springframework.boot.autoconfigure.condition.ConditionalOnBooleanProperty;
3640
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
3741
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
42+
import org.springframework.boot.autoconfigure.condition.SpringBootCondition;
3843
import org.springframework.boot.context.properties.EnableConfigurationProperties;
3944
import org.springframework.context.annotation.Bean;
45+
import org.springframework.context.annotation.ConditionContext;
46+
import org.springframework.context.annotation.Conditional;
4047
import org.springframework.context.annotation.Configuration;
4148
import org.springframework.core.env.Environment;
49+
import org.springframework.core.type.AnnotatedTypeMetadata;
4250

4351
/**
4452
* {@link EnableAutoConfiguration Auto-configuration} for the OpenTelemetry SDK.
4553
*
4654
* @author Moritz Halbritter
55+
* @author Yanming Zhou
4756
* @since 4.0.0
4857
*/
4958
@AutoConfiguration
@@ -54,6 +63,14 @@ public class OpenTelemetrySdkAutoConfiguration {
5463
OpenTelemetrySdkAutoConfiguration() {
5564
}
5665

66+
@Bean
67+
@ConditionalOnMissingBean(OpenTelemetry.class)
68+
@ConditionalOnBooleanProperty("management.opentelemetry.reuse-registered-global")
69+
@Conditional(OnRegisteredGlobalOpenTelemetryCondition.class)
70+
OpenTelemetry globalOpenTelemetry() {
71+
return GlobalOpenTelemetry.get();
72+
}
73+
5774
@Bean
5875
@ConditionalOnMissingBean(OpenTelemetry.class)
5976
OpenTelemetrySdk openTelemetrySdk(ObjectProvider<SdkTracerProvider> openTelemetrySdkTracerProvider,
@@ -106,4 +123,15 @@ SdkLoggerProvider openTelemetrySdkLoggerProvider(Resource openTelemetryResource,
106123

107124
}
108125

126+
static class OnRegisteredGlobalOpenTelemetryCondition extends SpringBootCondition {
127+
128+
@Override
129+
public ConditionOutcome getMatchOutcome(ConditionContext context, AnnotatedTypeMetadata metadata) {
130+
boolean globalOpenTelemetryRegistered = GlobalOpenTelemetry.get() != OpenTelemetry.noop();
131+
return new ConditionOutcome(globalOpenTelemetryRegistered, ConditionMessage
132+
.of("GlobalOpenTelemetry is" + (globalOpenTelemetryRegistered ? "" : " not") + " registered"));
133+
}
134+
135+
}
136+
109137
}

spring-boot-project/spring-boot-opentelemetry/src/test/java/org/springframework/boot/opentelemetry/autoconfigure/OpenTelemetrySdkAutoConfigurationTests.java

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,11 @@
1919
import java.util.Collection;
2020
import java.util.concurrent.atomic.AtomicInteger;
2121

22+
import io.opentelemetry.api.GlobalOpenTelemetry;
2223
import io.opentelemetry.api.OpenTelemetry;
2324
import io.opentelemetry.api.common.AttributeKey;
25+
import io.opentelemetry.api.trace.Tracer;
26+
import io.opentelemetry.api.trace.TracerProvider;
2427
import io.opentelemetry.context.Context;
2528
import io.opentelemetry.context.propagation.ContextPropagators;
2629
import io.opentelemetry.sdk.OpenTelemetrySdk;
@@ -49,6 +52,8 @@
4952

5053
import static org.assertj.core.api.Assertions.assertThat;
5154
import static org.assertj.core.api.Assertions.entry;
55+
import static org.mockito.ArgumentMatchers.eq;
56+
import static org.mockito.BDDMockito.given;
5257
import static org.mockito.Mockito.mock;
5358

5459
/**
@@ -57,6 +62,7 @@
5762
* @author Moritz Halbritter
5863
* @author Toshiaki Maki
5964
* @author Phillip Webb
65+
* @author Yanming Zhou
6066
*/
6167
class OpenTelemetrySdkAutoConfigurationTests {
6268

@@ -240,6 +246,21 @@ void whenHasMultipleSdkLoggerProviderBuilderCustomizersCallsCustomizeMethod() {
240246
});
241247
}
242248

249+
@Test
250+
void reuseRegisteredGlobalOpenTelemetry() {
251+
OpenTelemetry openTelemetry = mock(OpenTelemetry.class);
252+
TracerProvider tracerProvider = mock(TracerProvider.class);
253+
Tracer tracer = mock(Tracer.class);
254+
given(tracerProvider.get(eq("org.springframework.boot"))).willReturn(tracer);
255+
given(openTelemetry.getTracerProvider()).willReturn(tracerProvider);
256+
GlobalOpenTelemetry.set(openTelemetry);
257+
this.contextRunner.withPropertyValues("management.opentelemetry.reuse-registered-global=true")
258+
.run((context) -> {
259+
assertThat(context).doesNotHaveBean(OpenTelemetrySdk.class);
260+
assertThat(context.getBean(OpenTelemetry.class).getTracer("org.springframework.boot")).isSameAs(tracer);
261+
});
262+
}
263+
243264
@Configuration(proxyBeanMethods = false)
244265
static class UserConfiguration {
245266

0 commit comments

Comments
 (0)