Skip to content

Commit 8a66ed9

Browse files
committed
support ExtendedOpenTelemetry in GlobalOpenTelemetry
1 parent 2c379c7 commit 8a66ed9

File tree

4 files changed

+153
-45
lines changed

4 files changed

+153
-45
lines changed

api/all/src/main/java/io/opentelemetry/api/GlobalOpenTelemetry.java

Lines changed: 4 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77

88
import io.opentelemetry.api.internal.ConfigUtil;
99
import io.opentelemetry.api.internal.GuardedBy;
10-
import io.opentelemetry.api.logs.LoggerProvider;
10+
import io.opentelemetry.api.internal.IncubatingUtil;
1111
import io.opentelemetry.api.metrics.Meter;
1212
import io.opentelemetry.api.metrics.MeterBuilder;
1313
import io.opentelemetry.api.metrics.MeterProvider;
@@ -21,7 +21,6 @@
2121
import java.util.logging.Level;
2222
import java.util.logging.Logger;
2323
import javax.annotation.Nullable;
24-
import javax.annotation.concurrent.ThreadSafe;
2524

2625
/**
2726
* A global singleton for the entrypoint to telemetry functionality for tracing, metrics and
@@ -56,7 +55,7 @@ public final class GlobalOpenTelemetry {
5655

5756
@SuppressWarnings("NonFinalStaticField")
5857
@Nullable
59-
private static volatile ObfuscatedOpenTelemetry globalOpenTelemetry;
58+
private static volatile OpenTelemetry globalOpenTelemetry;
6059

6160
@SuppressWarnings("NonFinalStaticField")
6261
@GuardedBy("mutex")
@@ -112,7 +111,7 @@ public static void set(OpenTelemetry openTelemetry) {
112111
+ "instead. Previous invocation set to cause of this exception.",
113112
setGlobalCaller);
114113
}
115-
globalOpenTelemetry = new ObfuscatedOpenTelemetry(openTelemetry);
114+
globalOpenTelemetry = IncubatingUtil.obfuscatedOpenTelemetry(openTelemetry);
116115
setGlobalCaller = new Throwable();
117116
}
118117
}
@@ -261,7 +260,7 @@ private static OpenTelemetry maybeAutoConfigureAndSetGlobal() {
261260
Object autoConfiguredSdk = initialize.invoke(null);
262261
Method getOpenTelemetrySdk =
263262
openTelemetrySdkAutoConfiguration.getMethod("getOpenTelemetrySdk");
264-
return new ObfuscatedOpenTelemetry(
263+
return IncubatingUtil.obfuscatedOpenTelemetry(
265264
(OpenTelemetry) getOpenTelemetrySdk.invoke(autoConfiguredSdk));
266265
} catch (NoSuchMethodException | IllegalAccessException e) {
267266
throw new IllegalStateException(
@@ -276,44 +275,4 @@ private static OpenTelemetry maybeAutoConfigureAndSetGlobal() {
276275
return null;
277276
}
278277
}
279-
280-
/**
281-
* Static global instances are obfuscated when they are returned from the API to prevent users
282-
* from casting them to their SDK-specific implementation. For example, we do not want users to
283-
* use patterns like {@code (OpenTelemetrySdk) GlobalOpenTelemetry.get()}.
284-
*/
285-
@ThreadSafe
286-
static class ObfuscatedOpenTelemetry implements OpenTelemetry {
287-
288-
private final OpenTelemetry delegate;
289-
290-
ObfuscatedOpenTelemetry(OpenTelemetry delegate) {
291-
this.delegate = delegate;
292-
}
293-
294-
@Override
295-
public TracerProvider getTracerProvider() {
296-
return delegate.getTracerProvider();
297-
}
298-
299-
@Override
300-
public MeterProvider getMeterProvider() {
301-
return delegate.getMeterProvider();
302-
}
303-
304-
@Override
305-
public LoggerProvider getLogsBridge() {
306-
return delegate.getLogsBridge();
307-
}
308-
309-
@Override
310-
public ContextPropagators getPropagators() {
311-
return delegate.getPropagators();
312-
}
313-
314-
@Override
315-
public TracerBuilder tracerBuilder(String instrumentationScopeName) {
316-
return delegate.tracerBuilder(instrumentationScopeName);
317-
}
318-
}
319278
}

