Skip to content

Commit 8c8a96c

Browse files
committed
use customizer that can be easily added by native instrumentations and is added for agent and starter by default
1 parent 4dd3fd3 commit 8c8a96c

File tree

10 files changed

+92
-70
lines changed

10 files changed

+92
-70
lines changed

instrumentation-api-incubator/build.gradle.kts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ dependencies {
2222

2323
testImplementation("io.opentelemetry.javaagent:opentelemetry-testing-common")
2424
testImplementation("io.opentelemetry:opentelemetry-sdk")
25+
testImplementation("io.opentelemetry:opentelemetry-sdk-extension-incubator")
2526
testImplementation("io.opentelemetry:opentelemetry-sdk-testing")
2627
testImplementation("io.opentelemetry.semconv:opentelemetry-semconv-incubating")
2728
}

instrumentation-api-incubator/src/main/java/io/opentelemetry/instrumentation/api/incubator/instrumenter/InstrumenterCustomizer.java

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

66
package io.opentelemetry.instrumentation.api.incubator.instrumenter;
77

8+
import io.opentelemetry.api.OpenTelemetry;
89
import io.opentelemetry.context.Context;
910
import io.opentelemetry.instrumentation.api.instrumenter.AttributesExtractor;
1011
import io.opentelemetry.instrumentation.api.instrumenter.ContextCustomizer;
@@ -34,6 +35,13 @@ public interface InstrumenterCustomizer {
3435
*/
3536
String getInstrumentationName();
3637

38+
/**
39+
* Returns the OpenTelemetry instance associated with this instrumenter.
40+
*
41+
* @return the OpenTelemetry instance
42+
*/
43+
OpenTelemetry getOpenTelemetry();
44+
3745
/**
3846
* Tests whether given instrumenter produces telemetry of specified type. Instrumentation type is
3947
* detected based on the standard {@link AttributesExtractor} implementations used by this
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
package io.opentelemetry.instrumentation.api.incubator.instrumenter;
2+
3+
import io.opentelemetry.api.OpenTelemetry;
4+
import io.opentelemetry.api.common.AttributeKey;
5+
import io.opentelemetry.api.common.AttributesBuilder;
6+
import io.opentelemetry.api.incubator.ExtendedOpenTelemetry;
7+
import io.opentelemetry.api.incubator.config.DeclarativeConfigProperties;
8+
import io.opentelemetry.context.Context;
9+
import io.opentelemetry.instrumentation.api.instrumenter.AttributesExtractor;
10+
import javax.annotation.Nullable;
11+
12+
import static io.opentelemetry.api.common.AttributeKey.longKey;
13+
import static io.opentelemetry.api.common.AttributeKey.stringKey;
14+
import static io.opentelemetry.api.incubator.config.DeclarativeConfigProperties.empty;
15+
16+
public class ThreadDetailsInstrumenterCustomizerProvider implements InstrumenterCustomizerProvider {
17+
@Override
18+
public void customize(InstrumenterCustomizer customizer) {
19+
OpenTelemetry openTelemetry = customizer.getOpenTelemetry();
20+
if (openTelemetry instanceof ExtendedOpenTelemetry) {
21+
// Declarative config is used.
22+
// Otherwise, thread details are configured in
23+
// io.opentelemetry.javaagent.tooling.AgentTracerProviderConfigurer.
24+
25+
DeclarativeConfigProperties instrumentationConfig =
26+
((ExtendedOpenTelemetry) openTelemetry).getConfigProvider().getInstrumentationConfig();
27+
28+
if (instrumentationConfig != null
29+
&& instrumentationConfig
30+
.getStructured("java", empty())
31+
.getStructured("common", empty())
32+
.getStructured("thread_details", empty())
33+
.getBoolean("enabled", false)) {
34+
customizer.addAttributesExtractor(new ThreadDetailsAttributesExtractor<>());
35+
}
36+
}
37+
}
38+
39+
private static class ThreadDetailsAttributesExtractor<RESPONSE, REQUEST>
40+
implements AttributesExtractor<REQUEST, RESPONSE> {
41+
// attributes are not stable yet
42+
private static final AttributeKey<Long> THREAD_ID = longKey("thread.id");
43+
private static final AttributeKey<String> THREAD_NAME = stringKey("thread.name");
44+
45+
@Override
46+
public void onStart(AttributesBuilder attributes, Context parentContext, REQUEST request) {
47+
Thread currentThread = Thread.currentThread();
48+
attributes.put(THREAD_ID, currentThread.getId());
49+
attributes.put(THREAD_NAME, currentThread.getName());
50+
}
51+
52+
@Override
53+
public void onEnd(
54+
AttributesBuilder attributes,
55+
Context context,
56+
REQUEST request,
57+
@Nullable RESPONSE response,
58+
@Nullable Throwable error) {}
59+
}
60+
}

instrumentation-api-incubator/src/main/java/io/opentelemetry/instrumentation/api/incubator/instrumenter/internal/InstrumenterCustomizerImpl.java

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

66
package io.opentelemetry.instrumentation.api.incubator.instrumenter.internal;
77

8+
import io.opentelemetry.api.OpenTelemetry;
89
import io.opentelemetry.instrumentation.api.incubator.instrumenter.InstrumenterCustomizer;
910
import io.opentelemetry.instrumentation.api.instrumenter.AttributesExtractor;
1011
import io.opentelemetry.instrumentation.api.instrumenter.ContextCustomizer;
@@ -47,6 +48,11 @@ public String getInstrumentationName() {
4748
return customizer.getInstrumentationName();
4849
}
4950

51+
@Override
52+
public OpenTelemetry getOpenTelemetry() {
53+
return customizer.getOpenTelemetry();
54+
}
55+
5056
@Override
5157
public boolean hasType(InstrumentationType type) {
5258
SpanKey spanKey = typeToSpanKey.get(type);

instrumentation-api/src/test/java/io/opentelemetry/instrumentation/api/instrumenter/AddThreadDetailsTest.java renamed to instrumentation-api-incubator/src/test/java/io/opentelemetry/instrumentation/api/incubator/instrumenter/ThreadDetailsInstrumenterCustomizerProviderTest.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,15 @@
33
* SPDX-License-Identifier: Apache-2.0
44
*/
55

6-
package io.opentelemetry.instrumentation.api.instrumenter;
6+
package io.opentelemetry.instrumentation.api.incubator.instrumenter;
77

88
import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.satisfies;
99
import static java.util.Collections.emptyMap;
1010
import static java.util.Collections.singletonMap;
1111

1212
import io.opentelemetry.api.OpenTelemetry;
1313
import io.opentelemetry.context.Context;
14+
import io.opentelemetry.instrumentation.api.instrumenter.Instrumenter;
1415
import io.opentelemetry.sdk.extension.incubator.fileconfig.DeclarativeConfiguration;
1516
import io.opentelemetry.sdk.extension.incubator.fileconfig.DeclarativeConfigurationBuilder;
1617
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.ExperimentalLanguageSpecificInstrumentationModel;
@@ -28,7 +29,7 @@
2829
import org.junit.jupiter.params.provider.Arguments;
2930
import org.junit.jupiter.params.provider.MethodSource;
3031

31-
class AddThreadDetailsTest {
32+
class ThreadDetailsInstrumenterCustomizerProviderTest {
3233

3334
@RegisterExtension
3435
static final OpenTelemetryExtension otelTesting = OpenTelemetryExtension.create();
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
# added in test resources for testing purposes
2+
# the real implementation is in sdk-autoconfigure-support module
3+
io.opentelemetry.instrumentation.api.incubator.instrumenter.ThreadDetailsInstrumenterCustomizerProvider

instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/instrumenter/InstrumenterBuilder.java

Lines changed: 6 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -5,18 +5,11 @@
55

66
package io.opentelemetry.instrumentation.api.instrumenter;
77

8-
import static io.opentelemetry.api.common.AttributeKey.longKey;
9-
import static io.opentelemetry.api.common.AttributeKey.stringKey;
10-
import static io.opentelemetry.api.incubator.config.DeclarativeConfigProperties.empty;
118
import static java.util.Objects.requireNonNull;
129
import static java.util.logging.Level.WARNING;
1310

1411
import com.google.errorprone.annotations.CanIgnoreReturnValue;
1512
import io.opentelemetry.api.OpenTelemetry;
16-
import io.opentelemetry.api.common.AttributeKey;
17-
import io.opentelemetry.api.common.AttributesBuilder;
18-
import io.opentelemetry.api.incubator.ExtendedOpenTelemetry;
19-
import io.opentelemetry.api.incubator.config.DeclarativeConfigProperties;
2013
import io.opentelemetry.api.metrics.Meter;
2114
import io.opentelemetry.api.metrics.MeterBuilder;
2215
import io.opentelemetry.api.trace.SpanKind;
@@ -61,8 +54,6 @@ public final class InstrumenterBuilder<REQUEST, RESPONSE> {
6154
ConfigPropertiesUtil.getString(
6255
"otel.instrumentation.experimental.span-suppression-strategy"));
6356

64-
static boolean isIncubator = isIncubator();
65-
6657
final OpenTelemetry openTelemetry;
6758
final String instrumentationName;
6859
SpanNameExtractor<? super REQUEST> spanNameExtractor;
@@ -93,20 +84,6 @@ public final class InstrumenterBuilder<REQUEST, RESPONSE> {
9384
operationListenerAttributesExtractor, "operationListenerAttributesExtractor")));
9485
}
9586

