Skip to content

Commit 30182a3

Browse files
committed
Address review comments
1 parent 35da705 commit 30182a3

File tree

6 files changed

+98
-185
lines changed

6 files changed

+98
-185
lines changed
Lines changed: 5 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,10 @@
11
Comparing source compatibility of opentelemetry-instrumentation-api-2.17.0-SNAPSHOT.jar against opentelemetry-instrumentation-api-2.16.0.jar
2-
+++ NEW INTERFACE: PUBLIC(+) ABSTRACT(+) io.opentelemetry.instrumentation.api.instrumenter.AttributesExtractorCustomizer (not serializable)
2+
+++ NEW INTERFACE: PUBLIC(+) ABSTRACT(+) io.opentelemetry.instrumentation.api.instrumenter.InstrumentationCustomizer (not serializable)
33
+++ CLASS FILE FORMAT VERSION: 52.0 <- n.a.
44
+++ NEW SUPERCLASS: java.lang.Object
5-
+++ NEW METHOD: PUBLIC(+) ABSTRACT(+) io.opentelemetry.instrumentation.api.instrumenter.AttributesExtractor<REQUEST,RESPONSE> get()
5+
+++ NEW METHOD: PUBLIC(+) io.opentelemetry.instrumentation.api.instrumenter.AttributesExtractor<REQUEST,RESPONSE> getAttributesExtractor()
66
GENERIC TEMPLATES: +++ REQUEST:java.lang.Object, +++ RESPONSE:java.lang.Object
7-
+++ NEW METHOD: PUBLIC(+) ABSTRACT(+) java.util.List<java.lang.String> instrumentationNames()
8-
+++ NEW INTERFACE: PUBLIC(+) ABSTRACT(+) io.opentelemetry.instrumentation.api.instrumenter.ContextCustomizerCustomizer (not serializable)
9-
+++ CLASS FILE FORMAT VERSION: 52.0 <- n.a.
10-
+++ NEW SUPERCLASS: java.lang.Object
11-
+++ NEW METHOD: PUBLIC(+) ABSTRACT(+) io.opentelemetry.instrumentation.api.instrumenter.ContextCustomizer<REQUEST> get()
7+
+++ NEW METHOD: PUBLIC(+) io.opentelemetry.instrumentation.api.instrumenter.ContextCustomizer<REQUEST> getContextCustomizer()
128
GENERIC TEMPLATES: +++ REQUEST:java.lang.Object
13-
+++ NEW METHOD: PUBLIC(+) ABSTRACT(+) java.util.List<java.lang.String> instrumentationNames()
14-
+++ NEW INTERFACE: PUBLIC(+) ABSTRACT(+) io.opentelemetry.instrumentation.api.instrumenter.OperationMetricsCustomizer (not serializable)
15-
+++ CLASS FILE FORMAT VERSION: 52.0 <- n.a.
16-
+++ NEW SUPERCLASS: java.lang.Object
17-
+++ NEW METHOD: PUBLIC(+) ABSTRACT(+) io.opentelemetry.instrumentation.api.instrumenter.OperationMetrics get()
18-
+++ NEW METHOD: PUBLIC(+) ABSTRACT(+) java.util.List<java.lang.String> instrumentationNames()
9+
+++ NEW METHOD: PUBLIC(+) io.opentelemetry.instrumentation.api.instrumenter.OperationMetrics getOperationMetrics()
10+
+++ NEW METHOD: PUBLIC(+) ABSTRACT(+) java.util.function.Predicate<java.lang.String> instrumentationNamePredicate()

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

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

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

Lines changed: 0 additions & 38 deletions
This file was deleted.
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
/*
2+
* Copyright The OpenTelemetry Authors
3+
* SPDX-License-Identifier: Apache-2.0
4+
*/
5+
6+
package io.opentelemetry.instrumentation.api.instrumenter;
7+
8+
import java.util.function.Predicate;
9+
10+
/**
11+
* A service provider interface (SPI) for providing customizations for instrumentation, including
12+
* operation metrics, attributes extraction, and context customization.
13+
*
14+
* <p>This allows external modules or plugins to contribute custom logic for specific instrumented
15+
* libraries, without modifying core instrumentation code.
16+
*/
17+
public interface InstrumentationCustomizer {
18+
19+
/**
20+
* Returns a predicate that determines whether this customizer supports a given instrumentation
21+
* name.
22+
*
23+
* <p>The customizer will only be applied if the current instrumentation name matches the
24+
* predicate. For example, the predicate might match names like "io.opentelemetry.netty-3.8" or
25+
* "io.opentelemetry.apache-httpclient-4.3".
26+
*
27+
* @return a predicate for supported instrumentation names
28+
*/
29+
Predicate<String> instrumentationNamePredicate();
30+
31+
/**
32+
* Returns a new instance of an {@link OperationMetrics} that will record metrics for the
33+
* instrumented operation.
34+
*
35+
* @return an operation metrics instance, or null if not applicable
36+
*/
37+
default OperationMetrics getOperationMetrics() {
38+
return null;
39+
}
40+
41+
/**
42+
* Returns a new instance of an {@link AttributesExtractor} that will extract attributes from
43+
* requests and responses during the instrumentation process.
44+
*
45+
* @param <REQUEST> the type of request object used by the instrumented library
46+
* @param <RESPONSE> the type of response object used by the instrumented library
47+
* @return an attributes extractor instance, or null if not applicable
48+
*/
49+
default <REQUEST, RESPONSE> AttributesExtractor<REQUEST, RESPONSE> getAttributesExtractor() {
50+
return null;
51+
}
52+
53+
/**
54+
* Returns a new instance of a {@link ContextCustomizer} that will customize the tracing context
55+
* during request processing.
56+
*
57+
* @param <REQUEST> the type of request object used by the instrumented library
58+
* @return a context customizer instance, or null if not applicable
59+
*/
60+
default <REQUEST> ContextCustomizer<REQUEST> getContextCustomizer() {
61+
return null;
62+
}
63+
}

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