api/all/src/main/java/io/opentelemetry/api/internal/IncubatingUtil.java

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,13 @@
55

66
package io.opentelemetry.api.internal;
77

8+
import io.opentelemetry.api.OpenTelemetry;
9+
import io.opentelemetry.api.logs.LoggerProvider;
10+
import io.opentelemetry.api.metrics.MeterProvider;
11+
import io.opentelemetry.api.trace.TracerBuilder;
12+
import io.opentelemetry.api.trace.TracerProvider;
13+
import io.opentelemetry.context.propagation.ContextPropagators;
14+
import javax.annotation.concurrent.ThreadSafe;
815
import java.lang.reflect.Method;
916

1017
/**
@@ -26,4 +33,63 @@ public static <T> T incubatingApiIfAvailable(T stableApi, String incubatingClass
2633
return stableApi;
2734
}
2835
}
36+
37+
public static OpenTelemetry obfuscatedOpenTelemetry(OpenTelemetry openTelemetry) {
38+
try {
39+
Class<?> extendedClass =
40+
Class.forName("io.opentelemetry.api.incubator.ExtendedOpenTelemetry");
41+
if (extendedClass.isInstance(openTelemetry)) {
42+
Class<?> incubatingClass =
43+
Class.forName(
44+
"io.opentelemetry.api.incubator.internal.ObfuscatedExtendedOpenTelemetry");
45+
return (OpenTelemetry)
46+
incubatingClass
47+
.getDeclaredConstructor(extendedClass)
48+
.newInstance(extendedClass.cast(openTelemetry));
49+
}
50+
} catch (Exception e) {
51+
// incubator not available
52+
}
53+
return new ObfuscatedOpenTelemetry(openTelemetry);
54+
}
55+
56+
/**
57+
* Static global instances are obfuscated when they are returned from the API to prevent users
58+
* from casting them to their SDK-specific implementation. For example, we do not want users to
59+
* use patterns like {@code (OpenTelemetrySdk) GlobalOpenTelemetry.get()}.
60+
*/
61+
@ThreadSafe
62+
static class ObfuscatedOpenTelemetry implements OpenTelemetry {
63+
64+
private final OpenTelemetry delegate;
65+
66+
ObfuscatedOpenTelemetry(OpenTelemetry delegate) {
67+
this.delegate = delegate;
68+
}
69+
70+
@Override
71+
public TracerProvider getTracerProvider() {
72+
return delegate.getTracerProvider();
73+
}
74+
75+
@Override
76+
public MeterProvider getMeterProvider() {
77+
return delegate.getMeterProvider();
78+
}
79+
80+
@Override
81+
public LoggerProvider getLogsBridge() {
82+
return delegate.getLogsBridge();
83+
}
84+
85+
@Override
86+
public ContextPropagators getPropagators() {
87+
return delegate.getPropagators();
88+
}
89+
90+
@Override
91+
public TracerBuilder tracerBuilder(String instrumentationScopeName) {
92+
return delegate.tracerBuilder(instrumentationScopeName);
93+
}
94+
}
2995
}
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
package io.opentelemetry.api.incubator.internal;
2+
3+
import io.opentelemetry.api.OpenTelemetry;
4+
import io.opentelemetry.api.incubator.ExtendedOpenTelemetry;
5+
import io.opentelemetry.api.incubator.config.ConfigProvider;
6+
import io.opentelemetry.api.logs.LoggerProvider;
7+
import io.opentelemetry.api.metrics.MeterProvider;
8+
import io.opentelemetry.api.trace.TracerBuilder;
9+
import io.opentelemetry.api.trace.TracerProvider;
10+
import io.opentelemetry.context.propagation.ContextPropagators;
11+
import javax.annotation.concurrent.ThreadSafe;
12+
13+
/**
14+
* Static global instances are obfuscated when they are returned from the API to prevent users from
15+
* casting them to their SDK-specific implementation. For example, we do not want users to use
16+
* patterns like {@code (OpenTelemetrySdk) GlobalOpenTelemetry.get()}.
17+
*
18+
* <p>This class is internal and is hence not for public use. Its APIs are unstable and can change
19+
* at any time.
20+
*/
21+
@ThreadSafe
22+
public final class ObfuscatedExtendedOpenTelemetry implements ExtendedOpenTelemetry {
23+
24+
private final ExtendedOpenTelemetry delegate;
25+
26+
/**
27+
* This constructor is called via reflection from {@link
28+
* io.opentelemetry.api.internal.IncubatingUtil#obfuscatedOpenTelemetry(OpenTelemetry)}
29+
*/
30+
public ObfuscatedExtendedOpenTelemetry(ExtendedOpenTelemetry delegate) {
31+
this.delegate = delegate;
32+
}
33+
34+
@Override
35+
public TracerProvider getTracerProvider() {
36+
return delegate.getTracerProvider();
37+
}
38+
39+
@Override
40+
public MeterProvider getMeterProvider() {
41+
return delegate.getMeterProvider();
42+
}
43+
44+
@Override
45+
public LoggerProvider getLogsBridge() {
46+
return delegate.getLogsBridge();
47+
}
48+
49+
@Override
50+
public ContextPropagators getPropagators() {
51+
return delegate.getPropagators();
52+
}
53+
54+
@Override
55+
public TracerBuilder tracerBuilder(String instrumentationScopeName) {
56+
return delegate.tracerBuilder(instrumentationScopeName);
57+
}
58+
59+
@Override
60+
public ConfigProvider getConfigProvider() {
61+
return delegate.getConfigProvider();
62+
}
63+
}

