Skip to content

Commit f85a57b

Browse files
don't throw class cast exception when we have a noop tracer, meter, logger (#6617)
Co-authored-by: Jack Berg <[email protected]>
1 parent 1f6de35 commit f85a57b

File tree

34 files changed

+1889
-536
lines changed

34 files changed

+1889
-536
lines changed

api/all/build.gradle.kts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
plugins {
22
id("otel.java-conventions")
33
id("otel.publish-conventions")
4+
id("java-test-fixtures")
45

56
id("otel.jmh-conventions")
67
id("otel.animalsniffer-conventions")
@@ -17,6 +18,10 @@ dependencies {
1718

1819
testImplementation("edu.berkeley.cs.jqf:jqf-fuzz")
1920
testImplementation("com.google.guava:guava-testlib")
21+
testFixturesApi(project(":testing-internal"))
22+
testFixturesApi("junit:junit")
23+
testFixturesApi("org.assertj:assertj-core")
24+
testFixturesApi("org.mockito:mockito-core")
2025
}
2126

2227
tasks.test {
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
/*
2+
* Copyright The OpenTelemetry Authors
3+
* SPDX-License-Identifier: Apache-2.0
4+
*/
5+
6+
package io.opentelemetry.api.internal;
7+
8+
import java.lang.reflect.Method;
9+
10+
/**
11+
* Incubating utilities.
12+
*
13+
* <p>This class is internal and is hence not for public use. Its APIs are unstable and can change
14+
* at any time.
15+
*/
16+
public class IncubatingUtil {
17+
private IncubatingUtil() {}
18+
19+
@SuppressWarnings("unchecked")
20+
public static <T> T incubatingApiIfAvailable(T stableApi, String incubatingClassName) {
21+
try {
22+
Class<?> incubatingClass = Class.forName(incubatingClassName);
23+
Method getInstance = incubatingClass.getDeclaredMethod("getNoop");
24+
return (T) getInstance.invoke(null);
25+
} catch (Exception e) {
26+
return stableApi;
27+
}
28+
}
29+
}

api/all/src/main/java/io/opentelemetry/api/logs/LoggerProvider.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55

66
package io.opentelemetry.api.logs;
77

8+
import io.opentelemetry.api.internal.IncubatingUtil;
89
import javax.annotation.concurrent.ThreadSafe;
910

1011
/**
@@ -43,6 +44,8 @@ default Logger get(String instrumentationScopeName) {
4344

4445
/** Returns a no-op {@link LoggerProvider} which provides Loggers which do not record or emit. */
4546
static LoggerProvider noop() {
46-
return DefaultLoggerProvider.getInstance();
47+
return IncubatingUtil.incubatingApiIfAvailable(
48+
DefaultLoggerProvider.getInstance(),
49+
"io.opentelemetry.api.incubator.logs.ExtendedDefaultLoggerProvider");
4750
}
4851
}

api/all/src/main/java/io/opentelemetry/api/metrics/DefaultMeterProvider.java

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,19 @@
55

66
package io.opentelemetry.api.metrics;
77

8+
import io.opentelemetry.api.internal.IncubatingUtil;
9+
810
/** A {@link MeterProvider} that does nothing. */
911
class DefaultMeterProvider implements MeterProvider {
1012
@Override
1113
public MeterBuilder meterBuilder(String instrumentationScopeName) {
1214
return BUILDER_INSTANCE;
1315
}
1416

15-
private static final DefaultMeterProvider INSTANCE = new DefaultMeterProvider();
17+
private static final MeterProvider INSTANCE =
18+
IncubatingUtil.incubatingApiIfAvailable(
19+
new DefaultMeterProvider(),
20+
"io.opentelemetry.api.incubator.metrics.ExtendedDefaultMeterProvider");
1621
private static final MeterBuilder BUILDER_INSTANCE = new NoopMeterBuilder();
1722

1823
static MeterProvider getInstance() {

api/all/src/main/java/io/opentelemetry/api/trace/DefaultTracerProvider.java

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,16 @@
55

66
package io.opentelemetry.api.trace;
77

8+
import io.opentelemetry.api.internal.IncubatingUtil;
89
import javax.annotation.concurrent.ThreadSafe;
910

1011
@ThreadSafe
1112
class DefaultTracerProvider implements TracerProvider {
1213

13-
private static final TracerProvider INSTANCE = new DefaultTracerProvider();
14+
private static final TracerProvider INSTANCE =
15+
IncubatingUtil.incubatingApiIfAvailable(
16+
new DefaultTracerProvider(),
17+
"io.opentelemetry.api.incubator.trace.ExtendedDefaultTracerProvider");
1418

1519
static TracerProvider getInstance() {
1620
return INSTANCE;

api/all/src/test/java/io/opentelemetry/api/OpenTelemetryTest.java

Lines changed: 10 additions & 86 deletions
Original file line numberDiff line numberDiff line change
@@ -5,100 +5,24 @@
55

66
package io.opentelemetry.api;
77

8-
import static org.assertj.core.api.Assertions.assertThat;
9-
import static org.assertj.core.api.Assertions.assertThatThrownBy;
10-
import static org.mockito.Mockito.mock;
11-
128
import io.opentelemetry.api.logs.LoggerProvider;
139
import io.opentelemetry.api.metrics.MeterProvider;
1410
import io.opentelemetry.api.trace.TracerProvider;
15-
import io.opentelemetry.context.propagation.ContextPropagators;
16-
import org.junit.jupiter.api.AfterEach;
17-
import org.junit.jupiter.api.BeforeAll;
18-
import org.junit.jupiter.api.Test;
19-
20-
class OpenTelemetryTest {
21-
22-
@BeforeAll
23-
static void beforeClass() {
24-
GlobalOpenTelemetry.resetForTest();
25-
}
26-
27-
@AfterEach
28-
void after() {
29-
GlobalOpenTelemetry.resetForTest();
30-
}
31-
32-
@Test
33-
void testDefault() {
34-
assertThat(OpenTelemetry.noop().getTracerProvider()).isSameAs(TracerProvider.noop());
35-
assertThat(OpenTelemetry.noop().getPropagators()).isSameAs(ContextPropagators.noop());
36-
assertThat(OpenTelemetry.noop().getMeterProvider()).isSameAs(MeterProvider.noop());
37-
assertThat(OpenTelemetry.noop().getLogsBridge()).isSameAs(LoggerProvider.noop());
38-
}
3911

40-
@Test
41-
void propagating() {
42-
ContextPropagators contextPropagators = mock(ContextPropagators.class);
43-
OpenTelemetry openTelemetry = OpenTelemetry.propagating(contextPropagators);
44-
45-
assertThat(openTelemetry.getTracerProvider()).isSameAs(TracerProvider.noop());
46-
assertThat(openTelemetry.getMeterProvider()).isSameAs(MeterProvider.noop());
47-
assertThat(openTelemetry.getLogsBridge()).isSameAs(LoggerProvider.noop());
48-
assertThat(openTelemetry.getPropagators()).isSameAs(contextPropagators);
49-
}
50-
51-
@Test
52-
void testGlobalBeforeSet() {
53-
assertThat(GlobalOpenTelemetry.getTracerProvider()).isSameAs(TracerProvider.noop());
54-
assertThat(GlobalOpenTelemetry.getTracerProvider())
55-
.isSameAs(GlobalOpenTelemetry.getTracerProvider());
56-
assertThat(GlobalOpenTelemetry.getPropagators()).isSameAs(GlobalOpenTelemetry.getPropagators());
57-
}
58-
59-
@Test
60-
void independentNonGlobalPropagators() {
61-
ContextPropagators propagators1 = mock(ContextPropagators.class);
62-
OpenTelemetry otel1 = OpenTelemetry.propagating(propagators1);
63-
ContextPropagators propagators2 = mock(ContextPropagators.class);
64-
OpenTelemetry otel2 = OpenTelemetry.propagating(propagators2);
65-
66-
assertThat(otel1.getPropagators()).isSameAs(propagators1);
67-
assertThat(otel2.getPropagators()).isSameAs(propagators2);
68-
}
69-
70-
@Test
71-
void setThenSet() {
72-
setOpenTelemetry();
73-
assertThatThrownBy(() -> GlobalOpenTelemetry.set(OpenTelemetry.noop()))
74-
.isInstanceOf(IllegalStateException.class)
75-
.hasMessageContaining("GlobalOpenTelemetry.set has already been called")
76-
.hasStackTraceContaining("setOpenTelemetry");
77-
}
78-
79-
@Test
80-
void getThenSet() {
81-
assertThat(getOpenTelemetry()).isInstanceOf(DefaultOpenTelemetry.class);
82-
assertThatThrownBy(() -> GlobalOpenTelemetry.set(OpenTelemetry.noop()))
83-
.isInstanceOf(IllegalStateException.class)
84-
.hasMessageContaining("GlobalOpenTelemetry.set has already been called")
85-
.hasStackTraceContaining("getOpenTelemetry");
86-
}
12+
class OpenTelemetryTest extends AbstractOpenTelemetryTest {
8713

88-
@Test
89-
void toString_noop_Valid() {
90-
assertThat(OpenTelemetry.noop().toString())
91-
.isEqualTo(
92-
"DefaultOpenTelemetry{"
93-
+ "propagators=DefaultContextPropagators{textMapPropagator=NoopTextMapPropagator}"
94-
+ "}");
14+
@Override
15+
protected TracerProvider getTracerProvider() {
16+
return TracerProvider.noop();
9517
}
9618

97-
private static void setOpenTelemetry() {
98-
GlobalOpenTelemetry.set(OpenTelemetry.noop());
19+
@Override
20+
protected MeterProvider getMeterProvider() {
21+
return MeterProvider.noop();
9922
}
10023

101-
private static OpenTelemetry getOpenTelemetry() {
102-
return GlobalOpenTelemetry.get();
24+
@Override
25+
protected LoggerProvider getLoggerProvider() {
26+
return LoggerProvider.noop();
10327
}
10428
}

api/all/src/test/java/io/opentelemetry/api/logs/DefaultLoggerProviderTest.java

Lines changed: 0 additions & 33 deletions
This file was deleted.

api/all/src/test/java/io/opentelemetry/api/logs/DefaultLoggerTest.java

Lines changed: 8 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -5,36 +5,15 @@
55

66
package io.opentelemetry.api.logs;
77

8-
import static org.assertj.core.api.Assertions.assertThatCode;
8+
class DefaultLoggerTest extends AbstractDefaultLoggerTest {
99

10-
import io.opentelemetry.api.common.AttributeKey;
11-
import io.opentelemetry.api.common.Attributes;
12-
import io.opentelemetry.api.common.Value;
13-
import io.opentelemetry.context.Context;
14-
import java.time.Instant;
15-
import java.util.concurrent.TimeUnit;
16-
import org.junit.jupiter.api.Test;
17-
18-
class DefaultLoggerTest {
10+
@Override
11+
protected LoggerProvider getLoggerProvider() {
12+
return DefaultLoggerProvider.getInstance();
13+
}
1914

20-
@Test
21-
void buildAndEmit() {
22-
assertThatCode(
23-
() ->
24-
DefaultLogger.getInstance()
25-
.logRecordBuilder()
26-
.setTimestamp(100, TimeUnit.SECONDS)
27-
.setTimestamp(Instant.now())
28-
.setObservedTimestamp(100, TimeUnit.SECONDS)
29-
.setObservedTimestamp(Instant.now())
30-
.setContext(Context.root())
31-
.setSeverity(Severity.DEBUG)
32-
.setSeverityText("debug")
33-
.setBody("body")
34-
.setBody(Value.of("body"))
35-
.setAttribute(AttributeKey.stringKey("key1"), "value1")
36-
.setAllAttributes(Attributes.builder().put("key2", "value2").build())
37-
.emit())
38-
.doesNotThrowAnyException();
15+
@Override
16+
protected Logger getLogger() {
17+
return DefaultLogger.getInstance();
3918
}
4019
}

api/all/src/test/java/io/opentelemetry/api/metrics/DefaultMeterProviderTest.java

Lines changed: 0 additions & 29 deletions
This file was deleted.

0 commit comments

Comments
 (0)