Lines changed: 30 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
import java.util.Map;
3333
import java.util.ServiceLoader;
3434
import java.util.Set;
35+
import java.util.function.Predicate;
3536
import java.util.logging.Logger;
3637
import java.util.stream.Collectors;
3738
import java.util.stream.Stream;
@@ -72,43 +73,18 @@ public final class InstrumenterBuilder<REQUEST, RESPONSE> {
7273
boolean propagateOperationListenersToOnEnd = false;
7374
boolean enabled = true;
7475

75-
private static final Map<String, List<ContextCustomizerCustomizer>> CONTEXT_CUSTOMIZER_MAP =
76-
new HashMap<>();
77-
private static final Map<String, List<AttributesExtractorCustomizer>> ATTRIBUTES_EXTRACTOR_MAP =
78-
new HashMap<>();
79-
private static final Map<String, List<OperationMetricsCustomizer>> OPERATION_METRICS_MAP =
80-
new HashMap<>();
76+
private static final Map<Predicate<String>, List<InstrumentationCustomizer>>
77+
INSTRUMENTATION_CUSTOMIZER_MAP = new HashMap<>();
8178

8279
static {
83-
ServiceLoader.load(ContextCustomizerCustomizer.class)
84-
.forEach(
85-
customizers -> {
86-
for (String name : customizers.instrumentationNames()) {
87-
CONTEXT_CUSTOMIZER_MAP
88-
.computeIfAbsent(name, k -> new ArrayList<>())
89-
.add(customizers);
90-
}
91-
});
92-
93-
ServiceLoader.load(AttributesExtractorCustomizer.class)
94-
.forEach(
95-
customizers -> {
96-
for (String name : customizers.instrumentationNames()) {
97-
ATTRIBUTES_EXTRACTOR_MAP
98-
.computeIfAbsent(name, k -> new ArrayList<>())
99-
.add(customizers);
100-
}
101-
});
102-
103-
ServiceLoader.load(OperationMetricsCustomizer.class)
104-
.forEach(
105-
customizers -> {
106-
for (String name : customizers.instrumentationNames()) {
107-
OPERATION_METRICS_MAP
108-
.computeIfAbsent(name, k -> new ArrayList<>())
109-
.add(customizers);
110-
}
111-
});
80+
ServiceLoader<InstrumentationCustomizer> serviceLoader =
81+
ServiceLoader.load(InstrumentationCustomizer.class);
82+
83+
for (InstrumentationCustomizer customizer : serviceLoader) {
84+
INSTRUMENTATION_CUSTOMIZER_MAP
85+
.computeIfAbsent(customizer.instrumentationNamePredicate(), k -> new ArrayList<>())
86+
.add(customizer);
87+
}
11288
}
11389

11490
InstrumenterBuilder(
@@ -120,30 +96,6 @@ public final class InstrumenterBuilder<REQUEST, RESPONSE> {
12096
this.spanNameExtractor = spanNameExtractor;
12197
this.instrumentationVersion =
12298
EmbeddedInstrumentationProperties.findVersion(instrumentationName);
123-
124-
List<ContextCustomizerCustomizer> contextProviders =
125-
CONTEXT_CUSTOMIZER_MAP.get(instrumentationName);
126-
if (contextProviders != null) {
127-
for (ContextCustomizerCustomizer provider : contextProviders) {
128-
addContextCustomizer(provider.get());
129-
}
130-
}
131-
132-
List<AttributesExtractorCustomizer> attributeProviders =
133-
ATTRIBUTES_EXTRACTOR_MAP.get(instrumentationName);
134-
if (attributeProviders != null) {
135-
for (AttributesExtractorCustomizer provider : attributeProviders) {
136-
addAttributesExtractor(provider.get());
137-
}
138-
}
139-
140-
List<OperationMetricsCustomizer> metricsProviders =
141-
OPERATION_METRICS_MAP.get(instrumentationName);
142-
if (metricsProviders != null) {
143-
for (OperationMetricsCustomizer provider : metricsProviders) {
144-
addOperationMetrics(provider.get());
145-
}
146-
}
14799
}
148100

149101
/**
@@ -347,6 +299,25 @@ public Instrumenter<REQUEST, RESPONSE> buildInstrumenter(
347299
private Instrumenter<REQUEST, RESPONSE> buildInstrumenter(
348300
InstrumenterConstructor<REQUEST, RESPONSE> constructor,
349301
SpanKindExtractor<? super REQUEST> spanKindExtractor) {
302+
List<InstrumentationCustomizer> customizers =
303+
INSTRUMENTATION_CUSTOMIZER_MAP.entrySet().stream()
304+
.filter(entry -> entry.getKey().test(instrumentationName))
305+
.map(Map.Entry::getValue)
306+
.findFirst()
307+
.orElse(null);
308+
if (customizers != null) {
309+
for (InstrumentationCustomizer customizer : customizers) {
310+
if (customizer.getContextCustomizer() != null) {
311+
addContextCustomizer(customizer.getContextCustomizer());
312+
}
313+
if (customizer.getAttributesExtractor() != null) {
314+
addAttributesExtractor(customizer.getAttributesExtractor());
315+
}
316+
if (customizer.getOperationMetrics() != null) {
317+
addOperationMetrics(customizer.getOperationMetrics());
318+
}
319+
}
320+
}
350321
this.spanKindExtractor = spanKindExtractor;
351322
return constructor.create(this);
352323
}

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

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

0 commit comments

Comments
 (0)