api/incubator/src/test/java/io/opentelemetry/api/incubator/ExtendedOpenTelemetryTest.java

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77

88
import static org.assertj.core.api.Assertions.assertThat;
99

10+
import io.opentelemetry.api.GlobalOpenTelemetry;
1011
import io.opentelemetry.api.OpenTelemetry;
1112
import io.opentelemetry.api.incubator.logs.ExtendedDefaultLoggerProvider;
1213
import io.opentelemetry.api.incubator.logs.ExtendedLogger;
@@ -19,6 +20,11 @@
1920
import io.opentelemetry.api.testing.internal.AbstractOpenTelemetryTest;
2021
import io.opentelemetry.api.trace.TracerProvider;
2122
import io.opentelemetry.context.propagation.ContextPropagators;
23+
import io.opentelemetry.sdk.OpenTelemetrySdk;
24+
import io.opentelemetry.sdk.extension.incubator.ExtendedOpenTelemetrySdk;
25+
import io.opentelemetry.sdk.extension.incubator.fileconfig.SdkConfigProvider;
26+
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.OpenTelemetryConfigurationModel;
27+
import org.junit.jupiter.api.BeforeEach;
2228
import org.junit.jupiter.api.Test;
2329

2430
class ExtendedOpenTelemetryTest extends AbstractOpenTelemetryTest {
@@ -38,12 +44,26 @@ protected LoggerProvider getLoggerProvider() {
3844
return ExtendedDefaultLoggerProvider.getNoop();
3945
}
4046

47+
@BeforeEach
48+
void setUp() {
49+
GlobalOpenTelemetry.resetForTest();
50+
}
51+
4152
@Test
4253
void incubatingApiIsLoaded() {
4354
assertIsExtended(OpenTelemetry.noop());
4455
assertIsExtended(OpenTelemetry.propagating(ContextPropagators.noop()));
4556
}
4657

58+
@Test
59+
void globalOpenTelemetry() {
60+
GlobalOpenTelemetry.set(
61+
ExtendedOpenTelemetrySdk.create(
62+
OpenTelemetrySdk.builder().build(),
63+
SdkConfigProvider.create(new OpenTelemetryConfigurationModel())));
64+
assertThat(GlobalOpenTelemetry.get()).isInstanceOf(ExtendedOpenTelemetry.class);
65+
}
66+
4767
private static void assertIsExtended(OpenTelemetry openTelemetry) {
4868
assertThat(openTelemetry.getMeter("test").counterBuilder("test"))
4969
.isInstanceOf(ExtendedLongCounterBuilder.class);

0 commit comments

Comments
 (0)