Skip to content
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,2 +1,18 @@
Comparing source compatibility of opentelemetry-instrumentation-api-2.17.0-SNAPSHOT.jar against opentelemetry-instrumentation-api-2.16.0.jar
No changes.
+++ NEW INTERFACE: PUBLIC(+) ABSTRACT(+) io.opentelemetry.instrumentation.api.instrumenter.AttributesExtractorCustomizer (not serializable)
+++ CLASS FILE FORMAT VERSION: 52.0 <- n.a.
+++ NEW SUPERCLASS: java.lang.Object
+++ NEW METHOD: PUBLIC(+) ABSTRACT(+) io.opentelemetry.instrumentation.api.instrumenter.AttributesExtractor<REQUEST,RESPONSE> get()
GENERIC TEMPLATES: +++ REQUEST:java.lang.Object, +++ RESPONSE:java.lang.Object
+++ NEW METHOD: PUBLIC(+) ABSTRACT(+) java.util.List<java.lang.String> instrumentationNames()
+++ NEW INTERFACE: PUBLIC(+) ABSTRACT(+) io.opentelemetry.instrumentation.api.instrumenter.ContextCustomizerCustomizer (not serializable)
+++ CLASS FILE FORMAT VERSION: 52.0 <- n.a.
+++ NEW SUPERCLASS: java.lang.Object
+++ NEW METHOD: PUBLIC(+) ABSTRACT(+) io.opentelemetry.instrumentation.api.instrumenter.ContextCustomizer<REQUEST> get()
GENERIC TEMPLATES: +++ REQUEST:java.lang.Object
+++ NEW METHOD: PUBLIC(+) ABSTRACT(+) java.util.List<java.lang.String> instrumentationNames()
+++ NEW INTERFACE: PUBLIC(+) ABSTRACT(+) io.opentelemetry.instrumentation.api.instrumenter.OperationMetricsCustomizer (not serializable)
+++ CLASS FILE FORMAT VERSION: 52.0 <- n.a.
+++ NEW SUPERCLASS: java.lang.Object
+++ NEW METHOD: PUBLIC(+) ABSTRACT(+) io.opentelemetry.instrumentation.api.instrumenter.OperationMetrics get()
+++ NEW METHOD: PUBLIC(+) ABSTRACT(+) java.util.List<java.lang.String> instrumentationNames()
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/

package io.opentelemetry.instrumentation.api.instrumenter;

import java.util.List;

