Skip to content

Commit 6972f96

Browse files
committed
Address review comments
1 parent 30182a3 commit 6972f96

File tree

4 files changed

+130
-5
lines changed

4 files changed

+130
-5
lines changed

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

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -24,13 +24,13 @@
2424
import io.opentelemetry.instrumentation.api.internal.InstrumenterBuilderAccess;
2525
import io.opentelemetry.instrumentation.api.internal.InstrumenterUtil;
2626
import io.opentelemetry.instrumentation.api.internal.SchemaUrlProvider;
27+
import io.opentelemetry.instrumentation.api.internal.ServiceLoaderUtil;
2728
import io.opentelemetry.instrumentation.api.internal.SpanKey;
2829
import io.opentelemetry.instrumentation.api.internal.SpanKeyProvider;
2930
import java.util.ArrayList;
3031
import java.util.HashMap;
3132
import java.util.List;
3233
import java.util.Map;
33-
import java.util.ServiceLoader;
3434
import java.util.Set;
3535
import java.util.function.Predicate;
3636
import java.util.logging.Logger;
@@ -77,10 +77,9 @@ public final class InstrumenterBuilder<REQUEST, RESPONSE> {
7777
INSTRUMENTATION_CUSTOMIZER_MAP = new HashMap<>();
7878

7979
static {
80-
ServiceLoader<InstrumentationCustomizer> serviceLoader =
81-
ServiceLoader.load(InstrumentationCustomizer.class);
82-
83-
for (InstrumentationCustomizer customizer : serviceLoader) {
80+
List<InstrumentationCustomizer> customizers =
81+
ServiceLoaderUtil.load(InstrumentationCustomizer.class);
82+
for (InstrumentationCustomizer customizer : customizers) {
8483
INSTRUMENTATION_CUSTOMIZER_MAP
8584
.computeIfAbsent(customizer.instrumentationNamePredicate(), k -> new ArrayList<>())
8685
.add(customizer);
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
/*
2+
* Copyright The OpenTelemetry Authors
3+
* SPDX-License-Identifier: Apache-2.0
4+
*/
5+
6+
package io.opentelemetry.instrumentation.api.internal;
7+
8+
import java.util.ArrayList;
9+
import java.util.List;
10+
import java.util.ServiceLoader;
11+
import java.util.function.Function;
12+
13+
/**
14+
* This class is internal and is hence not for public use. Its APIs are unstable and can change at
15+
* any time.
16+
*/
17+
public final class ServiceLoaderUtil {
18+
19+
private static Function<Class<?>, List<?>> loaderFunction =
20+
clazz -> {
21+
List<Object> instances = new ArrayList<>();
22+
ServiceLoader<?> serviceLoader = ServiceLoader.load(clazz);
23+
for (Object instance : serviceLoader) {
24+
instances.add(instance);
25+
}
26+
return instances;
27+
};
28+
29+
private ServiceLoaderUtil() {
30+
// Utility class, no instantiation
31+
}
32+
33+
@SuppressWarnings("unchecked")
34+
public static <T> List<T> load(Class<T> clazz) {
35+
return (List<T>) loaderFunction.apply(clazz);
36+
}
37+
38+
public static void setLoaderFunction(Function<Class<?>, List<?>> customLoaderFunction) {
39+
loaderFunction = customLoaderFunction;
40+
}
41+
}
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
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 static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.assertThat;
9+
10+
import java.util.function.Predicate;
11+
import org.junit.jupiter.api.BeforeEach;
12+
import org.junit.jupiter.api.Test;
13+
import org.junit.jupiter.api.extension.ExtendWith;
14+
import org.mockito.Mock;
15+
import org.mockito.junit.jupiter.MockitoExtension;
16+
17+
@ExtendWith(MockitoExtension.class)
18+
class InstrumentationCustomizerTest {
19+
20+
@Mock private AttributesExtractor<Object, Object> attributesExtractor;
21+
@Mock private OperationMetrics operationMetrics;
22+
23+
private InstrumentationCustomizer customizer;
24+
25+
@BeforeEach
26+
@SuppressWarnings("unchecked")
27+
void setUp() {
28+
customizer =
29+
new InstrumentationCustomizer() {
30+
@Override
31+
public Predicate<String> instrumentationNamePredicate() {
32+
return name -> name.startsWith("test.instrumentation");
33+
}
34+
35+
@Override
36+
public <REQUEST, RESPONSE>
37+
AttributesExtractor<REQUEST, RESPONSE> getAttributesExtractor() {
38+
return (AttributesExtractor<REQUEST, RESPONSE>) attributesExtractor;
39+
}
40+
41+
@Override
42+
public OperationMetrics getOperationMetrics() {
43+
return operationMetrics;
44+
}
45+
};
46+
}
47+
48+
@Test
49+
void testInstrumentationNamePredicate() {
50+
assertThat(customizer.instrumentationNamePredicate().test("test.instrumentation.example"))
51+
.isTrue();
52+
assertThat(customizer.instrumentationNamePredicate().test("other.instrumentation.example"))
53+
.isFalse();
54+
}
55+
56+
@Test
57+
void testGetAttributesExtractor() {
58+
AttributesExtractor<Object, Object> extractor = customizer.getAttributesExtractor();
59+
assertThat(extractor).isSameAs(attributesExtractor);
60+
}
61+
62+
@Test
63+
void testGetOperationMetrics() {
64+
OperationMetrics metrics = customizer.getOperationMetrics();
65+
assertThat(metrics).isSameAs(operationMetrics);
66+
}
67+
}

javaagent-bootstrap/src/main/java/io/opentelemetry/javaagent/bootstrap/AgentInitializer.java

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,15 @@
66
package io.opentelemetry.javaagent.bootstrap;
77

88
import io.opentelemetry.instrumentation.api.internal.ConfigPropertiesUtil;
9+
import io.opentelemetry.instrumentation.api.internal.ServiceLoaderUtil;
910
import java.io.File;
1011
import java.lang.instrument.Instrumentation;
1112
import java.lang.reflect.Constructor;
1213
import java.security.PrivilegedAction;
1314
import java.security.PrivilegedExceptionAction;
15+
import java.util.ArrayList;
16+
import java.util.List;
17+
import java.util.ServiceLoader;
1418
import javax.annotation.Nullable;
1519

1620
/**
@@ -62,6 +66,7 @@ public Void run() {
6266
public Void run() throws Exception {
6367
agentClassLoader = createAgentClassLoader("inst", javaagentFile);
6468
agentStarter = createAgentStarter(agentClassLoader, inst, javaagentFile);
69+
setLoaderFunction();
6570
if (!fromPremain || !delayAgentStart()) {
6671
agentStarter.start();
6772
agentStarted = true;
@@ -212,6 +217,19 @@ private static AgentStarter createAgentStarter(
212217
constructor.newInstance(instrumentation, javaagentFile, isSecurityManagerSupportEnabled);
213218
}
214219

220+
/** Sets a custom loader function for the ServiceLoaderUtil to use the agentClassLoader. */
221+
private static void setLoaderFunction() {
222+
ServiceLoaderUtil.setLoaderFunction(
223+
clazz -> {
224+
List<Object> instances = new ArrayList<>();
225+
ServiceLoader<?> serviceLoader = ServiceLoader.load(clazz, agentClassLoader);
226+
for (Object instance : serviceLoader) {
227+
instances.add(instance);
228+
}
229+
return instances;
230+
});
231+
}
232+
215233
private AgentInitializer() {}
216234

217235
@SuppressWarnings("SystemOut")

0 commit comments

Comments
 (0)