96-
private static boolean isIncubator() {
97-
try {
98-
Class.forName("io.opentelemetry.api.incubator.ExtendedOpenTelemetry");
99-
return true;
100-
} catch (ClassNotFoundException e) {
101-
// The incubator module is not available.
102-
// This only happens in OpenTelemetry API instrumentation tests, where an older version of
103-
// OpenTelemetry API is used that does not have ExtendedOpenTelemetry.
104-
// Having the incubator module without ExtendedOpenTelemetry class should still return false
105-
// for those tests to avoid a ClassNotFoundException.
106-
return false;
107-
}
108-
}
109-
11087
InstrumenterBuilder(
11188
OpenTelemetry openTelemetry,
11289
String instrumentationName,
@@ -320,7 +297,6 @@ private Instrumenter<REQUEST, RESPONSE> buildInstrumenter(
320297
InstrumenterConstructor<REQUEST, RESPONSE> constructor,
321298
SpanKindExtractor<? super REQUEST> spanKindExtractor) {
322299

323-
addThreadDetailsAttributeExtractor(this);
324300
applyCustomizers(this);
325301

326302
this.spanKindExtractor = spanKindExtractor;
@@ -434,6 +410,11 @@ public String getInstrumentationName() {
434410
return builder.instrumentationName;
435411
}
436412

413+
@Override
414+
public OpenTelemetry getOpenTelemetry() {
415+
return builder.openTelemetry;
416+
}
417+
437418
@Override
438419
public boolean hasType(SpanKey type) {
439420
return spanKeys.contains(type);
@@ -478,28 +459,7 @@ public void setSpanStatusExtractorCustomizer(
478459
}
479460
}
480461

481-
private static <RESPONSE, REQUEST> void addThreadDetailsAttributeExtractor(
482-
InstrumenterBuilder<REQUEST, RESPONSE> builder) {
483-
if (isIncubator && builder.openTelemetry instanceof ExtendedOpenTelemetry) {
484-
// Declarative config is used.
485-
// Otherwise, thread details are configured in
486-
// io.opentelemetry.javaagent.tooling.AgentTracerProviderConfigurer.
487-
488-
DeclarativeConfigProperties instrumentationConfig =
489-
((ExtendedOpenTelemetry) builder.openTelemetry)
490-
.getConfigProvider()
491-
.getInstrumentationConfig();
492-
493-
if (instrumentationConfig != null
494-
&& instrumentationConfig
495-
.getStructured("java", empty())
496-
.getStructured("common", empty())
497-
.getStructured("thread_details", empty())
498-
.getBoolean("enabled", false)) {
499-
builder.addAttributesExtractor(new ThreadDetailsAttributesExtractor<>());
500-
}
501-
}
502-
}
462+
503463

504464
private interface InstrumenterConstructor<RQ, RS> {
505465
Instrumenter<RQ, RS> create(InstrumenterBuilder<RQ, RS> builder);
@@ -545,26 +505,4 @@ public <RQ, RS> void propagateOperationListenersToOnEnd(
545505
}
546506
});
547507
}
548-
549-
private static class ThreadDetailsAttributesExtractor<RESPONSE, REQUEST>
550-
implements AttributesExtractor<REQUEST, RESPONSE> {
551-
// attributes are not stable yet
552-
private static final AttributeKey<Long> THREAD_ID = longKey("thread.id");
553-
private static final AttributeKey<String> THREAD_NAME = stringKey("thread.name");
554-
555-
@Override
556-
public void onStart(AttributesBuilder attributes, Context parentContext, REQUEST request) {
557-
Thread currentThread = Thread.currentThread();
558-
attributes.put(THREAD_ID, currentThread.getId());
559-
attributes.put(THREAD_NAME, currentThread.getName());
560-
}
561-
562-
@Override
563-
public void onEnd(
564-
AttributesBuilder attributes,
565-
Context context,
566-
REQUEST request,
567-
@Nullable RESPONSE response,
568-
@Nullable Throwable error) {}
569-
}
570508
}

instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/internal/InternalInstrumenterCustomizer.java

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

66
package io.opentelemetry.instrumentation.api.internal;
77

8+
import io.opentelemetry.api.OpenTelemetry;
89
import io.opentelemetry.instrumentation.api.instrumenter.AttributesExtractor;
910
import io.opentelemetry.instrumentation.api.instrumenter.ContextCustomizer;
1011
import io.opentelemetry.instrumentation.api.instrumenter.OperationMetrics;
@@ -20,6 +21,8 @@ public interface InternalInstrumenterCustomizer<REQUEST, RESPONSE> {
2021

2122
String getInstrumentationName();
2223

24+
OpenTelemetry getOpenTelemetry();
25+
2326
boolean hasType(SpanKey type);
2427

2528
void addAttributesExtractor(AttributesExtractor<REQUEST, RESPONSE> extractor);

sdk-autoconfigure-support/build.gradle.kts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ group = "io.opentelemetry.instrumentation"
88
dependencies {
99
api("io.opentelemetry:opentelemetry-sdk-extension-autoconfigure")
1010
api("io.opentelemetry:opentelemetry-sdk-extension-incubator")
11+
implementation(project(":instrumentation-api-incubator"))
1112

1213
compileOnly("com.google.code.findbugs:annotations")
1314
testCompileOnly("com.google.code.findbugs:annotations")
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
io.opentelemetry.instrumentation.api.incubator.instrumenter.ThreadDetailsInstrumenterCustomizerProvider

0 commit comments

Comments
 (0)