/**
* A service provider interface (SPI) for providing {@link AttributesExtractorCustomizer} instances
* that are conditionally applied based on the instrumentation name.
*
* <p>This allows external modules or plugins to contribute custom attribute extraction logic for
* specific instrumented libraries, without modifying core instrumentation code.
*/
public interface AttributesExtractorCustomizer {
/**
* Returns a list of instrumentation names that this customizer supports.
*
* <p>The customizer will only be applied if the current instrumentation matches one of the
* returned names. For example: ["io.opentelemetry.netty-3.8",
* "io.opentelemetry.apache-httpclient-4.3"].
*
* @return a list of supported instrumentation names
*/
List<String> instrumentationNames();

/**
* Returns a new instance of an {@link AttributesExtractor} that will extract attributes from
* requests and responses during the instrumentation process.
*
* @param <REQUEST> the type of request object used by the instrumented library
* @param <RESPONSE> the type of response object used by the instrumented library
* @return an attributes extractor instance
*/
<REQUEST, RESPONSE> AttributesExtractor<REQUEST, RESPONSE> get();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/

package io.opentelemetry.instrumentation.api.instrumenter;

import java.util.List;

/**
* A service provider interface (SPI) for providing custom {@link ContextCustomizer} implementations
* that are conditionally applied based on the instrumentation name.
*
* <p>This allows external modules or plugins to customize context propagation and initialization
* logic for specific instrumented libraries, without modifying core instrumentation code.
*/
public interface ContextCustomizerCustomizer {

/**
* Returns a list of instrumentation names that this customizer supports.
*
* <p>The customizer will only be applied if the current instrumentation matches one of the
* returned names. For example: ["io.opentelemetry.netty-3.8",
* "io.opentelemetry.apache-httpclient-4.3"].
*
* @return a list of supported instrumentation names
*/
List<String> instrumentationNames();

/**
* Returns a new instance of a {@link ContextCustomizer} that will customize the tracing context
* during request processing.
*
* @param <REQUEST> the type of request object used by the instrumented library
* @return a context customizer instance
*/
<REQUEST> ContextCustomizer<REQUEST> get();
}
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,10 @@
import io.opentelemetry.instrumentation.api.internal.SpanKey;
import io.opentelemetry.instrumentation.api.internal.SpanKeyProvider;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.ServiceLoader;
import java.util.Set;
import java.util.logging.Logger;
import java.util.stream.Collectors;
Expand Down Expand Up @@ -69,6 +72,45 @@ public final class InstrumenterBuilder<REQUEST, RESPONSE> {
boolean propagateOperationListenersToOnEnd = false;
boolean enabled = true;

private static final Map<String, List<ContextCustomizerCustomizer>> CONTEXT_CUSTOMIZER_MAP =
new HashMap<>();
private static final Map<String, List<AttributesExtractorCustomizer>> ATTRIBUTES_EXTRACTOR_MAP =
new HashMap<>();
private static final Map<String, List<OperationMetricsCustomizer>> OPERATION_METRICS_MAP =
new HashMap<>();

static {
ServiceLoader.load(ContextCustomizerCustomizer.class)
.forEach(
customizers -> {
for (String name : customizers.instrumentationNames()) {
CONTEXT_CUSTOMIZER_MAP
.computeIfAbsent(name, k -> new ArrayList<>())
.add(customizers);
}
});

ServiceLoader.load(AttributesExtractorCustomizer.class)
.forEach(
customizers -> {
for (String name : customizers.instrumentationNames()) {
ATTRIBUTES_EXTRACTOR_MAP
.computeIfAbsent(name, k -> new ArrayList<>())
.add(customizers);
}
});

ServiceLoader.load(OperationMetricsCustomizer.class)
.forEach(
customizers -> {
for (String name : customizers.instrumentationNames()) {
OPERATION_METRICS_MAP
.computeIfAbsent(name, k -> new ArrayList<>())
.add(customizers);
}
});
}

InstrumenterBuilder(
OpenTelemetry openTelemetry,
String instrumentationName,
Expand All @@ -78,6 +120,30 @@ public final class InstrumenterBuilder<REQUEST, RESPONSE> {
this.spanNameExtractor = spanNameExtractor;
this.instrumentationVersion =
EmbeddedInstrumentationProperties.findVersion(instrumentationName);

List<ContextCustomizerCustomizer> contextProviders =
CONTEXT_CUSTOMIZER_MAP.get(instrumentationName);
if (contextProviders != null) {
for (ContextCustomizerCustomizer provider : contextProviders) {
addContextCustomizer(provider.get());
}
}

List<AttributesExtractorCustomizer> attributeProviders =
ATTRIBUTES_EXTRACTOR_MAP.get(instrumentationName);
if (attributeProviders != null) {
for (AttributesExtractorCustomizer provider : attributeProviders) {
addAttributesExtractor(provider.get());
}
}

List<OperationMetricsCustomizer> metricsProviders =
OPERATION_METRICS_MAP.get(instrumentationName);
if (metricsProviders != null) {
for (OperationMetricsCustomizer provider : metricsProviders) {
addOperationMetrics(provider.get());
}
}
}

/**
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/

package io.opentelemetry.instrumentation.api.instrumenter;

import java.util.List;

/**
* A service provider interface (SPI) for providing custom {@link OperationMetrics} instances that
* are conditionally applied based on the instrumentation name.
*
* <p>This allows external modules or plugins to contribute custom metrics collection logic for
* specific instrumented operations, without modifying core instrumentation code.
*/
public interface OperationMetricsCustomizer {

/**
* Returns a list of instrumentation names that this metrics customizer supports.
*
* <p>The customizer will only be applied if the current instrumentation matches one of the
* returned names. For example: ["io.opentelemetry.spring-webmvc-5.0",
* "io.opentelemetry.netty-3.8"].
*
* @return a list of supported instrumentation names
*/
List<String> instrumentationNames();

/**
* Returns a new instance of an {@link OperationMetrics} that will record metrics for the
* instrumented operation.
*
* @return an operation metrics instance
*/
OperationMetrics get();
}
Loading