-
Notifications
You must be signed in to change notification settings - Fork 886
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Adds binding of attributes in methods annotated with @WithSpan (#3188)
* Add binding of span attributes for traced methods * Spring Aspect support, memoization * Test with attribute name from ParameterNameDiscoverer * Refactorings, javadocs and tests * Refactor out creating AttributeBinding to separate class * Wrapped attribute bindings for array parameters * Attribute binding for List and EnumSet * Attribute binding for subclass of List with reflection helper class * Fix test failures in JDK 8 * Attribute binding to Set<? extends Enum> * Move attribute binding to instrumentation-annotation-support project * Fix copypastaed missing imports in tests * Simplify ParameterizedClass based on PR feedback and add javadocs * Remove blank javadoc * Switch to cache with weak keys for memoizing attribute bindings by method * Remove binding support for EnumSet<?> * Clean up javadoc * Use SpanAttribute annotation from opentelemetry 1.4.0-SNAPSHOT * Address some PR concerns * Clean up * Fix instrumentation dependency in Springboot * Update documentation * Switch javaagent dep to compileOnly per PR comment * spotless * Kick CI * Rename annotation support module and packages * Resolve SpanAttribute annotation at runtime with fallback for older OTel versions * Remove unnecessary dependency * Move reflection helper to annotation support module * Remove unnecessary enum and fields from unit test
- Loading branch information
Showing
28 changed files
with
1,832 additions
and
22 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
plugins { | ||
id("otel.java-conventions") | ||
id("otel.jacoco-conventions") | ||
id("otel.publish-conventions") | ||
} | ||
|
||
group = "io.opentelemetry.instrumentation" | ||
|
||
dependencies { | ||
implementation(project(":instrumentation-api")) | ||
|
||
api("io.opentelemetry:opentelemetry-api") | ||
api("io.opentelemetry:opentelemetry-semconv") | ||
|
||
implementation("io.opentelemetry:opentelemetry-api-metrics") | ||
implementation("org.slf4j:slf4j-api") | ||
|
||
compileOnly("com.google.auto.value:auto-value-annotations") | ||
annotationProcessor("com.google.auto.value:auto-value") | ||
|
||
testImplementation(project(":testing-common")) | ||
testImplementation("org.mockito:mockito-core") | ||
testImplementation("org.mockito:mockito-junit-jupiter") | ||
testImplementation("org.assertj:assertj-core") | ||
testImplementation("org.awaitility:awaitility") | ||
testImplementation("io.opentelemetry:opentelemetry-sdk-metrics") | ||
testImplementation("io.opentelemetry:opentelemetry-sdk-testing") | ||
} |
93 changes: 93 additions & 0 deletions
93
...a/io/opentelemetry/instrumentation/api/annotation/support/AnnotationReflectionHelper.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,93 @@ | ||
/* | ||
* Copyright The OpenTelemetry Authors | ||
* SPDX-License-Identifier: Apache-2.0 | ||
*/ | ||
|
||
package io.opentelemetry.instrumentation.api.annotation.support; | ||
|
||
import java.lang.annotation.Annotation; | ||
import java.lang.invoke.CallSite; | ||
import java.lang.invoke.LambdaMetafactory; | ||
import java.lang.invoke.MethodHandle; | ||
import java.lang.invoke.MethodHandles; | ||
import java.lang.invoke.MethodType; | ||
import java.util.function.Function; | ||
import org.checkerframework.checker.nullness.qual.Nullable; | ||
|
||
/** Helper class for reflecting over annotations at runtime.. */ | ||
public class AnnotationReflectionHelper { | ||
private AnnotationReflectionHelper() {} | ||
|
||
/** | ||
* Returns the {@link Class Class<? extends Annotation>} for the name of the {@link | ||
* Annotation} at runtime, otherwise returns {@code null}. | ||
*/ | ||
@Nullable | ||
public static Class<? extends Annotation> forNameOrNull( | ||
ClassLoader classLoader, String className) { | ||
try { | ||
return Class.forName(className, true, classLoader).asSubclass(Annotation.class); | ||
} catch (ClassNotFoundException | ClassCastException exception) { | ||
return null; | ||
} | ||
} | ||
|
||
/** | ||
* Binds a lambda of the functional interface {@link Function Function<A extends Annotation, | ||
* T>} to the element of an {@link Annotation} class by name which, when invoked with an | ||
* instance of that annotation, will return the value of that element. | ||
* | ||
* <p>For example, calling this method as follows: | ||
* | ||
* <pre>{@code | ||
* Function<WithSpan, String> function = AnnotationReflectionHelper.bindAnnotationElementMethod( | ||
* MethodHandles.lookup(), | ||
* WithSpan.class, | ||
* "value", | ||
* String.class); | ||
* }</pre> | ||
* | ||
* <p>is equivalent to the following Java code: | ||
* | ||
* <pre>{@code | ||
* Function<WithSpan, String> function = WithSpan::value; | ||
* }</pre> | ||
* | ||
* @param lookup the {@link MethodHandles.Lookup} of the calling method, e.g. {@link | ||
* MethodHandles#lookup()} | ||
* @param annotationClass the {@link Class} of the {@link Annotation} | ||
* @param methodName name of the annotation element method | ||
* @param returnClass type of the annotation element | ||
* @param <A> the type of the annotation | ||
* @param <T> the type of the annotation element | ||
* @return Instance of {@link Function Function<Annotation, T>} that is bound to the | ||
* annotation element method | ||
* @throws NoSuchMethodException the annotation element method was not found | ||
* @throws Throwable on failing to bind to the | ||
*/ | ||
public static <A extends Annotation, T> Function<A, T> bindAnnotationElementMethod( | ||
MethodHandles.Lookup lookup, | ||
Class<? extends Annotation> annotationClass, | ||
String methodName, | ||
Class<T> returnClass) | ||
throws Throwable { | ||
|
||
MethodHandle valueHandle = | ||
lookup.findVirtual(annotationClass, methodName, MethodType.methodType(returnClass)); | ||
|
||
CallSite callSite = | ||
LambdaMetafactory.metafactory( | ||
lookup, | ||
"apply", | ||
MethodType.methodType(Function.class), | ||
MethodType.methodType(Object.class, Object.class), | ||
valueHandle, | ||
MethodType.methodType(returnClass, annotationClass)); | ||
|
||
MethodHandle factory = callSite.getTarget(); | ||
|
||
@SuppressWarnings("unchecked") | ||
Function<A, T> function = (Function<A, T>) factory.invoke(); | ||
return function; | ||
} | ||
} |
21 changes: 21 additions & 0 deletions
21
...c/main/java/io/opentelemetry/instrumentation/api/annotation/support/AttributeBinding.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
/* | ||
* Copyright The OpenTelemetry Authors | ||
* SPDX-License-Identifier: Apache-2.0 | ||
*/ | ||
|
||
package io.opentelemetry.instrumentation.api.annotation.support; | ||
|
||
import io.opentelemetry.instrumentation.api.tracer.AttributeSetter; | ||
|
||
/** Represents the binding of a method parameter to an attribute of a traced method. */ | ||
@FunctionalInterface | ||
public interface AttributeBinding { | ||
|
||
/** | ||
* Applies the value of the method argument as an attribute on the span for the traced method. | ||
* | ||
* @param setter the {@link AttributeSetter} onto which to add the attribute | ||
* @param arg the value of the method argument | ||
*/ | ||
void apply(AttributeSetter setter, Object arg); | ||
} |
Oops, something went wrong.