From 21cbf96b97d2253f95a1df4550ca80df5bf492d3 Mon Sep 17 00:00:00 2001 From: Duncan-tree-zhou Date: Tue, 14 May 2024 23:44:01 +0800 Subject: [PATCH 01/21] add metric annotation instrumentation --- ...ntelemetry-instrumentation-annotations.txt | 38 +++- .../instrumentation/annotations/Counted.java | 95 ++++++++++ .../annotations/MetricAttribute.java | 39 ++++ .../instrumentation/annotations/Timed.java | 91 +++++++++ .../annotations/CountedUsageExamples.java | 19 ++ .../annotations/TimedUsageExamples.java | 19 ++ .../README.md | 5 + .../javaagent/build.gradle.kts | 46 +++++ .../counted/AnnotationExcludedMethods.java | 53 ++++++ .../counted/CountedHelper.java | 123 ++++++++++++ .../counted/CountedInstrumentation.java | 117 ++++++++++++ .../counted/CountedInstrumentationModule.java | 44 +++++ .../counted/KotlinCoroutineUtil.java | 32 ++++ .../counted/MethodRequest.java | 26 +++ .../annotations/counted/CountedExample.java | 60 ++++++ .../counted/CountedInstrumentationTest.java | 171 +++++++++++++++++ .../README.md | 5 + .../javaagent/build.gradle.kts | 46 +++++ .../timed/AnnotationExcludedMethods.java | 53 ++++++ .../timed/KotlinCoroutineUtil.java | 32 ++++ .../instrumentation/timed/MethodRequest.java | 26 +++ .../instrumentation/timed/TimedHelper.java | 163 ++++++++++++++++ .../timed/TimedInstrumentation.java | 125 ++++++++++++ .../timed/TimedInstrumentationModule.java | 43 +++++ .../test/annotations/timed/TimedExample.java | 61 ++++++ .../timed/TimedInstrumentationTest.java | 179 ++++++++++++++++++ settings.gradle.kts | 2 + 27 files changed, 1711 insertions(+), 2 deletions(-) create mode 100644 instrumentation-annotations/src/main/java/io/opentelemetry/instrumentation/annotations/Counted.java create mode 100644 instrumentation-annotations/src/main/java/io/opentelemetry/instrumentation/annotations/MetricAttribute.java create mode 100644 instrumentation-annotations/src/main/java/io/opentelemetry/instrumentation/annotations/Timed.java create mode 100644 instrumentation-annotations/src/test/java/io/opentelemetry/instrumentation/annotations/CountedUsageExamples.java create mode 100644 instrumentation-annotations/src/test/java/io/opentelemetry/instrumentation/annotations/TimedUsageExamples.java create mode 100644 instrumentation/opentelemetry-instrumentation-annotation-counted/README.md create mode 100644 instrumentation/opentelemetry-instrumentation-annotation-counted/javaagent/build.gradle.kts create mode 100644 instrumentation/opentelemetry-instrumentation-annotation-counted/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/counted/AnnotationExcludedMethods.java create mode 100644 instrumentation/opentelemetry-instrumentation-annotation-counted/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/counted/CountedHelper.java create mode 100644 instrumentation/opentelemetry-instrumentation-annotation-counted/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/counted/CountedInstrumentation.java create mode 100644 instrumentation/opentelemetry-instrumentation-annotation-counted/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/counted/CountedInstrumentationModule.java create mode 100644 instrumentation/opentelemetry-instrumentation-annotation-counted/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/counted/KotlinCoroutineUtil.java create mode 100644 instrumentation/opentelemetry-instrumentation-annotation-counted/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/counted/MethodRequest.java create mode 100644 instrumentation/opentelemetry-instrumentation-annotation-counted/javaagent/src/test/java/io/opentelemetry/test/annotations/counted/CountedExample.java create mode 100644 instrumentation/opentelemetry-instrumentation-annotation-counted/javaagent/src/test/java/io/opentelemetry/test/annotations/counted/CountedInstrumentationTest.java create mode 100644 instrumentation/opentelemetry-instrumentation-annotation-timed/README.md create mode 100644 instrumentation/opentelemetry-instrumentation-annotation-timed/javaagent/build.gradle.kts create mode 100644 instrumentation/opentelemetry-instrumentation-annotation-timed/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/timed/AnnotationExcludedMethods.java create mode 100644 instrumentation/opentelemetry-instrumentation-annotation-timed/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/timed/KotlinCoroutineUtil.java create mode 100644 instrumentation/opentelemetry-instrumentation-annotation-timed/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/timed/MethodRequest.java create mode 100644 instrumentation/opentelemetry-instrumentation-annotation-timed/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/timed/TimedHelper.java create mode 100644 instrumentation/opentelemetry-instrumentation-annotation-timed/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/timed/TimedInstrumentation.java create mode 100644 instrumentation/opentelemetry-instrumentation-annotation-timed/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/timed/TimedInstrumentationModule.java create mode 100644 instrumentation/opentelemetry-instrumentation-annotation-timed/javaagent/src/test/java/io/opentelemetry/test/annotations/timed/TimedExample.java create mode 100644 instrumentation/opentelemetry-instrumentation-annotation-timed/javaagent/src/test/java/io/opentelemetry/test/annotations/timed/TimedInstrumentationTest.java diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-instrumentation-annotations.txt b/docs/apidiffs/current_vs_latest/opentelemetry-instrumentation-annotations.txt index f2ce28a1b43b..8c4c7b6c6a37 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-instrumentation-annotations.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-instrumentation-annotations.txt @@ -1,2 +1,36 @@ -Comparing source compatibility of opentelemetry-instrumentation-annotations-2.5.0-SNAPSHOT.jar against opentelemetry-instrumentation-annotations-2.4.0.jar -No changes. \ No newline at end of file +Comparing source compatibility of against ++++ NEW ANNOTATION: PUBLIC(+) ABSTRACT(+) io.opentelemetry.instrumentation.annotations.Counted (not serializable) + +++ CLASS FILE FORMAT VERSION: 52.0 <- n.a. + +++ NEW INTERFACE: java.lang.annotation.Annotation + +++ NEW SUPERCLASS: java.lang.Object + +++ NEW METHOD: PUBLIC(+) ABSTRACT(+) java.lang.String[] additionalAttributes() + +++ NEW METHOD: PUBLIC(+) ABSTRACT(+) java.lang.String description() + +++ NEW METHOD: PUBLIC(+) ABSTRACT(+) java.lang.String returnValueAttribute() + +++ NEW METHOD: PUBLIC(+) ABSTRACT(+) java.lang.String unit() + +++ NEW METHOD: PUBLIC(+) ABSTRACT(+) java.lang.String value() + +++ NEW ANNOTATION: java.lang.annotation.Target + +++ NEW ELEMENT: value=java.lang.annotation.ElementType.METHOD,java.lang.annotation.ElementType.CONSTRUCTOR (+) + +++ NEW ANNOTATION: java.lang.annotation.Retention + +++ NEW ELEMENT: value=java.lang.annotation.RetentionPolicy.RUNTIME (+) ++++ NEW ANNOTATION: PUBLIC(+) ABSTRACT(+) io.opentelemetry.instrumentation.annotations.MetricAttribute (not serializable) + +++ CLASS FILE FORMAT VERSION: 52.0 <- n.a. + +++ NEW INTERFACE: java.lang.annotation.Annotation + +++ NEW SUPERCLASS: java.lang.Object + +++ NEW METHOD: PUBLIC(+) ABSTRACT(+) java.lang.String value() + +++ NEW ANNOTATION: java.lang.annotation.Target + +++ NEW ELEMENT: value=java.lang.annotation.ElementType.PARAMETER (+) + +++ NEW ANNOTATION: java.lang.annotation.Retention + +++ NEW ELEMENT: value=java.lang.annotation.RetentionPolicy.RUNTIME (+) ++++ NEW ANNOTATION: PUBLIC(+) ABSTRACT(+) io.opentelemetry.instrumentation.annotations.Timed (not serializable) + +++ CLASS FILE FORMAT VERSION: 52.0 <- n.a. + +++ NEW INTERFACE: java.lang.annotation.Annotation + +++ NEW SUPERCLASS: java.lang.Object + +++ NEW METHOD: PUBLIC(+) ABSTRACT(+) java.lang.String[] additionalAttributes() + +++ NEW METHOD: PUBLIC(+) ABSTRACT(+) java.lang.String description() + +++ NEW METHOD: PUBLIC(+) ABSTRACT(+) java.lang.String returnValueAttribute() + +++ NEW METHOD: PUBLIC(+) ABSTRACT(+) java.util.concurrent.TimeUnit unit() + +++ NEW METHOD: PUBLIC(+) ABSTRACT(+) java.lang.String value() + +++ NEW ANNOTATION: java.lang.annotation.Target + +++ NEW ELEMENT: value=java.lang.annotation.ElementType.METHOD,java.lang.annotation.ElementType.CONSTRUCTOR (+) + +++ NEW ANNOTATION: java.lang.annotation.Retention + +++ NEW ELEMENT: value=java.lang.annotation.RetentionPolicy.RUNTIME (+) diff --git a/instrumentation-annotations/src/main/java/io/opentelemetry/instrumentation/annotations/Counted.java b/instrumentation-annotations/src/main/java/io/opentelemetry/instrumentation/annotations/Counted.java new file mode 100644 index 000000000000..0907f0210ae6 --- /dev/null +++ b/instrumentation-annotations/src/main/java/io/opentelemetry/instrumentation/annotations/Counted.java @@ -0,0 +1,95 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.instrumentation.annotations; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * This annotation creates a {@link io.opentelemetry.api.metrics.LongCounter Counter} instrument + * recording the number of invocations of the annotated method or constructor. + * + *

By default, the Counter instrument will have the following attributes: + * + *

+ * + *

Application developers can use this annotation to signal OpenTelemetry auto-instrumentation + * that the Counter instrument should be created. + * + *

If you are a library developer, then probably you should NOT use this annotation, because it + * is non-functional without the OpenTelemetry auto-instrumentation agent, or some other annotation + * processor. + */ +@Target({ElementType.METHOD, ElementType.CONSTRUCTOR}) +@Retention(RetentionPolicy.RUNTIME) +public @interface Counted { + + /** + * Name of the Counter instrument. + * + *

The name should follow the instrument naming rule: https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/metrics/api.md#instrument-naming-rule + * + *

The default name is {@code method.invocation.count}. + */ + String value() default ""; + + /** + * Description of the instrument. + * + *

Description strings should follow the instrument description rules: https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/metrics/api.md#instrument-description + * + *

This property would not take effect if the value is not specified. + */ + String description() default ""; + + /** + * Unit of the instrument. + * + *

Unit strings should follow the instrument unit rules: https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/metrics/api.md#instrument-unit + * + *

This property would not take effect if the value is not specified. + */ + String unit() default "{invocation}"; + + /** + * List of key-value pairs to supply additional attributes. + * + *

Example: + * + *

+   * {@literal @}Counted(
+   *     additionalAttributes = {
+   *       "key1", "value1",
+   *       "key2", "value2",
+   * })
+   * 
+ */ + String[] additionalAttributes() default {}; + + /** + * Attribute name for the return value. + * + *

The name of the attribute for the return value of the method call. {@link Object#toString()} + * will be called on the return value to convert it to a String. + * + *

By default, the instrument will not have an attribute with the return value. + * + *

Warning: be careful to fill it because it might cause an explosion of the cardinality on + * your metric + */ + String returnValueAttribute() default ""; +} diff --git a/instrumentation-annotations/src/main/java/io/opentelemetry/instrumentation/annotations/MetricAttribute.java b/instrumentation-annotations/src/main/java/io/opentelemetry/instrumentation/annotations/MetricAttribute.java new file mode 100644 index 000000000000..39b753fb9b9e --- /dev/null +++ b/instrumentation-annotations/src/main/java/io/opentelemetry/instrumentation/annotations/MetricAttribute.java @@ -0,0 +1,39 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.instrumentation.annotations; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * This annotation marks that a parameter of a method or constructor annotated with {@link Timed} or + * {@link Counted} should be added as an attribute to the instrument. + * + *

Application developers can use this annotation to signal OpenTelemetry auto-instrumentation + * that the attribute should be created. + * + *

If you are a library developer, then probably you should NOT use this annotation, because it + * is non-functional without the OpenTelemetry auto-instrumentation agent, or some other annotation + * processor. + */ +@Target(ElementType.PARAMETER) +@Retention(RetentionPolicy.RUNTIME) +public @interface MetricAttribute { + + /** + * Optional name of the attribute. + * + *

If not specified and the code is compiled using the `{@code -parameters}` argument to + * `javac`, the parameter name will be used instead. If the parameter name is not available, e.g., + * because the code was not compiled with that flag, the attribute will be ignored. + * + *

Warning: be careful to fill it because it might cause an explosion of the cardinality on + * your metric + */ + String value() default ""; +} diff --git a/instrumentation-annotations/src/main/java/io/opentelemetry/instrumentation/annotations/Timed.java b/instrumentation-annotations/src/main/java/io/opentelemetry/instrumentation/annotations/Timed.java new file mode 100644 index 000000000000..730dedd5f482 --- /dev/null +++ b/instrumentation-annotations/src/main/java/io/opentelemetry/instrumentation/annotations/Timed.java @@ -0,0 +1,91 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.instrumentation.annotations; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; +import java.util.concurrent.TimeUnit; + +/** + * This annotation creates a {@link io.opentelemetry.api.metrics.LongHistogram Histogram} instrument + * observing the duration of invocations of the annotated method or constructor. + * + *

By default, the Histogram instrument will have the following attributes: + * + *

+ * + *

Application developers can use this annotation to signal OpenTelemetry auto-instrumentation + * that the Histogram instrument should be created. + * + *

If you are a library developer, then probably you should NOT use this annotation, because it + * is non-functional without the OpenTelemetry auto-instrumentation agent, or some other annotation + * processor. + */ +@Target({ElementType.METHOD, ElementType.CONSTRUCTOR}) +@Retention(RetentionPolicy.RUNTIME) +public @interface Timed { + + /** + * Name of the Histogram instrument. + * + *

The name should follow the instrument naming rule: https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/metrics/api.md#instrument-naming-rule + * + *

The default name is {@code method.invocation.duration}. + */ + String value() default ""; + + /** + * Description for the instrument. + * + *

Description strings should follow the instrument description rules: https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/metrics/api.md#instrument-description + */ + String description() default ""; + + /** + * The unit for the instrument. + * + *

Default is milliseconds. + */ + TimeUnit unit() default TimeUnit.MILLISECONDS; + + /** + * List of key-value pairs to supply additional attributes. + * + *

Example: + * + *

+   * {@literal @}Timed(
+   *     additionalAttributes = {
+   *       "key1", "value1",
+   *       "key2", "value2",
+   * })
+   * 
+ */ + String[] additionalAttributes() default {}; + + /** + * Attribute name for the return value. + * + *

The name of the attribute for the return value of the method call. {@link Object#toString()} + * will be called on the return value to convert it to a String. + * + *

By default, the instrument will not have an attribute with the return value. + * + *

Warning: be careful to fill it because it might cause an explosion of the cardinality on + * your metric + */ + String returnValueAttribute() default ""; +} diff --git a/instrumentation-annotations/src/test/java/io/opentelemetry/instrumentation/annotations/CountedUsageExamples.java b/instrumentation-annotations/src/test/java/io/opentelemetry/instrumentation/annotations/CountedUsageExamples.java new file mode 100644 index 000000000000..46189a4932b1 --- /dev/null +++ b/instrumentation-annotations/src/test/java/io/opentelemetry/instrumentation/annotations/CountedUsageExamples.java @@ -0,0 +1,19 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.instrumentation.annotations; + +public class CountedUsageExamples { + + @Counted() + public void method1() {} + + @Counted("customizedName") + public void method2() {} + + @Counted + public void attributes( + @MetricAttribute String attribute1, @MetricAttribute("attribute2") long attribute2) {} +} diff --git a/instrumentation-annotations/src/test/java/io/opentelemetry/instrumentation/annotations/TimedUsageExamples.java b/instrumentation-annotations/src/test/java/io/opentelemetry/instrumentation/annotations/TimedUsageExamples.java new file mode 100644 index 000000000000..f9fc6ee8c87e --- /dev/null +++ b/instrumentation-annotations/src/test/java/io/opentelemetry/instrumentation/annotations/TimedUsageExamples.java @@ -0,0 +1,19 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.instrumentation.annotations; + +public class TimedUsageExamples { + + @Timed() + public void method1() {} + + @Timed("customizedName") + public void method2() {} + + @Timed + public void attributes( + @MetricAttribute String attribute1, @MetricAttribute("attribute2") long attribute2) {} +} diff --git a/instrumentation/opentelemetry-instrumentation-annotation-counted/README.md b/instrumentation/opentelemetry-instrumentation-annotation-counted/README.md new file mode 100644 index 000000000000..f52a11a938c0 --- /dev/null +++ b/instrumentation/opentelemetry-instrumentation-annotation-counted/README.md @@ -0,0 +1,5 @@ +# Settings for the OpenTelemetry Counted Instrumentation Annotations integration + +| Environment variable | Type | Default | Description | +|-----------------------------------------------------------------------------------------| ------ | ------- |-------------------------------------------------------------------------------------| +| `otel.instrumentation.opentelemetry-instrumentation-annotation-counted.exclude-methods` | String | | All methods to be excluded from auto-instrumentation by Counted annotation advices. | diff --git a/instrumentation/opentelemetry-instrumentation-annotation-counted/javaagent/build.gradle.kts b/instrumentation/opentelemetry-instrumentation-annotation-counted/javaagent/build.gradle.kts new file mode 100644 index 000000000000..e20c13308be6 --- /dev/null +++ b/instrumentation/opentelemetry-instrumentation-annotation-counted/javaagent/build.gradle.kts @@ -0,0 +1,46 @@ +plugins { + id("otel.javaagent-instrumentation") +} + +// note that muzzle is not run against the current SNAPSHOT instrumentation-annotations, but this is +// ok because the tests are run against the current SNAPSHOT instrumentation-annotations which will +// catch any muzzle issues in SNAPSHOT instrumentation-annotations + +muzzle { + pass { + group.set("io.opentelemetry") + module.set("opentelemetry-instrumentation-annotations") + versions.set("(,)") + } +} + +dependencies { + compileOnly(project(":instrumentation-annotations-support")) + + compileOnly(project(":javaagent-tooling")) + + // this instrumentation needs to do similar shading dance as opentelemetry-api-1.0 because + // the @WithSpan annotation references the OpenTelemetry API's SpanKind class + // + // see the comment in opentelemetry-api-1.0.gradle for more details + compileOnly(project(":opentelemetry-instrumentation-annotations-shaded-for-instrumenting", configuration = "shadow")) + + // Used by byte-buddy but not brought in as a transitive dependency. + compileOnly("com.google.code.findbugs:annotations") + testCompileOnly("com.google.code.findbugs:annotations") + + testImplementation(project(":instrumentation-annotations")) + testImplementation(project(":instrumentation-annotations-support")) + testImplementation("net.bytebuddy:byte-buddy") +} + +tasks { + compileTestJava { + options.compilerArgs.add("-parameters") + } + test { + jvmArgs( + "-Dotel.instrumentation.opentelemetry-instrumentation-annotation-counted.exclude-methods=io.opentelemetry.test.annotations.counted.CountedExample[exampleIgnore]" + ) + } +} diff --git a/instrumentation/opentelemetry-instrumentation-annotation-counted/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/counted/AnnotationExcludedMethods.java b/instrumentation/opentelemetry-instrumentation-annotation-counted/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/counted/AnnotationExcludedMethods.java new file mode 100644 index 000000000000..c5496df8cf4a --- /dev/null +++ b/instrumentation/opentelemetry-instrumentation-annotation-counted/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/counted/AnnotationExcludedMethods.java @@ -0,0 +1,53 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.javaagent.instrumentation.counted; + +import static net.bytebuddy.matcher.ElementMatchers.isDeclaredBy; +import static net.bytebuddy.matcher.ElementMatchers.namedOneOf; +import static net.bytebuddy.matcher.ElementMatchers.none; + +import io.opentelemetry.javaagent.bootstrap.internal.InstrumentationConfig; +import io.opentelemetry.javaagent.tooling.config.MethodsConfigurationParser; +import java.util.Map; +import java.util.Set; +import net.bytebuddy.description.ByteCodeElement; +import net.bytebuddy.description.method.MethodDescription; +import net.bytebuddy.matcher.ElementMatcher; +import net.bytebuddy.matcher.ElementMatchers; + +public final class AnnotationExcludedMethods { + + private static final String COUNTED_METHODS_EXCLUDE_CONFIG = + "otel.instrumentation.opentelemetry-instrumentation-annotation-counted.exclude-methods"; + + /* + Returns a matcher for all methods that should be excluded from auto-instrumentation by + annotation-based advices. + */ + public static ElementMatcher.Junction configureExcludedMethods() { + ElementMatcher.Junction result = none(); + + Map> excludedMethods = + MethodsConfigurationParser.parse( + InstrumentationConfig.get().getString(COUNTED_METHODS_EXCLUDE_CONFIG)); + for (Map.Entry> entry : excludedMethods.entrySet()) { + String className = entry.getKey(); + ElementMatcher.Junction matcher = + isDeclaredBy(ElementMatchers.named(className)); + + Set methodNames = entry.getValue(); + if (!methodNames.isEmpty()) { + matcher = matcher.and(namedOneOf(methodNames.toArray(new String[0]))); + } + + result = result.or(matcher); + } + + return result; + } + + private AnnotationExcludedMethods() {} +} diff --git a/instrumentation/opentelemetry-instrumentation-annotation-counted/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/counted/CountedHelper.java b/instrumentation/opentelemetry-instrumentation-annotation-counted/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/counted/CountedHelper.java new file mode 100644 index 000000000000..62c1172ea7e4 --- /dev/null +++ b/instrumentation/opentelemetry-instrumentation-annotation-counted/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/counted/CountedHelper.java @@ -0,0 +1,123 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.javaagent.instrumentation.counted; + +import application.io.opentelemetry.instrumentation.annotations.Counted; +import application.io.opentelemetry.instrumentation.annotations.MetricAttribute; +import io.opentelemetry.api.GlobalOpenTelemetry; +import io.opentelemetry.api.common.Attributes; +import io.opentelemetry.api.common.AttributesBuilder; +import io.opentelemetry.api.internal.StringUtils; +import io.opentelemetry.api.metrics.LongCounter; +import io.opentelemetry.api.metrics.Meter; +import java.lang.reflect.Method; +import java.lang.reflect.Parameter; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentMap; + +public final class CountedHelper { + + private static final String INSTRUMENTATION_NAME = + "io.opentelemetry.opentelemetry-instrumentation-annotation-counted"; + private static final String COUNTED_DEFAULT_NAME = "method.invocation.count"; + private static final ConcurrentMap COUNTERS = new ConcurrentHashMap<>(); + private static final Meter METER = GlobalOpenTelemetry.get().getMeter(INSTRUMENTATION_NAME); + + private static void extractMetricAttributes( + MethodRequest methodRequest, AttributesBuilder attributesBuilder) { + Parameter[] parameters = methodRequest.method().getParameters(); + for (int i = 0; i < parameters.length; i++) { + if (parameters[i].isAnnotationPresent(MetricAttribute.class)) { + MetricAttribute annotation = parameters[i].getAnnotation(MetricAttribute.class); + String attributeKey = ""; + if (!StringUtils.isNullOrEmpty(annotation.value())) { + attributeKey = annotation.value(); + } else if (!StringUtils.isNullOrEmpty(parameters[i].getName())) { + attributeKey = parameters[i].getName(); + } else { + continue; + } + attributesBuilder.put(attributeKey, methodRequest.args()[i].toString()); + } + } + } + + private static void extractAdditionAttributes( + String[] attributes, AttributesBuilder attributesBuilder) { + int length = attributes.length; + for (int i = 0; i + 1 < length; i += 2) { + attributesBuilder.put(attributes[i], attributes[i + 1]); + } + } + + public static void recordCountWithAttributes( + MethodRequest methodRequest, Object returnValue, Throwable throwable) { + Counted countedAnnotation = methodRequest.method().getAnnotation(Counted.class); + AttributesBuilder attributesBuilder = + getCommonAttributesBuilder(countedAnnotation, returnValue, throwable); + extractMetricAttributes(methodRequest, attributesBuilder); + getCounter(methodRequest.method()).add(1, attributesBuilder.build()); + } + + public static void recordCount(Method method, Object returnValue, Throwable throwable) { + Counted countedAnnotation = method.getAnnotation(Counted.class); + AttributesBuilder attributesBuilder = + getCommonAttributesBuilder(countedAnnotation, returnValue, throwable); + getCounter(method).add(1, attributesBuilder.build()); + } + + private static AttributesBuilder getCommonAttributesBuilder( + Counted countedAnnotation, Object returnValue, Throwable throwable) { + AttributesBuilder attributesBuilder = Attributes.builder(); + extractAdditionAttributes(countedAnnotation.additionalAttributes(), attributesBuilder); + extractReturnValue(countedAnnotation, returnValue, attributesBuilder); + extractException(throwable, attributesBuilder); + return attributesBuilder; + } + + private static void extractException(Throwable throwable, AttributesBuilder attributesBuilder) { + if (null != throwable) { + attributesBuilder.put("exception", throwable.getClass().getName()); + } + } + + private static void extractReturnValue( + Counted countedAnnotation, Object returnValue, AttributesBuilder attributesBuilder) { + if (null != countedAnnotation.returnValueAttribute() + && !countedAnnotation.returnValueAttribute().isEmpty()) { + attributesBuilder.put(countedAnnotation.returnValueAttribute(), returnValue.toString()); + } + } + + private static LongCounter getCounter(Method method) { + Counted countedAnnotation = method.getAnnotation(Counted.class); + String metricName = + (null == countedAnnotation.value() || countedAnnotation.value().isEmpty()) + ? COUNTED_DEFAULT_NAME + : countedAnnotation.value(); + if (!COUNTERS.containsKey(metricName)) { + synchronized (metricName) { + if (!COUNTERS.containsKey(metricName)) { + LongCounter longCounter = null; + if (COUNTED_DEFAULT_NAME.equals(metricName)) { + longCounter = METER.counterBuilder(metricName).build(); + } else { + longCounter = + METER + .counterBuilder(metricName) + .setDescription(countedAnnotation.description()) + .setUnit(countedAnnotation.unit()) + .build(); + } + COUNTERS.put(metricName, longCounter); + } + } + } + return COUNTERS.get(metricName); + } + + private CountedHelper() {} +} diff --git a/instrumentation/opentelemetry-instrumentation-annotation-counted/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/counted/CountedInstrumentation.java b/instrumentation/opentelemetry-instrumentation-annotation-counted/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/counted/CountedInstrumentation.java new file mode 100644 index 000000000000..d8ef1a889539 --- /dev/null +++ b/instrumentation/opentelemetry-instrumentation-annotation-counted/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/counted/CountedInstrumentation.java @@ -0,0 +1,117 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.javaagent.instrumentation.counted; + +import static io.opentelemetry.javaagent.instrumentation.counted.KotlinCoroutineUtil.isKotlinSuspendMethod; +import static net.bytebuddy.matcher.ElementMatchers.declaresMethod; +import static net.bytebuddy.matcher.ElementMatchers.hasParameters; +import static net.bytebuddy.matcher.ElementMatchers.isAnnotatedWith; +import static net.bytebuddy.matcher.ElementMatchers.named; +import static net.bytebuddy.matcher.ElementMatchers.not; +import static net.bytebuddy.matcher.ElementMatchers.whereAny; + +import io.opentelemetry.javaagent.extension.instrumentation.TypeInstrumentation; +import io.opentelemetry.javaagent.extension.instrumentation.TypeTransformer; +import java.lang.reflect.Method; +import net.bytebuddy.asm.Advice; +import net.bytebuddy.description.annotation.AnnotationSource; +import net.bytebuddy.description.method.MethodDescription; +import net.bytebuddy.description.type.TypeDescription; +import net.bytebuddy.implementation.bytecode.assign.Assigner; +import net.bytebuddy.matcher.ElementMatcher; + +public class CountedInstrumentation implements TypeInstrumentation { + + private final ElementMatcher.Junction annotatedMethodMatcher; + private final ElementMatcher.Junction annotatedParametersMatcher; + // this matcher matches all methods that should be excluded from transformation + private final ElementMatcher.Junction excludedMethodsMatcher; + + CountedInstrumentation() { + annotatedMethodMatcher = + isAnnotatedWith(named("application.io.opentelemetry.instrumentation.annotations.Counted")); + annotatedParametersMatcher = + hasParameters( + whereAny( + isAnnotatedWith( + named( + "application.io.opentelemetry.instrumentation.annotations.MetricAttribute")))); + // exclude all kotlin suspend methods, these are handle in kotlinx-coroutines instrumentation + excludedMethodsMatcher = + AnnotationExcludedMethods.configureExcludedMethods().or(isKotlinSuspendMethod()); + } + + @Override + public ElementMatcher typeMatcher() { + return declaresMethod(annotatedMethodMatcher); + } + + @Override + public void transform(TypeTransformer transformer) { + ElementMatcher.Junction countedMethods = + annotatedMethodMatcher.and(not(excludedMethodsMatcher)); + + ElementMatcher.Junction timedMethodsWithParameters = + countedMethods.and(annotatedParametersMatcher); + + ElementMatcher.Junction timedMethodsWithoutParameters = + countedMethods.and(not(annotatedParametersMatcher)); + + transformer.applyAdviceToMethod( + timedMethodsWithoutParameters, CountedInstrumentation.class.getName() + "$CountedAdvice"); + + // Only apply advice for tracing parameters as attributes if any of the parameters are annotated + // with @MetricsAttribute to avoid unnecessarily copying the arguments into an array. + transformer.applyAdviceToMethod( + timedMethodsWithParameters, + CountedInstrumentation.class.getName() + "$CountedAttributesAdvice"); + } + + @SuppressWarnings("unused") + public static class CountedAttributesAdvice { + + @Advice.OnMethodEnter(suppress = Throwable.class) + public static void onEnter( + @Advice.Origin Method originMethod, + @Advice.Local("otelMethod") Method method, + @Advice.AllArguments(typing = Assigner.Typing.DYNAMIC) Object[] args, + @Advice.Local("otelRequest") MethodRequest request) { + + // Every usage of @Advice.Origin Method is replaced with a call to Class.getMethod, copy it + // to local variable so that there would be only one call to Class.getMethod. + method = originMethod; + request = new MethodRequest(method, args); + } + + @Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class) + public static void onExit( + @Advice.Local("otelMethod") Method method, + @Advice.Local("otelRequest") MethodRequest request, + @Advice.Return(typing = Assigner.Typing.DYNAMIC, readOnly = false) Object returnValue, + @Advice.Thrown Throwable throwable) { + CountedHelper.recordCountWithAttributes(request, returnValue, throwable); + } + } + + @SuppressWarnings("unused") + public static class CountedAdvice { + @Advice.OnMethodEnter(suppress = Throwable.class) + public static void onEnter( + @Advice.Origin Method originMethod, @Advice.Local("otelMethod") Method method) { + // Every usage of @Advice.Origin Method is replaced with a call to Class.getMethod, copy it + // to local variable so that there would be only one call to Class.getMethod. + method = originMethod; + } + + @Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class) + public static void onExit( + @Advice.Local("otelMethod") Method method, + @Advice.Return(typing = Assigner.Typing.DYNAMIC, readOnly = false) Object returnValue, + @Advice.Thrown Throwable throwable) { + CountedHelper.recordCount(method, returnValue, throwable); + } + } +} diff --git a/instrumentation/opentelemetry-instrumentation-annotation-counted/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/counted/CountedInstrumentationModule.java b/instrumentation/opentelemetry-instrumentation-annotation-counted/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/counted/CountedInstrumentationModule.java new file mode 100644 index 000000000000..c61f13f3bbca --- /dev/null +++ b/instrumentation/opentelemetry-instrumentation-annotation-counted/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/counted/CountedInstrumentationModule.java @@ -0,0 +1,44 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.javaagent.instrumentation.counted; + +import static io.opentelemetry.javaagent.extension.matcher.AgentElementMatchers.hasClassesNamed; +import static java.util.Arrays.asList; + +import com.google.auto.service.AutoService; +import io.opentelemetry.javaagent.extension.instrumentation.InstrumentationModule; +import io.opentelemetry.javaagent.extension.instrumentation.TypeInstrumentation; +import java.util.List; +import net.bytebuddy.matcher.ElementMatcher; + +/** + * Instrumentation for methods annotated with {@link Counted} or {@link MetricAttribute} + * annotations. + */ +@AutoService(InstrumentationModule.class) +public class CountedInstrumentationModule extends InstrumentationModule { + + public CountedInstrumentationModule() { + super("opentelemetry-instrumentation-annotation-counted", "counted"); + } + + @Override + public int order() { + // Run first to ensure other automatic instrumentation is added after and therefore is executed + // earlier in the instrumented method and create the span to attach attributes to. + return -1000; + } + + @Override + public ElementMatcher.Junction classLoaderMatcher() { + return hasClassesNamed("application.io.opentelemetry.instrumentation.annotations.Counted"); + } + + @Override + public List typeInstrumentations() { + return asList(new CountedInstrumentation()); + } +} diff --git a/instrumentation/opentelemetry-instrumentation-annotation-counted/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/counted/KotlinCoroutineUtil.java b/instrumentation/opentelemetry-instrumentation-annotation-counted/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/counted/KotlinCoroutineUtil.java new file mode 100644 index 000000000000..557cc436498f --- /dev/null +++ b/instrumentation/opentelemetry-instrumentation-annotation-counted/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/counted/KotlinCoroutineUtil.java @@ -0,0 +1,32 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.javaagent.instrumentation.counted; + +import static net.bytebuddy.matcher.ElementMatchers.returns; + +import net.bytebuddy.description.method.MethodDescription; +import net.bytebuddy.description.method.ParameterList; +import net.bytebuddy.matcher.ElementMatcher; + +public final class KotlinCoroutineUtil { + + private KotlinCoroutineUtil() {} + + public static ElementMatcher isKotlinSuspendMethod() { + // kotlin suspend methods return Object and take kotlin.coroutines.Continuation as last argument + return returns(Object.class) + .and( + target -> { + ParameterList parameterList = target.getParameters(); + if (!parameterList.isEmpty()) { + String lastParameter = + parameterList.get(parameterList.size() - 1).getType().asErasure().getName(); + return "kotlin.coroutines.Continuation".equals(lastParameter); + } + return false; + }); + } +} diff --git a/instrumentation/opentelemetry-instrumentation-annotation-counted/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/counted/MethodRequest.java b/instrumentation/opentelemetry-instrumentation-annotation-counted/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/counted/MethodRequest.java new file mode 100644 index 000000000000..8c151492d882 --- /dev/null +++ b/instrumentation/opentelemetry-instrumentation-annotation-counted/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/counted/MethodRequest.java @@ -0,0 +1,26 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.javaagent.instrumentation.counted; + +import java.lang.reflect.Method; + +public final class MethodRequest { + private final Method method; + private final Object[] args; + + public MethodRequest(Method method, Object[] args) { + this.method = method; + this.args = args; + } + + public Method method() { + return this.method; + } + + public Object[] args() { + return this.args; + } +} diff --git a/instrumentation/opentelemetry-instrumentation-annotation-counted/javaagent/src/test/java/io/opentelemetry/test/annotations/counted/CountedExample.java b/instrumentation/opentelemetry-instrumentation-annotation-counted/javaagent/src/test/java/io/opentelemetry/test/annotations/counted/CountedExample.java new file mode 100644 index 000000000000..801f4a10988f --- /dev/null +++ b/instrumentation/opentelemetry-instrumentation-annotation-counted/javaagent/src/test/java/io/opentelemetry/test/annotations/counted/CountedExample.java @@ -0,0 +1,60 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.test.annotations.counted; + +import io.opentelemetry.instrumentation.annotations.Counted; + +public class CountedExample { + + public static final String ANOTHER_NAME_COUNT = "another.name.count"; + public static final String METRIC_DESCRIPTION = "I am the description."; + public static final String METRIC_UNIT = "ms"; + public static final String RETURN_STRING = "I am a return string."; + + @Counted + public void defaultExample() {} + + @Counted(ANOTHER_NAME_COUNT) + public void exampleWithAnotherName() {} + + @Counted(description = METRIC_DESCRIPTION) + public void exampleWithDescriptionAndDefaultValue() {} + + @Counted(unit = METRIC_UNIT) + public void exampleWithUnitAndDefaultValue() {} + + @Counted(value = "example.with.description.count", description = METRIC_DESCRIPTION) + public void exampleWithDescription() {} + + @Counted(value = "example.with.unit.count", unit = METRIC_UNIT) + public void exampleWithUnit() {} + + @Counted(additionalAttributes = {"key1", "value1", "key2", "value2"}) + public void exampleWithAdditionalAttributes1() {} + + @Counted(additionalAttributes = {"key1", "value1", "key2", "value2", "key3"}) + public void exampleWithAdditionalAttributes2() {} + + @Counted(returnValueAttribute = "returnValue") + public ReturnObject exampleWithReturnValueAttribute() { + return new ReturnObject(); + } + + @Counted + public void exampleWithException() { + throw new IllegalStateException("test exception."); + } + + @Counted + public void exampleIgnore() {} + + public static class ReturnObject { + @Override + public String toString() { + return RETURN_STRING; + } + } +} diff --git a/instrumentation/opentelemetry-instrumentation-annotation-counted/javaagent/src/test/java/io/opentelemetry/test/annotations/counted/CountedInstrumentationTest.java b/instrumentation/opentelemetry-instrumentation-annotation-counted/javaagent/src/test/java/io/opentelemetry/test/annotations/counted/CountedInstrumentationTest.java new file mode 100644 index 000000000000..f3796189c73f --- /dev/null +++ b/instrumentation/opentelemetry-instrumentation-annotation-counted/javaagent/src/test/java/io/opentelemetry/test/annotations/counted/CountedInstrumentationTest.java @@ -0,0 +1,171 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.test.annotations.counted; + +import static io.opentelemetry.test.annotations.counted.CountedExample.ANOTHER_NAME_COUNT; +import static io.opentelemetry.test.annotations.counted.CountedExample.METRIC_DESCRIPTION; +import static io.opentelemetry.test.annotations.counted.CountedExample.METRIC_UNIT; +import static org.assertj.core.api.Assertions.assertThat; + +import io.opentelemetry.api.common.AttributeKey; +import io.opentelemetry.instrumentation.testing.junit.AgentInstrumentationExtension; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; + +class CountedInstrumentationTest { + + @RegisterExtension + public static final AgentInstrumentationExtension testing = + AgentInstrumentationExtension.create(); + + public static final String INSTRUMENTATION_NAME = + "io.opentelemetry.opentelemetry-instrumentation-annotation-counted"; + + public static final String COUNTED_DEFAULT_NAME = "method.invocation.count"; + + @Test + void testDefaultExample() { + new CountedExample().defaultExample(); + testing.waitAndAssertMetrics( + INSTRUMENTATION_NAME, metric -> metric.hasName(COUNTED_DEFAULT_NAME)); + } + + @Test + void testExampleWithAnotherName() { + new CountedExample().exampleWithAnotherName(); + testing.waitAndAssertMetrics( + INSTRUMENTATION_NAME, metric -> metric.hasName(ANOTHER_NAME_COUNT)); + } + + @Test + void testExampleWithDescriptionAndDefaultValue() { + new CountedExample().exampleWithDescriptionAndDefaultValue(); + testing.waitAndAssertMetrics( + INSTRUMENTATION_NAME, metric -> metric.hasName(COUNTED_DEFAULT_NAME).hasDescription("")); + } + + @Test + void testExampleWithUnitAndDefaultValue() { + new CountedExample().exampleWithUnitAndDefaultValue(); + testing.waitAndAssertMetrics( + INSTRUMENTATION_NAME, metric -> metric.hasName(COUNTED_DEFAULT_NAME).hasUnit("")); + } + + @Test + void testExampleWithDescription() { + new CountedExample().exampleWithDescription(); + testing.waitAndAssertMetrics( + INSTRUMENTATION_NAME, + metric -> + metric.hasName("example.with.description.count").hasDescription(METRIC_DESCRIPTION)); + } + + @Test + void testExampleWithUnit() { + new CountedExample().exampleWithUnit(); + testing.waitAndAssertMetrics( + INSTRUMENTATION_NAME, + metric -> metric.hasName("example.with.unit.count").hasUnit(METRIC_UNIT)); + } + + @Test + void testExampleWithAdditionalAttributes1() { + new CountedExample().exampleWithAdditionalAttributes1(); + testing.waitAndAssertMetrics( + INSTRUMENTATION_NAME, + metric -> + metric + .hasName(COUNTED_DEFAULT_NAME) + .satisfies( + metricData -> { + assertThat(metricData.getData().getPoints()) + .allMatch( + p -> + "value1" + .equals( + p.getAttributes().get(AttributeKey.stringKey("key1"))) + && "value2" + .equals( + p.getAttributes() + .get(AttributeKey.stringKey("key2")))); + })); + } + + @Test + void testExampleWithAdditionalAttributes2() { + new CountedExample().exampleWithAdditionalAttributes2(); + testing.waitAndAssertMetrics( + INSTRUMENTATION_NAME, + metric -> + metric + .hasName(COUNTED_DEFAULT_NAME) + .satisfies( + metricData -> { + assertThat(metricData.getData().getPoints()) + .allMatch( + p -> + "value1" + .equals( + p.getAttributes().get(AttributeKey.stringKey("key1"))) + && "value2" + .equals( + p.getAttributes().get(AttributeKey.stringKey("key2"))) + && null + == p.getAttributes().get(AttributeKey.stringKey("key3"))); + })); + } + + @Test + void testExampleWithReturnAttribute() { + new CountedExample().exampleWithReturnValueAttribute(); + testing.waitAndAssertMetrics( + INSTRUMENTATION_NAME, + metric -> + metric + .hasName(COUNTED_DEFAULT_NAME) + .satisfies( + metricData -> { + assertThat(metricData.getData().getPoints()) + .allMatch( + p -> + CountedExample.RETURN_STRING.equals( + p.getAttributes() + .get(AttributeKey.stringKey("returnValue")))); + })); + } + + @Test + void testExampleWithException() { + try { + new CountedExample().exampleWithException(); + } catch (IllegalStateException e) { + // noop + } + testing.waitAndAssertMetrics( + INSTRUMENTATION_NAME, + metric -> + metric + .hasName(COUNTED_DEFAULT_NAME) + .satisfies( + metricData -> { + assertThat(metricData.getData().getPoints()) + .allMatch( + p -> + IllegalStateException.class + .getName() + .equals( + p.getAttributes() + .get(AttributeKey.stringKey("exception")))); + })); + } + + @Test + void testExampleIgnore() throws Exception { + new CountedExample().exampleIgnore(); + Thread.sleep(500); // sleep a bit just to make sure no metric is captured + assertThat(testing.metrics()).isEmpty(); + } +} diff --git a/instrumentation/opentelemetry-instrumentation-annotation-timed/README.md b/instrumentation/opentelemetry-instrumentation-annotation-timed/README.md new file mode 100644 index 000000000000..a16004d9f4dd --- /dev/null +++ b/instrumentation/opentelemetry-instrumentation-annotation-timed/README.md @@ -0,0 +1,5 @@ +# Settings for the OpenTelemetry Timed Instrumentation Annotations integration + +| Environment variable | Type | Default | Description | +|-----------------------------------------------------------------------------------------| ------ | ------- |-----------------------------------------------------------------------------------| +| `otel.instrumentation.opentelemetry-instrumentation-annotation-Timed.exclude-methods` | String | | All methods to be excluded from auto-instrumentation by Timed annotation advices. | diff --git a/instrumentation/opentelemetry-instrumentation-annotation-timed/javaagent/build.gradle.kts b/instrumentation/opentelemetry-instrumentation-annotation-timed/javaagent/build.gradle.kts new file mode 100644 index 000000000000..ce5402c4d69c --- /dev/null +++ b/instrumentation/opentelemetry-instrumentation-annotation-timed/javaagent/build.gradle.kts @@ -0,0 +1,46 @@ +plugins { + id("otel.javaagent-instrumentation") +} + +// note that muzzle is not run against the current SNAPSHOT instrumentation-annotations, but this is +// ok because the tests are run against the current SNAPSHOT instrumentation-annotations which will +// catch any muzzle issues in SNAPSHOT instrumentation-annotations + +muzzle { + pass { + group.set("io.opentelemetry") + module.set("opentelemetry-instrumentation-annotations") + versions.set("(,)") + } +} + +dependencies { + compileOnly(project(":instrumentation-annotations-support")) + + compileOnly(project(":javaagent-tooling")) + + // this instrumentation needs to do similar shading dance as opentelemetry-api-1.0 because + // the @WithSpan annotation references the OpenTelemetry API's SpanKind class + // + // see the comment in opentelemetry-api-1.0.gradle for more details + compileOnly(project(":opentelemetry-instrumentation-annotations-shaded-for-instrumenting", configuration = "shadow")) + + // Used by byte-buddy but not brought in as a transitive dependency. + compileOnly("com.google.code.findbugs:annotations") + testCompileOnly("com.google.code.findbugs:annotations") + + testImplementation(project(":instrumentation-annotations")) + testImplementation(project(":instrumentation-annotations-support")) + testImplementation("net.bytebuddy:byte-buddy") +} + +tasks { + compileTestJava { + options.compilerArgs.add("-parameters") + } + test { + jvmArgs( + "-Dotel.instrumentation.opentelemetry-instrumentation-annotation-timed.exclude-methods=io.opentelemetry.test.annotations.timed.TimedExample[exampleIgnore]" + ) + } +} diff --git a/instrumentation/opentelemetry-instrumentation-annotation-timed/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/timed/AnnotationExcludedMethods.java b/instrumentation/opentelemetry-instrumentation-annotation-timed/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/timed/AnnotationExcludedMethods.java new file mode 100644 index 000000000000..ea14c24f8aa0 --- /dev/null +++ b/instrumentation/opentelemetry-instrumentation-annotation-timed/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/timed/AnnotationExcludedMethods.java @@ -0,0 +1,53 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.javaagent.instrumentation.timed; + +import static net.bytebuddy.matcher.ElementMatchers.isDeclaredBy; +import static net.bytebuddy.matcher.ElementMatchers.namedOneOf; +import static net.bytebuddy.matcher.ElementMatchers.none; + +import io.opentelemetry.javaagent.bootstrap.internal.InstrumentationConfig; +import io.opentelemetry.javaagent.tooling.config.MethodsConfigurationParser; +import java.util.Map; +import java.util.Set; +import net.bytebuddy.description.ByteCodeElement; +import net.bytebuddy.description.method.MethodDescription; +import net.bytebuddy.matcher.ElementMatcher; +import net.bytebuddy.matcher.ElementMatchers; + +public final class AnnotationExcludedMethods { + + private static final String TIMED_METHODS_EXCLUDE_CONFIG = + "otel.instrumentation.opentelemetry-instrumentation-annotation-timed.exclude-methods"; + + /* + Returns a matcher for all methods that should be excluded from auto-instrumentation by + annotation-based advices. + */ + public static ElementMatcher.Junction configureExcludedMethods() { + ElementMatcher.Junction result = none(); + + Map> excludedMethods = + MethodsConfigurationParser.parse( + InstrumentationConfig.get().getString(TIMED_METHODS_EXCLUDE_CONFIG)); + for (Map.Entry> entry : excludedMethods.entrySet()) { + String className = entry.getKey(); + ElementMatcher.Junction matcher = + isDeclaredBy(ElementMatchers.named(className)); + + Set methodNames = entry.getValue(); + if (!methodNames.isEmpty()) { + matcher = matcher.and(namedOneOf(methodNames.toArray(new String[0]))); + } + + result = result.or(matcher); + } + + return result; + } + + private AnnotationExcludedMethods() {} +} diff --git a/instrumentation/opentelemetry-instrumentation-annotation-timed/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/timed/KotlinCoroutineUtil.java b/instrumentation/opentelemetry-instrumentation-annotation-timed/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/timed/KotlinCoroutineUtil.java new file mode 100644 index 000000000000..c0e0e6c31379 --- /dev/null +++ b/instrumentation/opentelemetry-instrumentation-annotation-timed/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/timed/KotlinCoroutineUtil.java @@ -0,0 +1,32 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.javaagent.instrumentation.timed; + +import static net.bytebuddy.matcher.ElementMatchers.returns; + +import net.bytebuddy.description.method.MethodDescription; +import net.bytebuddy.description.method.ParameterList; +import net.bytebuddy.matcher.ElementMatcher; + +public final class KotlinCoroutineUtil { + + private KotlinCoroutineUtil() {} + + public static ElementMatcher isKotlinSuspendMethod() { + // kotlin suspend methods return Object and take kotlin.coroutines.Continuation as last argument + return returns(Object.class) + .and( + target -> { + ParameterList parameterList = target.getParameters(); + if (!parameterList.isEmpty()) { + String lastParameter = + parameterList.get(parameterList.size() - 1).getType().asErasure().getName(); + return "kotlin.coroutines.Continuation".equals(lastParameter); + } + return false; + }); + } +} diff --git a/instrumentation/opentelemetry-instrumentation-annotation-timed/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/timed/MethodRequest.java b/instrumentation/opentelemetry-instrumentation-annotation-timed/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/timed/MethodRequest.java new file mode 100644 index 000000000000..352e65d06611 --- /dev/null +++ b/instrumentation/opentelemetry-instrumentation-annotation-timed/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/timed/MethodRequest.java @@ -0,0 +1,26 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.javaagent.instrumentation.timed; + +import java.lang.reflect.Method; + +public final class MethodRequest { + private final Method method; + private final Object[] args; + + public MethodRequest(Method method, Object[] args) { + this.method = method; + this.args = args; + } + + public Method method() { + return this.method; + } + + public Object[] args() { + return this.args; + } +} diff --git a/instrumentation/opentelemetry-instrumentation-annotation-timed/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/timed/TimedHelper.java b/instrumentation/opentelemetry-instrumentation-annotation-timed/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/timed/TimedHelper.java new file mode 100644 index 000000000000..deaa1c21b306 --- /dev/null +++ b/instrumentation/opentelemetry-instrumentation-annotation-timed/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/timed/TimedHelper.java @@ -0,0 +1,163 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.javaagent.instrumentation.timed; + +import static java.util.concurrent.TimeUnit.MICROSECONDS; +import static java.util.concurrent.TimeUnit.NANOSECONDS; +import static java.util.concurrent.TimeUnit.SECONDS; + +import application.io.opentelemetry.instrumentation.annotations.MetricAttribute; +import application.io.opentelemetry.instrumentation.annotations.Timed; +// import io.opentelemetry.javaagent.instrumentation.timed.annotations.Timed; +// import io.opentelemetry.javaagent.instrumentation.timed.annotations.MetricAttribute; +import io.opentelemetry.api.GlobalOpenTelemetry; +import io.opentelemetry.api.common.Attributes; +import io.opentelemetry.api.common.AttributesBuilder; +import io.opentelemetry.api.internal.StringUtils; +import io.opentelemetry.api.metrics.DoubleHistogram; +import io.opentelemetry.api.metrics.Meter; +import java.lang.reflect.Method; +import java.lang.reflect.Parameter; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentMap; +import java.util.concurrent.TimeUnit; + +public final class TimedHelper { + + private static final String INSTRUMENTATION_NAME = + "io.opentelemetry.opentelemetry-instrumentation-annotation-timed"; + private static final String TIMED_DEFAULT_NAME = "method.invocation.duration"; + + private static final ConcurrentMap HISTOGRAMS = + new ConcurrentHashMap<>(); + + private static final Meter METER = GlobalOpenTelemetry.get().getMeter(INSTRUMENTATION_NAME); + + private static void extractMetricAttributes( + MethodRequest methodRequest, AttributesBuilder attributesBuilder) { + Parameter[] parameters = methodRequest.method().getParameters(); + for (int i = 0; i < parameters.length; i++) { + if (parameters[i].isAnnotationPresent(MetricAttribute.class)) { + MetricAttribute annotation = parameters[i].getAnnotation(MetricAttribute.class); + String attributeKey = ""; + if (!StringUtils.isNullOrEmpty(annotation.value())) { + attributeKey = annotation.value(); + } else if (!StringUtils.isNullOrEmpty(parameters[i].getName())) { + attributeKey = parameters[i].getName(); + } else { + continue; + } + attributesBuilder.put(attributeKey, methodRequest.args()[i].toString()); + } + } + } + + private static void extractAdditionAttributes( + String[] attributes, AttributesBuilder attributesBuilder) { + int length = attributes.length; + for (int i = 0; i + 1 < length; i += 2) { + attributesBuilder.put(attributes[i], attributes[i + 1]); + } + } + + public static void recordHistogramWithAttributes( + MethodRequest methodRequest, Throwable throwable, Object returnValue, long startNanoTime) { + Timed timedAnnotation = methodRequest.method().getAnnotation(Timed.class); + AttributesBuilder attributesBuilder = + getCommonAttributeBuilder(throwable, returnValue, timedAnnotation); + double duration = getTransformedDuration(startNanoTime, timedAnnotation); + extractMetricAttributes(methodRequest, attributesBuilder); + getHistogram(timedAnnotation).record(duration, attributesBuilder.build()); + } + + public static void recordHistogram( + Method method, Throwable throwable, Object returnValue, long startNanoTime) { + Timed timedAnnotation = method.getAnnotation(Timed.class); + AttributesBuilder attributesBuilder = + getCommonAttributeBuilder(throwable, returnValue, timedAnnotation); + double duration = getTransformedDuration(startNanoTime, timedAnnotation); + getHistogram(timedAnnotation).record(duration, attributesBuilder.build()); + } + + private static AttributesBuilder getCommonAttributeBuilder( + Throwable throwable, Object returnValue, Timed timedAnnotation) { + AttributesBuilder attributesBuilder = Attributes.builder(); + extractAdditionAttributes(timedAnnotation.additionalAttributes(), attributesBuilder); + extractReturnValue(timedAnnotation, returnValue, attributesBuilder); + extractException(throwable, attributesBuilder); + return attributesBuilder; + } + + private static double getTransformedDuration(long startNanoTime, Timed timedAnnotation) { + TimeUnit unit = extractTimeUnit(timedAnnotation); + long nanoDelta = System.nanoTime() - startNanoTime; + double duration = unit.convert(nanoDelta, NANOSECONDS); + return duration; + } + + private static void extractException(Throwable throwable, AttributesBuilder attributesBuilder) { + if (null != throwable) { + attributesBuilder.put("exception", throwable.getClass().getName()); + } + } + + private static void extractReturnValue( + Timed countedAnnotation, Object returnValue, AttributesBuilder attributesBuilder) { + if (null != countedAnnotation.returnValueAttribute() + && !countedAnnotation.returnValueAttribute().isEmpty()) { + attributesBuilder.put(countedAnnotation.returnValueAttribute(), returnValue.toString()); + } + } + + private static DoubleHistogram getHistogram(Timed timedAnnotation) { + String metricName = + (null == timedAnnotation.value() || timedAnnotation.value().isEmpty()) + ? TIMED_DEFAULT_NAME + : timedAnnotation.value(); + if (!HISTOGRAMS.containsKey(metricName)) { + synchronized (metricName) { + if (!HISTOGRAMS.containsKey(metricName)) { + DoubleHistogram doubleHistogram = null; + if (TIMED_DEFAULT_NAME.equals(metricName)) { + doubleHistogram = METER.histogramBuilder(metricName).build(); + } else { + String unitStr = extractUnitStr(timedAnnotation); + doubleHistogram = + METER + .histogramBuilder(metricName) + .setDescription(timedAnnotation.description()) + .setUnit(unitStr) + .build(); + } + HISTOGRAMS.put(metricName, doubleHistogram); + } + } + } + return HISTOGRAMS.get(metricName); + } + + private static TimeUnit extractTimeUnit(Timed timedAnnotation) { + if (null == timedAnnotation.unit()) { + return TimeUnit.MILLISECONDS; + } + return timedAnnotation.unit(); + } + + private static String extractUnitStr(Timed timedAnnotation) { + switch (timedAnnotation.unit()) { + case NANOSECONDS: + return "ns"; + case MICROSECONDS: + return "µs"; + case SECONDS: + return "s"; + default: + return "ms"; + } + } + + private TimedHelper() {} +} diff --git a/instrumentation/opentelemetry-instrumentation-annotation-timed/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/timed/TimedInstrumentation.java b/instrumentation/opentelemetry-instrumentation-annotation-timed/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/timed/TimedInstrumentation.java new file mode 100644 index 000000000000..af92a66287c7 --- /dev/null +++ b/instrumentation/opentelemetry-instrumentation-annotation-timed/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/timed/TimedInstrumentation.java @@ -0,0 +1,125 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.javaagent.instrumentation.timed; + +import static io.opentelemetry.javaagent.instrumentation.timed.KotlinCoroutineUtil.isKotlinSuspendMethod; +import static net.bytebuddy.matcher.ElementMatchers.declaresMethod; +import static net.bytebuddy.matcher.ElementMatchers.hasParameters; +import static net.bytebuddy.matcher.ElementMatchers.isAnnotatedWith; +import static net.bytebuddy.matcher.ElementMatchers.named; +import static net.bytebuddy.matcher.ElementMatchers.not; +import static net.bytebuddy.matcher.ElementMatchers.whereAny; + +import io.opentelemetry.javaagent.extension.instrumentation.TypeInstrumentation; +import io.opentelemetry.javaagent.extension.instrumentation.TypeTransformer; +import java.lang.reflect.Method; +import net.bytebuddy.asm.Advice; +import net.bytebuddy.description.annotation.AnnotationSource; +import net.bytebuddy.description.method.MethodDescription; +import net.bytebuddy.description.type.TypeDescription; +import net.bytebuddy.implementation.bytecode.assign.Assigner; +import net.bytebuddy.matcher.ElementMatcher; + +public class TimedInstrumentation implements TypeInstrumentation { + + private final ElementMatcher.Junction annotatedMethodMatcher; + private final ElementMatcher.Junction annotatedParametersMatcher; + // this matcher matches all methods that should be excluded from transformation + private final ElementMatcher.Junction excludedMethodsMatcher; + + TimedInstrumentation() { + annotatedMethodMatcher = + isAnnotatedWith(named("application.io.opentelemetry.instrumentation.annotations.Timed")); + annotatedParametersMatcher = + hasParameters( + whereAny( + isAnnotatedWith( + named( + "application.io.opentelemetry.instrumentation.annotations.MetricAttribute")))); + // exclude all kotlin suspend methods, these are handle in kotlinx-coroutines instrumentation + excludedMethodsMatcher = + AnnotationExcludedMethods.configureExcludedMethods().or(isKotlinSuspendMethod()); + } + + @Override + public ElementMatcher typeMatcher() { + return declaresMethod(annotatedMethodMatcher); + } + + @Override + public void transform(TypeTransformer transformer) { + ElementMatcher.Junction timedMethods = + annotatedMethodMatcher.and(not(excludedMethodsMatcher)); + + ElementMatcher.Junction timedMethodsWithParameters = + timedMethods.and(annotatedParametersMatcher); + + ElementMatcher.Junction timedMethodsWithoutParameters = + timedMethods.and(not(annotatedParametersMatcher)); + + transformer.applyAdviceToMethod( + timedMethodsWithoutParameters, TimedInstrumentation.class.getName() + "$TimedAdvice"); + + // Only apply advice for tracing parameters as attributes if any of the parameters are annotated + // with @MetricsAttribute to avoid unnecessarily copying the arguments into an array. + transformer.applyAdviceToMethod( + timedMethodsWithParameters, + TimedInstrumentation.class.getName() + "$TimedAttributesAdvice"); + } + + @SuppressWarnings("unused") + public static class TimedAttributesAdvice { + + @Advice.OnMethodEnter(suppress = Throwable.class) + public static void onEnter( + @Advice.Origin Method originMethod, + @Advice.Local("otelMethod") Method method, + @Advice.AllArguments(typing = Assigner.Typing.DYNAMIC) Object[] args, + @Advice.Local("otelRequest") MethodRequest request, + @Advice.Local("startNanoTime") long startNanoTime) { + + // Every usage of @Advice.Origin Method is replaced with a call to Class.getMethod, copy it + // to local variable so that there would be only one call to Class.getMethod. + method = originMethod; + request = new MethodRequest(method, args); + startNanoTime = System.nanoTime(); + } + + @Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class) + public static void onExit( + @Advice.Local("otelMethod") Method method, + @Advice.Local("otelRequest") MethodRequest request, + @Advice.Local("startNanoTime") long startNanoTime, + @Advice.Return(typing = Assigner.Typing.DYNAMIC, readOnly = false) Object returnValue, + @Advice.Thrown Throwable throwable) { + TimedHelper.recordHistogramWithAttributes(request, throwable, returnValue, startNanoTime); + } + } + + @SuppressWarnings("unused") + public static class TimedAdvice { + + @Advice.OnMethodEnter(suppress = Throwable.class) + public static void onEnter( + @Advice.Origin Method originMethod, + @Advice.Local("otelMethod") Method method, + @Advice.Local("startNanoTime") long startNanoTime) { + // Every usage of @Advice.Origin Method is replaced with a call to Class.getMethod, copy it + // to local variable so that there would be only one call to Class.getMethod. + method = originMethod; + startNanoTime = System.nanoTime(); + } + + @Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class) + public static void onExit( + @Advice.Local("otelMethod") Method method, + @Advice.Local("startNanoTime") long startNanoTime, + @Advice.Return(typing = Assigner.Typing.DYNAMIC, readOnly = false) Object returnValue, + @Advice.Thrown Throwable throwable) { + TimedHelper.recordHistogram(method, throwable, returnValue, startNanoTime); + } + } +} diff --git a/instrumentation/opentelemetry-instrumentation-annotation-timed/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/timed/TimedInstrumentationModule.java b/instrumentation/opentelemetry-instrumentation-annotation-timed/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/timed/TimedInstrumentationModule.java new file mode 100644 index 000000000000..c8cd222d2810 --- /dev/null +++ b/instrumentation/opentelemetry-instrumentation-annotation-timed/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/timed/TimedInstrumentationModule.java @@ -0,0 +1,43 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.javaagent.instrumentation.timed; + +import static io.opentelemetry.javaagent.extension.matcher.AgentElementMatchers.hasClassesNamed; +import static java.util.Arrays.asList; + +import com.google.auto.service.AutoService; +import io.opentelemetry.javaagent.extension.instrumentation.InstrumentationModule; +import io.opentelemetry.javaagent.extension.instrumentation.TypeInstrumentation; +import java.util.List; +import net.bytebuddy.matcher.ElementMatcher; + +/** + * Instrumentation for methods annotated with {@link Timed} and {@link MetricAttribute} annotations. + */ +@AutoService(InstrumentationModule.class) +public class TimedInstrumentationModule extends InstrumentationModule { + + public TimedInstrumentationModule() { + super("opentelemetry-instrumentation-annotation-timed", "timed"); + } + + @Override + public int order() { + // Run first to ensure other automatic instrumentation is added after and therefore is executed + // earlier in the instrumented method and create the span to attach attributes to. + return -1000; + } + + @Override + public ElementMatcher.Junction classLoaderMatcher() { + return hasClassesNamed("application.io.opentelemetry.instrumentation.annotations.Timed"); + } + + @Override + public List typeInstrumentations() { + return asList(new TimedInstrumentation()); + } +} diff --git a/instrumentation/opentelemetry-instrumentation-annotation-timed/javaagent/src/test/java/io/opentelemetry/test/annotations/timed/TimedExample.java b/instrumentation/opentelemetry-instrumentation-annotation-timed/javaagent/src/test/java/io/opentelemetry/test/annotations/timed/TimedExample.java new file mode 100644 index 000000000000..db5ee37d0020 --- /dev/null +++ b/instrumentation/opentelemetry-instrumentation-annotation-timed/javaagent/src/test/java/io/opentelemetry/test/annotations/timed/TimedExample.java @@ -0,0 +1,61 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.test.annotations.timed; + +import io.opentelemetry.instrumentation.annotations.Timed; +import java.util.concurrent.TimeUnit; + +public class TimedExample { + public static final String ANOTHER_NAME_HISTOGRAM = "another.name.duration"; + public static final String METRIC_DESCRIPTION = "I am the description."; + public static final String RETURN_STRING = "I am a return string."; + + @Timed + public void defaultExample() {} + + @Timed(ANOTHER_NAME_HISTOGRAM) + public void exampleWithAnotherName() {} + + @Timed(description = METRIC_DESCRIPTION) + public void exampleWithDescriptionAndDefaultValue() {} + + @Timed(unit = TimeUnit.MICROSECONDS) + public void exampleWithUnitUSAndDefaultValue() {} + + @Timed(value = "example.with.description.duration", description = METRIC_DESCRIPTION) + public void exampleWithDescription() {} + + @Timed(value = "example.with.unit.duration", unit = TimeUnit.SECONDS) + public void exampleWithUnitSecondAnd2SecondLatency() throws InterruptedException { + Thread.sleep(2000); + } + + @Timed(additionalAttributes = {"key1", "value1", "key2", "value2"}) + public void exampleWithAdditionalAttributes1() {} + + @Timed(additionalAttributes = {"key1", "value1", "key2", "value2", "key3"}) + public void exampleWithAdditionalAttributes2() {} + + @Timed + public void exampleIgnore() {} + + @Timed + public void exampleWithException() { + throw new IllegalStateException("test"); + } + + @Timed(returnValueAttribute = "returnValue") + public ReturnObject exampleWithReturnValueAttribute() { + return new ReturnObject(); + } + + public static class ReturnObject { + @Override + public String toString() { + return RETURN_STRING; + } + } +} diff --git a/instrumentation/opentelemetry-instrumentation-annotation-timed/javaagent/src/test/java/io/opentelemetry/test/annotations/timed/TimedInstrumentationTest.java b/instrumentation/opentelemetry-instrumentation-annotation-timed/javaagent/src/test/java/io/opentelemetry/test/annotations/timed/TimedInstrumentationTest.java new file mode 100644 index 000000000000..7456007eca30 --- /dev/null +++ b/instrumentation/opentelemetry-instrumentation-annotation-timed/javaagent/src/test/java/io/opentelemetry/test/annotations/timed/TimedInstrumentationTest.java @@ -0,0 +1,179 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.test.annotations.timed; + +import static io.opentelemetry.test.annotations.timed.TimedExample.ANOTHER_NAME_HISTOGRAM; +import static io.opentelemetry.test.annotations.timed.TimedExample.METRIC_DESCRIPTION; +import static org.assertj.core.api.Assertions.assertThat; + +import io.opentelemetry.api.common.AttributeKey; +import io.opentelemetry.instrumentation.testing.junit.AgentInstrumentationExtension; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; + +class TimedInstrumentationTest { + + @RegisterExtension + public static final AgentInstrumentationExtension testing = + AgentInstrumentationExtension.create(); + + public static final String TIMED_DEFAULT_NAME = "method.invocation.duration"; + + public static final String TIMED_INSTRUMENTATION_NAME = + "io.opentelemetry.opentelemetry-instrumentation-annotation-timed"; + + @Test + void testDefaultExample() { + new TimedExample().defaultExample(); + testing.waitAndAssertMetrics( + TIMED_INSTRUMENTATION_NAME, metric -> metric.hasName(TIMED_DEFAULT_NAME)); + } + + @Test + void testExampleWithAnotherName() { + new TimedExample().exampleWithAnotherName(); + testing.waitAndAssertMetrics( + TIMED_INSTRUMENTATION_NAME, metric -> metric.hasName(ANOTHER_NAME_HISTOGRAM)); + } + + @Test + void testExampleWithDescriptionAndDefaultValue() { + new TimedExample().exampleWithDescriptionAndDefaultValue(); + testing.waitAndAssertMetrics( + TIMED_INSTRUMENTATION_NAME, + metric -> metric.hasName(TIMED_DEFAULT_NAME).hasDescription("")); + } + + @Test + void testExampleWithUnitUSAndDefaultValue() { + new TimedExample().exampleWithUnitUSAndDefaultValue(); + testing.waitAndAssertMetrics( + TIMED_INSTRUMENTATION_NAME, metric -> metric.hasName(TIMED_DEFAULT_NAME).hasUnit("")); + } + + @Test + void testExampleWithDescription() { + new TimedExample().exampleWithDescription(); + testing.waitAndAssertMetrics( + TIMED_INSTRUMENTATION_NAME, + metric -> + metric.hasName("example.with.description.duration").hasDescription(METRIC_DESCRIPTION)); + } + + @Test + void testExampleWithUnitSecondAnd2SecondLatency() throws InterruptedException { + new TimedExample().exampleWithUnitSecondAnd2SecondLatency(); + testing.waitAndAssertMetrics( + TIMED_INSTRUMENTATION_NAME, + metric -> + metric + .hasName("example.with.unit.duration") + .hasUnit("s") + .satisfies( + metricData -> { + assertThat(metricData.getHistogramData().getPoints()) + .allMatch(p -> p.getMax() < 5 && p.getMin() > 0); + })); + } + + @Test + void testExampleWithAdditionalAttributes1() { + new TimedExample().exampleWithAdditionalAttributes1(); + testing.waitAndAssertMetrics( + TIMED_INSTRUMENTATION_NAME, + metric -> + metric + .hasName(TIMED_DEFAULT_NAME) + .satisfies( + metricData -> { + assertThat(metricData.getData().getPoints()) + .allMatch( + p -> + "value1" + .equals( + p.getAttributes().get(AttributeKey.stringKey("key1"))) + && "value2" + .equals( + p.getAttributes() + .get(AttributeKey.stringKey("key2")))); + })); + } + + @Test + void testExampleWithAdditionalAttributes2() { + new TimedExample().exampleWithAdditionalAttributes2(); + testing.waitAndAssertMetrics( + TIMED_INSTRUMENTATION_NAME, + metric -> + metric + .hasName(TIMED_DEFAULT_NAME) + .satisfies( + metricData -> { + assertThat(metricData.getData().getPoints()) + .allMatch( + p -> + "value1" + .equals( + p.getAttributes().get(AttributeKey.stringKey("key1"))) + && "value2" + .equals( + p.getAttributes().get(AttributeKey.stringKey("key2"))) + && null + == p.getAttributes().get(AttributeKey.stringKey("key3"))); + })); + } + + @Test + void testExampleIgnore() throws Exception { + new TimedExample().exampleIgnore(); + Thread.sleep(500); + assertThat(testing.metrics()).isEmpty(); + } + + @Test + void testExampleWithException() { + try { + new TimedExample().exampleWithException(); + } catch (IllegalStateException e) { + // noop + } + testing.waitAndAssertMetrics( + TIMED_INSTRUMENTATION_NAME, + metric -> + metric + .hasName(TIMED_DEFAULT_NAME) + .satisfies( + metricData -> { + assertThat(metricData.getData().getPoints()) + .allMatch( + p -> + IllegalStateException.class + .getName() + .equals( + p.getAttributes() + .get(AttributeKey.stringKey("exception")))); + })); + } + + @Test + void testExampleWithReturnValueAttribute() { + new TimedExample().exampleWithReturnValueAttribute(); + testing.waitAndAssertMetrics( + TIMED_INSTRUMENTATION_NAME, + metric -> + metric + .hasName(TIMED_DEFAULT_NAME) + .satisfies( + metricData -> { + assertThat(metricData.getData().getPoints()) + .allMatch( + p -> + TimedExample.RETURN_STRING.equals( + p.getAttributes() + .get(AttributeKey.stringKey("returnValue")))); + })); + } +} diff --git a/settings.gradle.kts b/settings.gradle.kts index edb133b4a1f0..b09e868c7ba9 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -433,6 +433,8 @@ include(":instrumentation:opentelemetry-api:opentelemetry-api-1.37:javaagent") include(":instrumentation:opentelemetry-api:opentelemetry-api-1.38:javaagent") include(":instrumentation:opentelemetry-extension-annotations-1.0:javaagent") include(":instrumentation:opentelemetry-extension-kotlin-1.0:javaagent") +include(":instrumentation:opentelemetry-instrumentation-annotation-counted:javaagent") +include(":instrumentation:opentelemetry-instrumentation-annotation-timed:javaagent") include(":instrumentation:opentelemetry-instrumentation-annotations-1.16:javaagent") include(":instrumentation:opentelemetry-instrumentation-api:javaagent") include(":instrumentation:opentelemetry-instrumentation-api:testing") From ff05043d97372e00ab1dbc688172888aadd95071 Mon Sep 17 00:00:00 2001 From: Duncan-tree-zhou Date: Sun, 9 Jun 2024 13:29:14 +0800 Subject: [PATCH 02/21] support returnValueAttribute and exception attribtue for Timed and Counted --- .../opentelemetry-instrumentation-annotations.txt | 2 +- .../javaagent/instrumentation/timed/TimedHelper.java | 4 +--- .../instrumentation/timed/TimedInstrumentationModule.java | 2 ++ .../opentelemetry/test/annotations/timed/TimedExample.java | 4 ++-- .../test/annotations/timed/TimedInstrumentationTest.java | 6 +++--- 5 files changed, 9 insertions(+), 9 deletions(-) diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-instrumentation-annotations.txt b/docs/apidiffs/current_vs_latest/opentelemetry-instrumentation-annotations.txt index 8c4c7b6c6a37..76f15ce4c21f 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-instrumentation-annotations.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-instrumentation-annotations.txt @@ -1,4 +1,4 @@ -Comparing source compatibility of against +Comparing source compatibility of opentelemetry-instrumentation-annotations-2.5.0-SNAPSHOT.jar against opentelemetry-instrumentation-annotations-2.4.0.jar +++ NEW ANNOTATION: PUBLIC(+) ABSTRACT(+) io.opentelemetry.instrumentation.annotations.Counted (not serializable) +++ CLASS FILE FORMAT VERSION: 52.0 <- n.a. +++ NEW INTERFACE: java.lang.annotation.Annotation diff --git a/instrumentation/opentelemetry-instrumentation-annotation-timed/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/timed/TimedHelper.java b/instrumentation/opentelemetry-instrumentation-annotation-timed/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/timed/TimedHelper.java index deaa1c21b306..a93e54bb3f33 100644 --- a/instrumentation/opentelemetry-instrumentation-annotation-timed/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/timed/TimedHelper.java +++ b/instrumentation/opentelemetry-instrumentation-annotation-timed/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/timed/TimedHelper.java @@ -11,8 +11,6 @@ import application.io.opentelemetry.instrumentation.annotations.MetricAttribute; import application.io.opentelemetry.instrumentation.annotations.Timed; -// import io.opentelemetry.javaagent.instrumentation.timed.annotations.Timed; -// import io.opentelemetry.javaagent.instrumentation.timed.annotations.MetricAttribute; import io.opentelemetry.api.GlobalOpenTelemetry; import io.opentelemetry.api.common.Attributes; import io.opentelemetry.api.common.AttributesBuilder; @@ -122,7 +120,7 @@ private static DoubleHistogram getHistogram(Timed timedAnnotation) { if (!HISTOGRAMS.containsKey(metricName)) { DoubleHistogram doubleHistogram = null; if (TIMED_DEFAULT_NAME.equals(metricName)) { - doubleHistogram = METER.histogramBuilder(metricName).build(); + doubleHistogram = METER.histogramBuilder(metricName).setUnit("ms").build(); } else { String unitStr = extractUnitStr(timedAnnotation); doubleHistogram = diff --git a/instrumentation/opentelemetry-instrumentation-annotation-timed/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/timed/TimedInstrumentationModule.java b/instrumentation/opentelemetry-instrumentation-annotation-timed/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/timed/TimedInstrumentationModule.java index c8cd222d2810..f5bbb9e0ecf6 100644 --- a/instrumentation/opentelemetry-instrumentation-annotation-timed/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/timed/TimedInstrumentationModule.java +++ b/instrumentation/opentelemetry-instrumentation-annotation-timed/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/timed/TimedInstrumentationModule.java @@ -8,6 +8,8 @@ import static io.opentelemetry.javaagent.extension.matcher.AgentElementMatchers.hasClassesNamed; import static java.util.Arrays.asList; +import application.io.opentelemetry.instrumentation.annotations.MetricAttribute; +import application.io.opentelemetry.instrumentation.annotations.Timed; import com.google.auto.service.AutoService; import io.opentelemetry.javaagent.extension.instrumentation.InstrumentationModule; import io.opentelemetry.javaagent.extension.instrumentation.TypeInstrumentation; diff --git a/instrumentation/opentelemetry-instrumentation-annotation-timed/javaagent/src/test/java/io/opentelemetry/test/annotations/timed/TimedExample.java b/instrumentation/opentelemetry-instrumentation-annotation-timed/javaagent/src/test/java/io/opentelemetry/test/annotations/timed/TimedExample.java index db5ee37d0020..baa872fa1f26 100644 --- a/instrumentation/opentelemetry-instrumentation-annotation-timed/javaagent/src/test/java/io/opentelemetry/test/annotations/timed/TimedExample.java +++ b/instrumentation/opentelemetry-instrumentation-annotation-timed/javaagent/src/test/java/io/opentelemetry/test/annotations/timed/TimedExample.java @@ -22,8 +22,8 @@ public void exampleWithAnotherName() {} @Timed(description = METRIC_DESCRIPTION) public void exampleWithDescriptionAndDefaultValue() {} - @Timed(unit = TimeUnit.MICROSECONDS) - public void exampleWithUnitUSAndDefaultValue() {} + @Timed(unit = TimeUnit.NANOSECONDS) + public void exampleWithUnitNanoSecondAndDefaultValue() {} @Timed(value = "example.with.description.duration", description = METRIC_DESCRIPTION) public void exampleWithDescription() {} diff --git a/instrumentation/opentelemetry-instrumentation-annotation-timed/javaagent/src/test/java/io/opentelemetry/test/annotations/timed/TimedInstrumentationTest.java b/instrumentation/opentelemetry-instrumentation-annotation-timed/javaagent/src/test/java/io/opentelemetry/test/annotations/timed/TimedInstrumentationTest.java index 7456007eca30..f93aba564aa3 100644 --- a/instrumentation/opentelemetry-instrumentation-annotation-timed/javaagent/src/test/java/io/opentelemetry/test/annotations/timed/TimedInstrumentationTest.java +++ b/instrumentation/opentelemetry-instrumentation-annotation-timed/javaagent/src/test/java/io/opentelemetry/test/annotations/timed/TimedInstrumentationTest.java @@ -48,10 +48,10 @@ void testExampleWithDescriptionAndDefaultValue() { } @Test - void testExampleWithUnitUSAndDefaultValue() { - new TimedExample().exampleWithUnitUSAndDefaultValue(); + void testExampleWithUnitNanoSecondAndDefaultValue() { + new TimedExample().exampleWithUnitNanoSecondAndDefaultValue(); testing.waitAndAssertMetrics( - TIMED_INSTRUMENTATION_NAME, metric -> metric.hasName(TIMED_DEFAULT_NAME).hasUnit("")); + TIMED_INSTRUMENTATION_NAME, metric -> metric.hasName(TIMED_DEFAULT_NAME).hasUnit("ms")); } @Test From f5d339f87a3609c480aa325817487beab0fc33bd Mon Sep 17 00:00:00 2001 From: Lauri Tulmin Date: Mon, 10 Jun 2024 16:28:41 +0300 Subject: [PATCH 03/21] move timed and counted instrumentation into same gradle module --- .../javaagent/build.gradle.kts | 2 +- .../counted/AnnotationExcludedMethods.java | 53 ------------------- .../counted/KotlinCoroutineUtil.java | 32 ----------- .../counted/MethodRequest.java | 26 --------- .../timed/AnnotationExcludedMethods.java | 53 ------------------- .../timed/KotlinCoroutineUtil.java | 32 ----------- .../instrumentation/timed/MethodRequest.java | 26 --------- .../README.md | 0 .../javaagent/build.gradle.kts | 2 +- .../AddingSpanAttributesInstrumentation.java | 0 .../AnnotationInstrumentationModule.java | 0 .../AnnotationSingletons.java | 0 .../MethodCodeAttributesGetter.java | 0 .../MethodRequestCodeAttributesGetter.java | 0 .../WithSpanInstrumentation.java | 0 ...hSpanParameterAttributeNamesExtractor.java | 0 ...dingSpanAttributesInstrumentationTest.java | 0 ...ctAttributesUsingAddingSpanAttributes.java | 0 .../test/annotation/TracedWithSpan.java | 0 .../WithSpanInstrumentationTest.java | 0 .../javaagent/build.gradle.kts | 9 +--- .../counted/CountedHelper.java | 1 + .../counted/CountedInstrumentation.java | 4 +- .../counted/CountedInstrumentationModule.java | 2 + .../instrumentation/timed/TimedHelper.java | 3 +- .../timed/TimedInstrumentation.java | 4 +- .../timed/TimedInstrumentationModule.java | 0 .../annotations/counted/CountedExample.java | 0 .../counted/CountedInstrumentationTest.java | 0 .../test/annotations/timed/TimedExample.java | 0 .../timed/TimedInstrumentationTest.java | 0 .../javaagent/build.gradle.kts | 9 ++++ .../AnnotationExcludedMethods.java | 0 .../KotlinCoroutineUtil.java | 0 .../MethodRequest.java | 0 javaagent/build.gradle.kts | 3 +- settings.gradle.kts | 6 +-- 37 files changed, 28 insertions(+), 239 deletions(-) delete mode 100644 instrumentation/opentelemetry-instrumentation-annotation-counted/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/counted/AnnotationExcludedMethods.java delete mode 100644 instrumentation/opentelemetry-instrumentation-annotation-counted/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/counted/KotlinCoroutineUtil.java delete mode 100644 instrumentation/opentelemetry-instrumentation-annotation-counted/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/counted/MethodRequest.java delete mode 100644 instrumentation/opentelemetry-instrumentation-annotation-timed/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/timed/AnnotationExcludedMethods.java delete mode 100644 instrumentation/opentelemetry-instrumentation-annotation-timed/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/timed/KotlinCoroutineUtil.java delete mode 100644 instrumentation/opentelemetry-instrumentation-annotation-timed/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/timed/MethodRequest.java rename instrumentation/{opentelemetry-instrumentation-annotations-1.16 => opentelemetry-instrumentation-annotations}/README.md (100%) rename instrumentation/{ => opentelemetry-instrumentation-annotations}/opentelemetry-instrumentation-annotations-1.16/javaagent/build.gradle.kts (91%) rename instrumentation/{ => opentelemetry-instrumentation-annotations}/opentelemetry-instrumentation-annotations-1.16/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/AddingSpanAttributesInstrumentation.java (100%) rename instrumentation/{ => opentelemetry-instrumentation-annotations}/opentelemetry-instrumentation-annotations-1.16/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/AnnotationInstrumentationModule.java (100%) rename instrumentation/{ => opentelemetry-instrumentation-annotations}/opentelemetry-instrumentation-annotations-1.16/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/AnnotationSingletons.java (100%) rename instrumentation/{ => opentelemetry-instrumentation-annotations}/opentelemetry-instrumentation-annotations-1.16/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/MethodCodeAttributesGetter.java (100%) rename instrumentation/{ => opentelemetry-instrumentation-annotations}/opentelemetry-instrumentation-annotations-1.16/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/MethodRequestCodeAttributesGetter.java (100%) rename instrumentation/{ => opentelemetry-instrumentation-annotations}/opentelemetry-instrumentation-annotations-1.16/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/WithSpanInstrumentation.java (100%) rename instrumentation/{ => opentelemetry-instrumentation-annotations}/opentelemetry-instrumentation-annotations-1.16/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/WithSpanParameterAttributeNamesExtractor.java (100%) rename instrumentation/{ => opentelemetry-instrumentation-annotations}/opentelemetry-instrumentation-annotations-1.16/javaagent/src/test/java/io/opentelemetry/test/annotation/AddingSpanAttributesInstrumentationTest.java (100%) rename instrumentation/{ => opentelemetry-instrumentation-annotations}/opentelemetry-instrumentation-annotations-1.16/javaagent/src/test/java/io/opentelemetry/test/annotation/ExtractAttributesUsingAddingSpanAttributes.java (100%) rename instrumentation/{ => opentelemetry-instrumentation-annotations}/opentelemetry-instrumentation-annotations-1.16/javaagent/src/test/java/io/opentelemetry/test/annotation/TracedWithSpan.java (100%) rename instrumentation/{ => opentelemetry-instrumentation-annotations}/opentelemetry-instrumentation-annotations-1.16/javaagent/src/test/java/io/opentelemetry/test/annotation/WithSpanInstrumentationTest.java (100%) rename instrumentation/{opentelemetry-instrumentation-annotation-counted => opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-2.6}/javaagent/build.gradle.kts (78%) rename instrumentation/{opentelemetry-instrumentation-annotation-counted => opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-2.6}/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/counted/CountedHelper.java (98%) rename instrumentation/{opentelemetry-instrumentation-annotation-counted => opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-2.6}/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/counted/CountedInstrumentation.java (94%) rename instrumentation/{opentelemetry-instrumentation-annotation-counted => opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-2.6}/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/counted/CountedInstrumentationModule.java (90%) rename instrumentation/{opentelemetry-instrumentation-annotation-timed => opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-2.6}/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/timed/TimedHelper.java (98%) rename instrumentation/{opentelemetry-instrumentation-annotation-timed => opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-2.6}/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/timed/TimedInstrumentation.java (94%) rename instrumentation/{opentelemetry-instrumentation-annotation-timed => opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-2.6}/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/timed/TimedInstrumentationModule.java (100%) rename instrumentation/{opentelemetry-instrumentation-annotation-counted => opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-2.6}/javaagent/src/test/java/io/opentelemetry/test/annotations/counted/CountedExample.java (100%) rename instrumentation/{opentelemetry-instrumentation-annotation-counted => opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-2.6}/javaagent/src/test/java/io/opentelemetry/test/annotations/counted/CountedInstrumentationTest.java (100%) rename instrumentation/{opentelemetry-instrumentation-annotation-timed => opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-2.6}/javaagent/src/test/java/io/opentelemetry/test/annotations/timed/TimedExample.java (100%) rename instrumentation/{opentelemetry-instrumentation-annotation-timed => opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-2.6}/javaagent/src/test/java/io/opentelemetry/test/annotations/timed/TimedInstrumentationTest.java (100%) create mode 100644 instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-common/javaagent/build.gradle.kts rename instrumentation/{opentelemetry-instrumentation-annotations-1.16 => opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-common}/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/AnnotationExcludedMethods.java (100%) rename instrumentation/{opentelemetry-instrumentation-annotations-1.16 => opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-common}/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/KotlinCoroutineUtil.java (100%) rename instrumentation/{opentelemetry-instrumentation-annotations-1.16 => opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-common}/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/MethodRequest.java (100%) diff --git a/instrumentation/kotlinx-coroutines/kotlinx-coroutines-1.0/javaagent/build.gradle.kts b/instrumentation/kotlinx-coroutines/kotlinx-coroutines-1.0/javaagent/build.gradle.kts index 3e1be05c41ff..8d937d750112 100644 --- a/instrumentation/kotlinx-coroutines/kotlinx-coroutines-1.0/javaagent/build.gradle.kts +++ b/instrumentation/kotlinx-coroutines/kotlinx-coroutines-1.0/javaagent/build.gradle.kts @@ -30,7 +30,7 @@ dependencies { implementation("org.ow2.asm:asm-tree") implementation("org.ow2.asm:asm-util") - implementation(project(":instrumentation:opentelemetry-instrumentation-annotations-1.16:javaagent")) + implementation(project(":instrumentation:opentelemetry-instrumentation-annotations:opentelemetry-instrumentation-annotations-common:javaagent")) testInstrumentation(project(":instrumentation:opentelemetry-extension-kotlin-1.0:javaagent")) testInstrumentation(project(":instrumentation:reactor:reactor-3.1:javaagent")) diff --git a/instrumentation/opentelemetry-instrumentation-annotation-counted/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/counted/AnnotationExcludedMethods.java b/instrumentation/opentelemetry-instrumentation-annotation-counted/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/counted/AnnotationExcludedMethods.java deleted file mode 100644 index c5496df8cf4a..000000000000 --- a/instrumentation/opentelemetry-instrumentation-annotation-counted/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/counted/AnnotationExcludedMethods.java +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -package io.opentelemetry.javaagent.instrumentation.counted; - -import static net.bytebuddy.matcher.ElementMatchers.isDeclaredBy; -import static net.bytebuddy.matcher.ElementMatchers.namedOneOf; -import static net.bytebuddy.matcher.ElementMatchers.none; - -import io.opentelemetry.javaagent.bootstrap.internal.InstrumentationConfig; -import io.opentelemetry.javaagent.tooling.config.MethodsConfigurationParser; -import java.util.Map; -import java.util.Set; -import net.bytebuddy.description.ByteCodeElement; -import net.bytebuddy.description.method.MethodDescription; -import net.bytebuddy.matcher.ElementMatcher; -import net.bytebuddy.matcher.ElementMatchers; - -public final class AnnotationExcludedMethods { - - private static final String COUNTED_METHODS_EXCLUDE_CONFIG = - "otel.instrumentation.opentelemetry-instrumentation-annotation-counted.exclude-methods"; - - /* - Returns a matcher for all methods that should be excluded from auto-instrumentation by - annotation-based advices. - */ - public static ElementMatcher.Junction configureExcludedMethods() { - ElementMatcher.Junction result = none(); - - Map> excludedMethods = - MethodsConfigurationParser.parse( - InstrumentationConfig.get().getString(COUNTED_METHODS_EXCLUDE_CONFIG)); - for (Map.Entry> entry : excludedMethods.entrySet()) { - String className = entry.getKey(); - ElementMatcher.Junction matcher = - isDeclaredBy(ElementMatchers.named(className)); - - Set methodNames = entry.getValue(); - if (!methodNames.isEmpty()) { - matcher = matcher.and(namedOneOf(methodNames.toArray(new String[0]))); - } - - result = result.or(matcher); - } - - return result; - } - - private AnnotationExcludedMethods() {} -} diff --git a/instrumentation/opentelemetry-instrumentation-annotation-counted/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/counted/KotlinCoroutineUtil.java b/instrumentation/opentelemetry-instrumentation-annotation-counted/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/counted/KotlinCoroutineUtil.java deleted file mode 100644 index 557cc436498f..000000000000 --- a/instrumentation/opentelemetry-instrumentation-annotation-counted/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/counted/KotlinCoroutineUtil.java +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -package io.opentelemetry.javaagent.instrumentation.counted; - -import static net.bytebuddy.matcher.ElementMatchers.returns; - -import net.bytebuddy.description.method.MethodDescription; -import net.bytebuddy.description.method.ParameterList; -import net.bytebuddy.matcher.ElementMatcher; - -public final class KotlinCoroutineUtil { - - private KotlinCoroutineUtil() {} - - public static ElementMatcher isKotlinSuspendMethod() { - // kotlin suspend methods return Object and take kotlin.coroutines.Continuation as last argument - return returns(Object.class) - .and( - target -> { - ParameterList parameterList = target.getParameters(); - if (!parameterList.isEmpty()) { - String lastParameter = - parameterList.get(parameterList.size() - 1).getType().asErasure().getName(); - return "kotlin.coroutines.Continuation".equals(lastParameter); - } - return false; - }); - } -} diff --git a/instrumentation/opentelemetry-instrumentation-annotation-counted/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/counted/MethodRequest.java b/instrumentation/opentelemetry-instrumentation-annotation-counted/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/counted/MethodRequest.java deleted file mode 100644 index 8c151492d882..000000000000 --- a/instrumentation/opentelemetry-instrumentation-annotation-counted/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/counted/MethodRequest.java +++ /dev/null @@ -1,26 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -package io.opentelemetry.javaagent.instrumentation.counted; - -import java.lang.reflect.Method; - -public final class MethodRequest { - private final Method method; - private final Object[] args; - - public MethodRequest(Method method, Object[] args) { - this.method = method; - this.args = args; - } - - public Method method() { - return this.method; - } - - public Object[] args() { - return this.args; - } -} diff --git a/instrumentation/opentelemetry-instrumentation-annotation-timed/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/timed/AnnotationExcludedMethods.java b/instrumentation/opentelemetry-instrumentation-annotation-timed/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/timed/AnnotationExcludedMethods.java deleted file mode 100644 index ea14c24f8aa0..000000000000 --- a/instrumentation/opentelemetry-instrumentation-annotation-timed/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/timed/AnnotationExcludedMethods.java +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -package io.opentelemetry.javaagent.instrumentation.timed; - -import static net.bytebuddy.matcher.ElementMatchers.isDeclaredBy; -import static net.bytebuddy.matcher.ElementMatchers.namedOneOf; -import static net.bytebuddy.matcher.ElementMatchers.none; - -import io.opentelemetry.javaagent.bootstrap.internal.InstrumentationConfig; -import io.opentelemetry.javaagent.tooling.config.MethodsConfigurationParser; -import java.util.Map; -import java.util.Set; -import net.bytebuddy.description.ByteCodeElement; -import net.bytebuddy.description.method.MethodDescription; -import net.bytebuddy.matcher.ElementMatcher; -import net.bytebuddy.matcher.ElementMatchers; - -public final class AnnotationExcludedMethods { - - private static final String TIMED_METHODS_EXCLUDE_CONFIG = - "otel.instrumentation.opentelemetry-instrumentation-annotation-timed.exclude-methods"; - - /* - Returns a matcher for all methods that should be excluded from auto-instrumentation by - annotation-based advices. - */ - public static ElementMatcher.Junction configureExcludedMethods() { - ElementMatcher.Junction result = none(); - - Map> excludedMethods = - MethodsConfigurationParser.parse( - InstrumentationConfig.get().getString(TIMED_METHODS_EXCLUDE_CONFIG)); - for (Map.Entry> entry : excludedMethods.entrySet()) { - String className = entry.getKey(); - ElementMatcher.Junction matcher = - isDeclaredBy(ElementMatchers.named(className)); - - Set methodNames = entry.getValue(); - if (!methodNames.isEmpty()) { - matcher = matcher.and(namedOneOf(methodNames.toArray(new String[0]))); - } - - result = result.or(matcher); - } - - return result; - } - - private AnnotationExcludedMethods() {} -} diff --git a/instrumentation/opentelemetry-instrumentation-annotation-timed/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/timed/KotlinCoroutineUtil.java b/instrumentation/opentelemetry-instrumentation-annotation-timed/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/timed/KotlinCoroutineUtil.java deleted file mode 100644 index c0e0e6c31379..000000000000 --- a/instrumentation/opentelemetry-instrumentation-annotation-timed/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/timed/KotlinCoroutineUtil.java +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -package io.opentelemetry.javaagent.instrumentation.timed; - -import static net.bytebuddy.matcher.ElementMatchers.returns; - -import net.bytebuddy.description.method.MethodDescription; -import net.bytebuddy.description.method.ParameterList; -import net.bytebuddy.matcher.ElementMatcher; - -public final class KotlinCoroutineUtil { - - private KotlinCoroutineUtil() {} - - public static ElementMatcher isKotlinSuspendMethod() { - // kotlin suspend methods return Object and take kotlin.coroutines.Continuation as last argument - return returns(Object.class) - .and( - target -> { - ParameterList parameterList = target.getParameters(); - if (!parameterList.isEmpty()) { - String lastParameter = - parameterList.get(parameterList.size() - 1).getType().asErasure().getName(); - return "kotlin.coroutines.Continuation".equals(lastParameter); - } - return false; - }); - } -} diff --git a/instrumentation/opentelemetry-instrumentation-annotation-timed/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/timed/MethodRequest.java b/instrumentation/opentelemetry-instrumentation-annotation-timed/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/timed/MethodRequest.java deleted file mode 100644 index 352e65d06611..000000000000 --- a/instrumentation/opentelemetry-instrumentation-annotation-timed/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/timed/MethodRequest.java +++ /dev/null @@ -1,26 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -package io.opentelemetry.javaagent.instrumentation.timed; - -import java.lang.reflect.Method; - -public final class MethodRequest { - private final Method method; - private final Object[] args; - - public MethodRequest(Method method, Object[] args) { - this.method = method; - this.args = args; - } - - public Method method() { - return this.method; - } - - public Object[] args() { - return this.args; - } -} diff --git a/instrumentation/opentelemetry-instrumentation-annotations-1.16/README.md b/instrumentation/opentelemetry-instrumentation-annotations/README.md similarity index 100% rename from instrumentation/opentelemetry-instrumentation-annotations-1.16/README.md rename to instrumentation/opentelemetry-instrumentation-annotations/README.md diff --git a/instrumentation/opentelemetry-instrumentation-annotations-1.16/javaagent/build.gradle.kts b/instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-1.16/javaagent/build.gradle.kts similarity index 91% rename from instrumentation/opentelemetry-instrumentation-annotations-1.16/javaagent/build.gradle.kts rename to instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-1.16/javaagent/build.gradle.kts index 6ea1548e4354..e9f6b111a94c 100644 --- a/instrumentation/opentelemetry-instrumentation-annotations-1.16/javaagent/build.gradle.kts +++ b/instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-1.16/javaagent/build.gradle.kts @@ -16,8 +16,8 @@ muzzle { dependencies { compileOnly(project(":instrumentation-annotations-support")) - compileOnly(project(":javaagent-tooling")) + implementation(project(":instrumentation:opentelemetry-instrumentation-annotations:opentelemetry-instrumentation-annotations-common:javaagent")) // this instrumentation needs to do similar shading dance as opentelemetry-api-1.0 because // the @WithSpan annotation references the OpenTelemetry API's SpanKind class diff --git a/instrumentation/opentelemetry-instrumentation-annotations-1.16/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/AddingSpanAttributesInstrumentation.java b/instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-1.16/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/AddingSpanAttributesInstrumentation.java similarity index 100% rename from instrumentation/opentelemetry-instrumentation-annotations-1.16/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/AddingSpanAttributesInstrumentation.java rename to instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-1.16/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/AddingSpanAttributesInstrumentation.java diff --git a/instrumentation/opentelemetry-instrumentation-annotations-1.16/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/AnnotationInstrumentationModule.java b/instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-1.16/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/AnnotationInstrumentationModule.java similarity index 100% rename from instrumentation/opentelemetry-instrumentation-annotations-1.16/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/AnnotationInstrumentationModule.java rename to instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-1.16/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/AnnotationInstrumentationModule.java diff --git a/instrumentation/opentelemetry-instrumentation-annotations-1.16/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/AnnotationSingletons.java b/instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-1.16/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/AnnotationSingletons.java similarity index 100% rename from instrumentation/opentelemetry-instrumentation-annotations-1.16/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/AnnotationSingletons.java rename to instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-1.16/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/AnnotationSingletons.java diff --git a/instrumentation/opentelemetry-instrumentation-annotations-1.16/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/MethodCodeAttributesGetter.java b/instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-1.16/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/MethodCodeAttributesGetter.java similarity index 100% rename from instrumentation/opentelemetry-instrumentation-annotations-1.16/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/MethodCodeAttributesGetter.java rename to instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-1.16/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/MethodCodeAttributesGetter.java diff --git a/instrumentation/opentelemetry-instrumentation-annotations-1.16/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/MethodRequestCodeAttributesGetter.java b/instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-1.16/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/MethodRequestCodeAttributesGetter.java similarity index 100% rename from instrumentation/opentelemetry-instrumentation-annotations-1.16/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/MethodRequestCodeAttributesGetter.java rename to instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-1.16/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/MethodRequestCodeAttributesGetter.java diff --git a/instrumentation/opentelemetry-instrumentation-annotations-1.16/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/WithSpanInstrumentation.java b/instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-1.16/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/WithSpanInstrumentation.java similarity index 100% rename from instrumentation/opentelemetry-instrumentation-annotations-1.16/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/WithSpanInstrumentation.java rename to instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-1.16/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/WithSpanInstrumentation.java diff --git a/instrumentation/opentelemetry-instrumentation-annotations-1.16/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/WithSpanParameterAttributeNamesExtractor.java b/instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-1.16/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/WithSpanParameterAttributeNamesExtractor.java similarity index 100% rename from instrumentation/opentelemetry-instrumentation-annotations-1.16/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/WithSpanParameterAttributeNamesExtractor.java rename to instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-1.16/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/WithSpanParameterAttributeNamesExtractor.java diff --git a/instrumentation/opentelemetry-instrumentation-annotations-1.16/javaagent/src/test/java/io/opentelemetry/test/annotation/AddingSpanAttributesInstrumentationTest.java b/instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-1.16/javaagent/src/test/java/io/opentelemetry/test/annotation/AddingSpanAttributesInstrumentationTest.java similarity index 100% rename from instrumentation/opentelemetry-instrumentation-annotations-1.16/javaagent/src/test/java/io/opentelemetry/test/annotation/AddingSpanAttributesInstrumentationTest.java rename to instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-1.16/javaagent/src/test/java/io/opentelemetry/test/annotation/AddingSpanAttributesInstrumentationTest.java diff --git a/instrumentation/opentelemetry-instrumentation-annotations-1.16/javaagent/src/test/java/io/opentelemetry/test/annotation/ExtractAttributesUsingAddingSpanAttributes.java b/instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-1.16/javaagent/src/test/java/io/opentelemetry/test/annotation/ExtractAttributesUsingAddingSpanAttributes.java similarity index 100% rename from instrumentation/opentelemetry-instrumentation-annotations-1.16/javaagent/src/test/java/io/opentelemetry/test/annotation/ExtractAttributesUsingAddingSpanAttributes.java rename to instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-1.16/javaagent/src/test/java/io/opentelemetry/test/annotation/ExtractAttributesUsingAddingSpanAttributes.java diff --git a/instrumentation/opentelemetry-instrumentation-annotations-1.16/javaagent/src/test/java/io/opentelemetry/test/annotation/TracedWithSpan.java b/instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-1.16/javaagent/src/test/java/io/opentelemetry/test/annotation/TracedWithSpan.java similarity index 100% rename from instrumentation/opentelemetry-instrumentation-annotations-1.16/javaagent/src/test/java/io/opentelemetry/test/annotation/TracedWithSpan.java rename to instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-1.16/javaagent/src/test/java/io/opentelemetry/test/annotation/TracedWithSpan.java diff --git a/instrumentation/opentelemetry-instrumentation-annotations-1.16/javaagent/src/test/java/io/opentelemetry/test/annotation/WithSpanInstrumentationTest.java b/instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-1.16/javaagent/src/test/java/io/opentelemetry/test/annotation/WithSpanInstrumentationTest.java similarity index 100% rename from instrumentation/opentelemetry-instrumentation-annotations-1.16/javaagent/src/test/java/io/opentelemetry/test/annotation/WithSpanInstrumentationTest.java rename to instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-1.16/javaagent/src/test/java/io/opentelemetry/test/annotation/WithSpanInstrumentationTest.java diff --git a/instrumentation/opentelemetry-instrumentation-annotation-counted/javaagent/build.gradle.kts b/instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-2.6/javaagent/build.gradle.kts similarity index 78% rename from instrumentation/opentelemetry-instrumentation-annotation-counted/javaagent/build.gradle.kts rename to instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-2.6/javaagent/build.gradle.kts index e20c13308be6..cca08e10ea34 100644 --- a/instrumentation/opentelemetry-instrumentation-annotation-counted/javaagent/build.gradle.kts +++ b/instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-2.6/javaagent/build.gradle.kts @@ -16,8 +16,8 @@ muzzle { dependencies { compileOnly(project(":instrumentation-annotations-support")) - compileOnly(project(":javaagent-tooling")) + implementation(project(":instrumentation:opentelemetry-instrumentation-annotations:opentelemetry-instrumentation-annotations-common:javaagent")) // this instrumentation needs to do similar shading dance as opentelemetry-api-1.0 because // the @WithSpan annotation references the OpenTelemetry API's SpanKind class @@ -25,13 +25,8 @@ dependencies { // see the comment in opentelemetry-api-1.0.gradle for more details compileOnly(project(":opentelemetry-instrumentation-annotations-shaded-for-instrumenting", configuration = "shadow")) - // Used by byte-buddy but not brought in as a transitive dependency. - compileOnly("com.google.code.findbugs:annotations") - testCompileOnly("com.google.code.findbugs:annotations") - testImplementation(project(":instrumentation-annotations")) testImplementation(project(":instrumentation-annotations-support")) - testImplementation("net.bytebuddy:byte-buddy") } tasks { @@ -40,7 +35,7 @@ tasks { } test { jvmArgs( - "-Dotel.instrumentation.opentelemetry-instrumentation-annotation-counted.exclude-methods=io.opentelemetry.test.annotations.counted.CountedExample[exampleIgnore]" + "-Dotel.instrumentation.opentelemetry-instrumentation-annotations.exclude-methods=io.opentelemetry.test.annotations.counted.CountedExample[exampleIgnore];io.opentelemetry.test.annotations.timed.TimedExample[exampleIgnore]" ) } } diff --git a/instrumentation/opentelemetry-instrumentation-annotation-counted/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/counted/CountedHelper.java b/instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-2.6/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/counted/CountedHelper.java similarity index 98% rename from instrumentation/opentelemetry-instrumentation-annotation-counted/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/counted/CountedHelper.java rename to instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-2.6/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/counted/CountedHelper.java index 62c1172ea7e4..127773f92e55 100644 --- a/instrumentation/opentelemetry-instrumentation-annotation-counted/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/counted/CountedHelper.java +++ b/instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-2.6/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/counted/CountedHelper.java @@ -13,6 +13,7 @@ import io.opentelemetry.api.internal.StringUtils; import io.opentelemetry.api.metrics.LongCounter; import io.opentelemetry.api.metrics.Meter; +import io.opentelemetry.javaagent.instrumentation.instrumentationannotations.MethodRequest; import java.lang.reflect.Method; import java.lang.reflect.Parameter; import java.util.concurrent.ConcurrentHashMap; diff --git a/instrumentation/opentelemetry-instrumentation-annotation-counted/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/counted/CountedInstrumentation.java b/instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-2.6/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/counted/CountedInstrumentation.java similarity index 94% rename from instrumentation/opentelemetry-instrumentation-annotation-counted/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/counted/CountedInstrumentation.java rename to instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-2.6/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/counted/CountedInstrumentation.java index d8ef1a889539..f0b5c726902d 100644 --- a/instrumentation/opentelemetry-instrumentation-annotation-counted/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/counted/CountedInstrumentation.java +++ b/instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-2.6/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/counted/CountedInstrumentation.java @@ -5,7 +5,7 @@ package io.opentelemetry.javaagent.instrumentation.counted; -import static io.opentelemetry.javaagent.instrumentation.counted.KotlinCoroutineUtil.isKotlinSuspendMethod; +import static io.opentelemetry.javaagent.instrumentation.instrumentationannotations.KotlinCoroutineUtil.isKotlinSuspendMethod; import static net.bytebuddy.matcher.ElementMatchers.declaresMethod; import static net.bytebuddy.matcher.ElementMatchers.hasParameters; import static net.bytebuddy.matcher.ElementMatchers.isAnnotatedWith; @@ -15,6 +15,8 @@ import io.opentelemetry.javaagent.extension.instrumentation.TypeInstrumentation; import io.opentelemetry.javaagent.extension.instrumentation.TypeTransformer; +import io.opentelemetry.javaagent.instrumentation.instrumentationannotations.AnnotationExcludedMethods; +import io.opentelemetry.javaagent.instrumentation.instrumentationannotations.MethodRequest; import java.lang.reflect.Method; import net.bytebuddy.asm.Advice; import net.bytebuddy.description.annotation.AnnotationSource; diff --git a/instrumentation/opentelemetry-instrumentation-annotation-counted/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/counted/CountedInstrumentationModule.java b/instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-2.6/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/counted/CountedInstrumentationModule.java similarity index 90% rename from instrumentation/opentelemetry-instrumentation-annotation-counted/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/counted/CountedInstrumentationModule.java rename to instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-2.6/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/counted/CountedInstrumentationModule.java index c61f13f3bbca..3617dcc2c322 100644 --- a/instrumentation/opentelemetry-instrumentation-annotation-counted/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/counted/CountedInstrumentationModule.java +++ b/instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-2.6/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/counted/CountedInstrumentationModule.java @@ -8,6 +8,8 @@ import static io.opentelemetry.javaagent.extension.matcher.AgentElementMatchers.hasClassesNamed; import static java.util.Arrays.asList; +import application.io.opentelemetry.instrumentation.annotations.Counted; +import application.io.opentelemetry.instrumentation.annotations.MetricAttribute; import com.google.auto.service.AutoService; import io.opentelemetry.javaagent.extension.instrumentation.InstrumentationModule; import io.opentelemetry.javaagent.extension.instrumentation.TypeInstrumentation; diff --git a/instrumentation/opentelemetry-instrumentation-annotation-timed/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/timed/TimedHelper.java b/instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-2.6/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/timed/TimedHelper.java similarity index 98% rename from instrumentation/opentelemetry-instrumentation-annotation-timed/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/timed/TimedHelper.java rename to instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-2.6/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/timed/TimedHelper.java index a93e54bb3f33..4b21ff189bbe 100644 --- a/instrumentation/opentelemetry-instrumentation-annotation-timed/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/timed/TimedHelper.java +++ b/instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-2.6/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/timed/TimedHelper.java @@ -5,9 +5,7 @@ package io.opentelemetry.javaagent.instrumentation.timed; -import static java.util.concurrent.TimeUnit.MICROSECONDS; import static java.util.concurrent.TimeUnit.NANOSECONDS; -import static java.util.concurrent.TimeUnit.SECONDS; import application.io.opentelemetry.instrumentation.annotations.MetricAttribute; import application.io.opentelemetry.instrumentation.annotations.Timed; @@ -17,6 +15,7 @@ import io.opentelemetry.api.internal.StringUtils; import io.opentelemetry.api.metrics.DoubleHistogram; import io.opentelemetry.api.metrics.Meter; +import io.opentelemetry.javaagent.instrumentation.instrumentationannotations.MethodRequest; import java.lang.reflect.Method; import java.lang.reflect.Parameter; import java.util.concurrent.ConcurrentHashMap; diff --git a/instrumentation/opentelemetry-instrumentation-annotation-timed/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/timed/TimedInstrumentation.java b/instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-2.6/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/timed/TimedInstrumentation.java similarity index 94% rename from instrumentation/opentelemetry-instrumentation-annotation-timed/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/timed/TimedInstrumentation.java rename to instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-2.6/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/timed/TimedInstrumentation.java index af92a66287c7..b5b21ff304c8 100644 --- a/instrumentation/opentelemetry-instrumentation-annotation-timed/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/timed/TimedInstrumentation.java +++ b/instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-2.6/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/timed/TimedInstrumentation.java @@ -5,7 +5,7 @@ package io.opentelemetry.javaagent.instrumentation.timed; -import static io.opentelemetry.javaagent.instrumentation.timed.KotlinCoroutineUtil.isKotlinSuspendMethod; +import static io.opentelemetry.javaagent.instrumentation.instrumentationannotations.KotlinCoroutineUtil.isKotlinSuspendMethod; import static net.bytebuddy.matcher.ElementMatchers.declaresMethod; import static net.bytebuddy.matcher.ElementMatchers.hasParameters; import static net.bytebuddy.matcher.ElementMatchers.isAnnotatedWith; @@ -15,6 +15,8 @@ import io.opentelemetry.javaagent.extension.instrumentation.TypeInstrumentation; import io.opentelemetry.javaagent.extension.instrumentation.TypeTransformer; +import io.opentelemetry.javaagent.instrumentation.instrumentationannotations.AnnotationExcludedMethods; +import io.opentelemetry.javaagent.instrumentation.instrumentationannotations.MethodRequest; import java.lang.reflect.Method; import net.bytebuddy.asm.Advice; import net.bytebuddy.description.annotation.AnnotationSource; diff --git a/instrumentation/opentelemetry-instrumentation-annotation-timed/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/timed/TimedInstrumentationModule.java b/instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-2.6/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/timed/TimedInstrumentationModule.java similarity index 100% rename from instrumentation/opentelemetry-instrumentation-annotation-timed/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/timed/TimedInstrumentationModule.java rename to instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-2.6/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/timed/TimedInstrumentationModule.java diff --git a/instrumentation/opentelemetry-instrumentation-annotation-counted/javaagent/src/test/java/io/opentelemetry/test/annotations/counted/CountedExample.java b/instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-2.6/javaagent/src/test/java/io/opentelemetry/test/annotations/counted/CountedExample.java similarity index 100% rename from instrumentation/opentelemetry-instrumentation-annotation-counted/javaagent/src/test/java/io/opentelemetry/test/annotations/counted/CountedExample.java rename to instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-2.6/javaagent/src/test/java/io/opentelemetry/test/annotations/counted/CountedExample.java diff --git a/instrumentation/opentelemetry-instrumentation-annotation-counted/javaagent/src/test/java/io/opentelemetry/test/annotations/counted/CountedInstrumentationTest.java b/instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-2.6/javaagent/src/test/java/io/opentelemetry/test/annotations/counted/CountedInstrumentationTest.java similarity index 100% rename from instrumentation/opentelemetry-instrumentation-annotation-counted/javaagent/src/test/java/io/opentelemetry/test/annotations/counted/CountedInstrumentationTest.java rename to instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-2.6/javaagent/src/test/java/io/opentelemetry/test/annotations/counted/CountedInstrumentationTest.java diff --git a/instrumentation/opentelemetry-instrumentation-annotation-timed/javaagent/src/test/java/io/opentelemetry/test/annotations/timed/TimedExample.java b/instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-2.6/javaagent/src/test/java/io/opentelemetry/test/annotations/timed/TimedExample.java similarity index 100% rename from instrumentation/opentelemetry-instrumentation-annotation-timed/javaagent/src/test/java/io/opentelemetry/test/annotations/timed/TimedExample.java rename to instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-2.6/javaagent/src/test/java/io/opentelemetry/test/annotations/timed/TimedExample.java diff --git a/instrumentation/opentelemetry-instrumentation-annotation-timed/javaagent/src/test/java/io/opentelemetry/test/annotations/timed/TimedInstrumentationTest.java b/instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-2.6/javaagent/src/test/java/io/opentelemetry/test/annotations/timed/TimedInstrumentationTest.java similarity index 100% rename from instrumentation/opentelemetry-instrumentation-annotation-timed/javaagent/src/test/java/io/opentelemetry/test/annotations/timed/TimedInstrumentationTest.java rename to instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-2.6/javaagent/src/test/java/io/opentelemetry/test/annotations/timed/TimedInstrumentationTest.java diff --git a/instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-common/javaagent/build.gradle.kts b/instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-common/javaagent/build.gradle.kts new file mode 100644 index 000000000000..8c365ac278a8 --- /dev/null +++ b/instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-common/javaagent/build.gradle.kts @@ -0,0 +1,9 @@ +plugins { + id("otel.javaagent-instrumentation") +} + +dependencies { + compileOnly(project(":instrumentation-annotations-support")) + + compileOnly(project(":javaagent-tooling")) +} diff --git a/instrumentation/opentelemetry-instrumentation-annotations-1.16/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/AnnotationExcludedMethods.java b/instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/AnnotationExcludedMethods.java similarity index 100% rename from instrumentation/opentelemetry-instrumentation-annotations-1.16/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/AnnotationExcludedMethods.java rename to instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/AnnotationExcludedMethods.java diff --git a/instrumentation/opentelemetry-instrumentation-annotations-1.16/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/KotlinCoroutineUtil.java b/instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/KotlinCoroutineUtil.java similarity index 100% rename from instrumentation/opentelemetry-instrumentation-annotations-1.16/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/KotlinCoroutineUtil.java rename to instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/KotlinCoroutineUtil.java diff --git a/instrumentation/opentelemetry-instrumentation-annotations-1.16/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/MethodRequest.java b/instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/MethodRequest.java similarity index 100% rename from instrumentation/opentelemetry-instrumentation-annotations-1.16/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/MethodRequest.java rename to instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/MethodRequest.java diff --git a/javaagent/build.gradle.kts b/javaagent/build.gradle.kts index 89df36ddc9d6..f827214b1a5c 100644 --- a/javaagent/build.gradle.kts +++ b/javaagent/build.gradle.kts @@ -75,7 +75,8 @@ dependencies { baseJavaagentLibs(project(":instrumentation:opentelemetry-api:opentelemetry-api-1.0:javaagent")) baseJavaagentLibs(project(":instrumentation:opentelemetry-api:opentelemetry-api-1.4:javaagent")) baseJavaagentLibs(project(":instrumentation:opentelemetry-instrumentation-api:javaagent")) - baseJavaagentLibs(project(":instrumentation:opentelemetry-instrumentation-annotations-1.16:javaagent")) + baseJavaagentLibs(project(":instrumentation:opentelemetry-instrumentation-annotations:opentelemetry-instrumentation-annotations-1.16:javaagent")) + baseJavaagentLibs(project(":instrumentation:opentelemetry-instrumentation-annotations:opentelemetry-instrumentation-annotations-2.6:javaagent")) baseJavaagentLibs(project(":instrumentation:executors:javaagent")) baseJavaagentLibs(project(":instrumentation:internal:internal-application-logger:javaagent")) baseJavaagentLibs(project(":instrumentation:internal:internal-class-loader:javaagent")) diff --git a/settings.gradle.kts b/settings.gradle.kts index b09e868c7ba9..b5f394f3e0f7 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -433,9 +433,9 @@ include(":instrumentation:opentelemetry-api:opentelemetry-api-1.37:javaagent") include(":instrumentation:opentelemetry-api:opentelemetry-api-1.38:javaagent") include(":instrumentation:opentelemetry-extension-annotations-1.0:javaagent") include(":instrumentation:opentelemetry-extension-kotlin-1.0:javaagent") -include(":instrumentation:opentelemetry-instrumentation-annotation-counted:javaagent") -include(":instrumentation:opentelemetry-instrumentation-annotation-timed:javaagent") -include(":instrumentation:opentelemetry-instrumentation-annotations-1.16:javaagent") +include(":instrumentation:opentelemetry-instrumentation-annotations:opentelemetry-instrumentation-annotations-1.16:javaagent") +include(":instrumentation:opentelemetry-instrumentation-annotations:opentelemetry-instrumentation-annotations-2.6:javaagent") +include(":instrumentation:opentelemetry-instrumentation-annotations:opentelemetry-instrumentation-annotations-common:javaagent") include(":instrumentation:opentelemetry-instrumentation-api:javaagent") include(":instrumentation:opentelemetry-instrumentation-api:testing") include(":instrumentation:oracle-ucp-11.2:javaagent") From 22d6c4389a4e9850e7631bf94334a10c4e8f0077 Mon Sep 17 00:00:00 2001 From: Lauri Tulmin Date: Mon, 10 Jun 2024 17:05:39 +0300 Subject: [PATCH 04/21] Use a single instrumentation module for counted and timed instrumentation --- .../README.md | 5 -- .../README.md | 5 -- .../javaagent/build.gradle.kts | 46 ------------------- .../javaagent/build.gradle.kts | 2 +- .../v2_6}/CountedHelper.java | 39 +--------------- .../v2_6}/CountedInstrumentation.java | 2 +- .../v2_6/MetricsAnnotationHelper.java | 46 +++++++++++++++++++ ...tricsAnnotationInstrumentationModule.java} | 15 +++--- .../v2_6}/TimedHelper.java | 40 +--------------- .../v2_6}/TimedInstrumentation.java | 2 +- .../timed/TimedInstrumentationModule.java | 45 ------------------ .../v2_6}/counted/CountedExample.java | 2 +- .../counted/CountedInstrumentationTest.java | 15 +++--- .../v2_6}/timed/TimedExample.java | 2 +- .../v2_6}/timed/TimedInstrumentationTest.java | 13 +++--- 15 files changed, 76 insertions(+), 203 deletions(-) delete mode 100644 instrumentation/opentelemetry-instrumentation-annotation-counted/README.md delete mode 100644 instrumentation/opentelemetry-instrumentation-annotation-timed/README.md delete mode 100644 instrumentation/opentelemetry-instrumentation-annotation-timed/javaagent/build.gradle.kts rename instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-2.6/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/{counted => instrumentationannotations/v2_6}/CountedHelper.java (68%) rename instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-2.6/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/{counted => instrumentationannotations/v2_6}/CountedInstrumentation.java (98%) create mode 100644 instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-2.6/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/v2_6/MetricsAnnotationHelper.java rename instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-2.6/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/{counted/CountedInstrumentationModule.java => instrumentationannotations/v2_6/MetricsAnnotationInstrumentationModule.java} (68%) rename instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-2.6/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/{timed => instrumentationannotations/v2_6}/TimedHelper.java (73%) rename instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-2.6/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/{timed => instrumentationannotations/v2_6}/TimedInstrumentation.java (98%) delete mode 100644 instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-2.6/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/timed/TimedInstrumentationModule.java rename instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-2.6/javaagent/src/test/java/io/opentelemetry/{test/annotations => javaagent/instrumentation/instrumentationannotations/v2_6}/counted/CountedExample.java (94%) rename instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-2.6/javaagent/src/test/java/io/opentelemetry/{test/annotations => javaagent/instrumentation/instrumentationannotations/v2_6}/counted/CountedInstrumentationTest.java (90%) rename instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-2.6/javaagent/src/test/java/io/opentelemetry/{test/annotations => javaagent/instrumentation/instrumentationannotations/v2_6}/timed/TimedExample.java (95%) rename instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-2.6/javaagent/src/test/java/io/opentelemetry/{test/annotations => javaagent/instrumentation/instrumentationannotations/v2_6}/timed/TimedInstrumentationTest.java (92%) diff --git a/instrumentation/opentelemetry-instrumentation-annotation-counted/README.md b/instrumentation/opentelemetry-instrumentation-annotation-counted/README.md deleted file mode 100644 index f52a11a938c0..000000000000 --- a/instrumentation/opentelemetry-instrumentation-annotation-counted/README.md +++ /dev/null @@ -1,5 +0,0 @@ -# Settings for the OpenTelemetry Counted Instrumentation Annotations integration - -| Environment variable | Type | Default | Description | -|-----------------------------------------------------------------------------------------| ------ | ------- |-------------------------------------------------------------------------------------| -| `otel.instrumentation.opentelemetry-instrumentation-annotation-counted.exclude-methods` | String | | All methods to be excluded from auto-instrumentation by Counted annotation advices. | diff --git a/instrumentation/opentelemetry-instrumentation-annotation-timed/README.md b/instrumentation/opentelemetry-instrumentation-annotation-timed/README.md deleted file mode 100644 index a16004d9f4dd..000000000000 --- a/instrumentation/opentelemetry-instrumentation-annotation-timed/README.md +++ /dev/null @@ -1,5 +0,0 @@ -# Settings for the OpenTelemetry Timed Instrumentation Annotations integration - -| Environment variable | Type | Default | Description | -|-----------------------------------------------------------------------------------------| ------ | ------- |-----------------------------------------------------------------------------------| -| `otel.instrumentation.opentelemetry-instrumentation-annotation-Timed.exclude-methods` | String | | All methods to be excluded from auto-instrumentation by Timed annotation advices. | diff --git a/instrumentation/opentelemetry-instrumentation-annotation-timed/javaagent/build.gradle.kts b/instrumentation/opentelemetry-instrumentation-annotation-timed/javaagent/build.gradle.kts deleted file mode 100644 index ce5402c4d69c..000000000000 --- a/instrumentation/opentelemetry-instrumentation-annotation-timed/javaagent/build.gradle.kts +++ /dev/null @@ -1,46 +0,0 @@ -plugins { - id("otel.javaagent-instrumentation") -} - -// note that muzzle is not run against the current SNAPSHOT instrumentation-annotations, but this is -// ok because the tests are run against the current SNAPSHOT instrumentation-annotations which will -// catch any muzzle issues in SNAPSHOT instrumentation-annotations - -muzzle { - pass { - group.set("io.opentelemetry") - module.set("opentelemetry-instrumentation-annotations") - versions.set("(,)") - } -} - -dependencies { - compileOnly(project(":instrumentation-annotations-support")) - - compileOnly(project(":javaagent-tooling")) - - // this instrumentation needs to do similar shading dance as opentelemetry-api-1.0 because - // the @WithSpan annotation references the OpenTelemetry API's SpanKind class - // - // see the comment in opentelemetry-api-1.0.gradle for more details - compileOnly(project(":opentelemetry-instrumentation-annotations-shaded-for-instrumenting", configuration = "shadow")) - - // Used by byte-buddy but not brought in as a transitive dependency. - compileOnly("com.google.code.findbugs:annotations") - testCompileOnly("com.google.code.findbugs:annotations") - - testImplementation(project(":instrumentation-annotations")) - testImplementation(project(":instrumentation-annotations-support")) - testImplementation("net.bytebuddy:byte-buddy") -} - -tasks { - compileTestJava { - options.compilerArgs.add("-parameters") - } - test { - jvmArgs( - "-Dotel.instrumentation.opentelemetry-instrumentation-annotation-timed.exclude-methods=io.opentelemetry.test.annotations.timed.TimedExample[exampleIgnore]" - ) - } -} diff --git a/instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-2.6/javaagent/build.gradle.kts b/instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-2.6/javaagent/build.gradle.kts index cca08e10ea34..521fb5ef4de3 100644 --- a/instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-2.6/javaagent/build.gradle.kts +++ b/instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-2.6/javaagent/build.gradle.kts @@ -35,7 +35,7 @@ tasks { } test { jvmArgs( - "-Dotel.instrumentation.opentelemetry-instrumentation-annotations.exclude-methods=io.opentelemetry.test.annotations.counted.CountedExample[exampleIgnore];io.opentelemetry.test.annotations.timed.TimedExample[exampleIgnore]" + "-Dotel.instrumentation.opentelemetry-instrumentation-annotations.exclude-methods=io.opentelemetry.javaagent.instrumentation.instrumentationannotations.v2_6.counted.CountedExample[exampleIgnore];io.opentelemetry.javaagent.instrumentation.instrumentationannotations.v2_6.timed.TimedExample[exampleIgnore]" ) } } diff --git a/instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-2.6/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/counted/CountedHelper.java b/instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-2.6/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/v2_6/CountedHelper.java similarity index 68% rename from instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-2.6/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/counted/CountedHelper.java rename to instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-2.6/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/v2_6/CountedHelper.java index 127773f92e55..d1c002066fc8 100644 --- a/instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-2.6/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/counted/CountedHelper.java +++ b/instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-2.6/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/v2_6/CountedHelper.java @@ -3,56 +3,21 @@ * SPDX-License-Identifier: Apache-2.0 */ -package io.opentelemetry.javaagent.instrumentation.counted; +package io.opentelemetry.javaagent.instrumentation.instrumentationannotations.v2_6; import application.io.opentelemetry.instrumentation.annotations.Counted; -import application.io.opentelemetry.instrumentation.annotations.MetricAttribute; -import io.opentelemetry.api.GlobalOpenTelemetry; import io.opentelemetry.api.common.Attributes; import io.opentelemetry.api.common.AttributesBuilder; -import io.opentelemetry.api.internal.StringUtils; import io.opentelemetry.api.metrics.LongCounter; -import io.opentelemetry.api.metrics.Meter; import io.opentelemetry.javaagent.instrumentation.instrumentationannotations.MethodRequest; import java.lang.reflect.Method; -import java.lang.reflect.Parameter; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; -public final class CountedHelper { +public final class CountedHelper extends MetricsAnnotationHelper { - private static final String INSTRUMENTATION_NAME = - "io.opentelemetry.opentelemetry-instrumentation-annotation-counted"; private static final String COUNTED_DEFAULT_NAME = "method.invocation.count"; private static final ConcurrentMap COUNTERS = new ConcurrentHashMap<>(); - private static final Meter METER = GlobalOpenTelemetry.get().getMeter(INSTRUMENTATION_NAME); - - private static void extractMetricAttributes( - MethodRequest methodRequest, AttributesBuilder attributesBuilder) { - Parameter[] parameters = methodRequest.method().getParameters(); - for (int i = 0; i < parameters.length; i++) { - if (parameters[i].isAnnotationPresent(MetricAttribute.class)) { - MetricAttribute annotation = parameters[i].getAnnotation(MetricAttribute.class); - String attributeKey = ""; - if (!StringUtils.isNullOrEmpty(annotation.value())) { - attributeKey = annotation.value(); - } else if (!StringUtils.isNullOrEmpty(parameters[i].getName())) { - attributeKey = parameters[i].getName(); - } else { - continue; - } - attributesBuilder.put(attributeKey, methodRequest.args()[i].toString()); - } - } - } - - private static void extractAdditionAttributes( - String[] attributes, AttributesBuilder attributesBuilder) { - int length = attributes.length; - for (int i = 0; i + 1 < length; i += 2) { - attributesBuilder.put(attributes[i], attributes[i + 1]); - } - } public static void recordCountWithAttributes( MethodRequest methodRequest, Object returnValue, Throwable throwable) { diff --git a/instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-2.6/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/counted/CountedInstrumentation.java b/instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-2.6/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/v2_6/CountedInstrumentation.java similarity index 98% rename from instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-2.6/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/counted/CountedInstrumentation.java rename to instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-2.6/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/v2_6/CountedInstrumentation.java index f0b5c726902d..51703ab0cb67 100644 --- a/instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-2.6/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/counted/CountedInstrumentation.java +++ b/instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-2.6/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/v2_6/CountedInstrumentation.java @@ -3,7 +3,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -package io.opentelemetry.javaagent.instrumentation.counted; +package io.opentelemetry.javaagent.instrumentation.instrumentationannotations.v2_6; import static io.opentelemetry.javaagent.instrumentation.instrumentationannotations.KotlinCoroutineUtil.isKotlinSuspendMethod; import static net.bytebuddy.matcher.ElementMatchers.declaresMethod; diff --git a/instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-2.6/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/v2_6/MetricsAnnotationHelper.java b/instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-2.6/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/v2_6/MetricsAnnotationHelper.java new file mode 100644 index 000000000000..4c95c1e76c90 --- /dev/null +++ b/instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-2.6/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/v2_6/MetricsAnnotationHelper.java @@ -0,0 +1,46 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.javaagent.instrumentation.instrumentationannotations.v2_6; + +import application.io.opentelemetry.instrumentation.annotations.MetricAttribute; +import io.opentelemetry.api.GlobalOpenTelemetry; +import io.opentelemetry.api.common.AttributesBuilder; +import io.opentelemetry.api.internal.StringUtils; +import io.opentelemetry.api.metrics.Meter; +import io.opentelemetry.javaagent.instrumentation.instrumentationannotations.MethodRequest; +import java.lang.reflect.Parameter; + +public abstract class MetricsAnnotationHelper { + private static final String INSTRUMENTATION_NAME = + "io.opentelemetry.opentelemetry-instrumentation-annotations-2.6"; + static final Meter METER = GlobalOpenTelemetry.get().getMeter(INSTRUMENTATION_NAME); + + static void extractMetricAttributes( + MethodRequest methodRequest, AttributesBuilder attributesBuilder) { + Parameter[] parameters = methodRequest.method().getParameters(); + for (int i = 0; i < parameters.length; i++) { + if (parameters[i].isAnnotationPresent(MetricAttribute.class)) { + MetricAttribute annotation = parameters[i].getAnnotation(MetricAttribute.class); + String attributeKey = ""; + if (!StringUtils.isNullOrEmpty(annotation.value())) { + attributeKey = annotation.value(); + } else if (!StringUtils.isNullOrEmpty(parameters[i].getName())) { + attributeKey = parameters[i].getName(); + } else { + continue; + } + attributesBuilder.put(attributeKey, methodRequest.args()[i].toString()); + } + } + } + + static void extractAdditionAttributes(String[] attributes, AttributesBuilder attributesBuilder) { + int length = attributes.length; + for (int i = 0; i + 1 < length; i += 2) { + attributesBuilder.put(attributes[i], attributes[i + 1]); + } + } +} diff --git a/instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-2.6/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/counted/CountedInstrumentationModule.java b/instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-2.6/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/v2_6/MetricsAnnotationInstrumentationModule.java similarity index 68% rename from instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-2.6/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/counted/CountedInstrumentationModule.java rename to instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-2.6/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/v2_6/MetricsAnnotationInstrumentationModule.java index 3617dcc2c322..f2e1dbb28320 100644 --- a/instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-2.6/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/counted/CountedInstrumentationModule.java +++ b/instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-2.6/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/v2_6/MetricsAnnotationInstrumentationModule.java @@ -3,13 +3,14 @@ * SPDX-License-Identifier: Apache-2.0 */ -package io.opentelemetry.javaagent.instrumentation.counted; +package io.opentelemetry.javaagent.instrumentation.instrumentationannotations.v2_6; import static io.opentelemetry.javaagent.extension.matcher.AgentElementMatchers.hasClassesNamed; import static java.util.Arrays.asList; import application.io.opentelemetry.instrumentation.annotations.Counted; import application.io.opentelemetry.instrumentation.annotations.MetricAttribute; +import application.io.opentelemetry.instrumentation.annotations.Timed; import com.google.auto.service.AutoService; import io.opentelemetry.javaagent.extension.instrumentation.InstrumentationModule; import io.opentelemetry.javaagent.extension.instrumentation.TypeInstrumentation; @@ -17,14 +18,14 @@ import net.bytebuddy.matcher.ElementMatcher; /** - * Instrumentation for methods annotated with {@link Counted} or {@link MetricAttribute} - * annotations. + * Instrumentation for methods annotated with {@link Counted}, {@link Timed} and {@link + * MetricAttribute} annotations. */ @AutoService(InstrumentationModule.class) -public class CountedInstrumentationModule extends InstrumentationModule { +public class MetricsAnnotationInstrumentationModule extends InstrumentationModule { - public CountedInstrumentationModule() { - super("opentelemetry-instrumentation-annotation-counted", "counted"); + public MetricsAnnotationInstrumentationModule() { + super("opentelemetry-instrumentation-annotations", "metrics-annotations"); } @Override @@ -41,6 +42,6 @@ public ElementMatcher.Junction classLoaderMatcher() { @Override public List typeInstrumentations() { - return asList(new CountedInstrumentation()); + return asList(new CountedInstrumentation(), new TimedInstrumentation()); } } diff --git a/instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-2.6/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/timed/TimedHelper.java b/instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-2.6/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/v2_6/TimedHelper.java similarity index 73% rename from instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-2.6/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/timed/TimedHelper.java rename to instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-2.6/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/v2_6/TimedHelper.java index 4b21ff189bbe..d8c2a240cfcf 100644 --- a/instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-2.6/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/timed/TimedHelper.java +++ b/instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-2.6/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/v2_6/TimedHelper.java @@ -3,63 +3,27 @@ * SPDX-License-Identifier: Apache-2.0 */ -package io.opentelemetry.javaagent.instrumentation.timed; +package io.opentelemetry.javaagent.instrumentation.instrumentationannotations.v2_6; import static java.util.concurrent.TimeUnit.NANOSECONDS; -import application.io.opentelemetry.instrumentation.annotations.MetricAttribute; import application.io.opentelemetry.instrumentation.annotations.Timed; -import io.opentelemetry.api.GlobalOpenTelemetry; import io.opentelemetry.api.common.Attributes; import io.opentelemetry.api.common.AttributesBuilder; -import io.opentelemetry.api.internal.StringUtils; import io.opentelemetry.api.metrics.DoubleHistogram; -import io.opentelemetry.api.metrics.Meter; import io.opentelemetry.javaagent.instrumentation.instrumentationannotations.MethodRequest; import java.lang.reflect.Method; -import java.lang.reflect.Parameter; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; import java.util.concurrent.TimeUnit; -public final class TimedHelper { +public final class TimedHelper extends MetricsAnnotationHelper { - private static final String INSTRUMENTATION_NAME = - "io.opentelemetry.opentelemetry-instrumentation-annotation-timed"; private static final String TIMED_DEFAULT_NAME = "method.invocation.duration"; private static final ConcurrentMap HISTOGRAMS = new ConcurrentHashMap<>(); - private static final Meter METER = GlobalOpenTelemetry.get().getMeter(INSTRUMENTATION_NAME); - - private static void extractMetricAttributes( - MethodRequest methodRequest, AttributesBuilder attributesBuilder) { - Parameter[] parameters = methodRequest.method().getParameters(); - for (int i = 0; i < parameters.length; i++) { - if (parameters[i].isAnnotationPresent(MetricAttribute.class)) { - MetricAttribute annotation = parameters[i].getAnnotation(MetricAttribute.class); - String attributeKey = ""; - if (!StringUtils.isNullOrEmpty(annotation.value())) { - attributeKey = annotation.value(); - } else if (!StringUtils.isNullOrEmpty(parameters[i].getName())) { - attributeKey = parameters[i].getName(); - } else { - continue; - } - attributesBuilder.put(attributeKey, methodRequest.args()[i].toString()); - } - } - } - - private static void extractAdditionAttributes( - String[] attributes, AttributesBuilder attributesBuilder) { - int length = attributes.length; - for (int i = 0; i + 1 < length; i += 2) { - attributesBuilder.put(attributes[i], attributes[i + 1]); - } - } - public static void recordHistogramWithAttributes( MethodRequest methodRequest, Throwable throwable, Object returnValue, long startNanoTime) { Timed timedAnnotation = methodRequest.method().getAnnotation(Timed.class); diff --git a/instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-2.6/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/timed/TimedInstrumentation.java b/instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-2.6/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/v2_6/TimedInstrumentation.java similarity index 98% rename from instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-2.6/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/timed/TimedInstrumentation.java rename to instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-2.6/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/v2_6/TimedInstrumentation.java index b5b21ff304c8..a31237351edb 100644 --- a/instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-2.6/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/timed/TimedInstrumentation.java +++ b/instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-2.6/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/v2_6/TimedInstrumentation.java @@ -3,7 +3,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -package io.opentelemetry.javaagent.instrumentation.timed; +package io.opentelemetry.javaagent.instrumentation.instrumentationannotations.v2_6; import static io.opentelemetry.javaagent.instrumentation.instrumentationannotations.KotlinCoroutineUtil.isKotlinSuspendMethod; import static net.bytebuddy.matcher.ElementMatchers.declaresMethod; diff --git a/instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-2.6/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/timed/TimedInstrumentationModule.java b/instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-2.6/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/timed/TimedInstrumentationModule.java deleted file mode 100644 index f5bbb9e0ecf6..000000000000 --- a/instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-2.6/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/timed/TimedInstrumentationModule.java +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -package io.opentelemetry.javaagent.instrumentation.timed; - -import static io.opentelemetry.javaagent.extension.matcher.AgentElementMatchers.hasClassesNamed; -import static java.util.Arrays.asList; - -import application.io.opentelemetry.instrumentation.annotations.MetricAttribute; -import application.io.opentelemetry.instrumentation.annotations.Timed; -import com.google.auto.service.AutoService; -import io.opentelemetry.javaagent.extension.instrumentation.InstrumentationModule; -import io.opentelemetry.javaagent.extension.instrumentation.TypeInstrumentation; -import java.util.List; -import net.bytebuddy.matcher.ElementMatcher; - -/** - * Instrumentation for methods annotated with {@link Timed} and {@link MetricAttribute} annotations. - */ -@AutoService(InstrumentationModule.class) -public class TimedInstrumentationModule extends InstrumentationModule { - - public TimedInstrumentationModule() { - super("opentelemetry-instrumentation-annotation-timed", "timed"); - } - - @Override - public int order() { - // Run first to ensure other automatic instrumentation is added after and therefore is executed - // earlier in the instrumented method and create the span to attach attributes to. - return -1000; - } - - @Override - public ElementMatcher.Junction classLoaderMatcher() { - return hasClassesNamed("application.io.opentelemetry.instrumentation.annotations.Timed"); - } - - @Override - public List typeInstrumentations() { - return asList(new TimedInstrumentation()); - } -} diff --git a/instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-2.6/javaagent/src/test/java/io/opentelemetry/test/annotations/counted/CountedExample.java b/instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-2.6/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/v2_6/counted/CountedExample.java similarity index 94% rename from instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-2.6/javaagent/src/test/java/io/opentelemetry/test/annotations/counted/CountedExample.java rename to instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-2.6/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/v2_6/counted/CountedExample.java index 801f4a10988f..bfa6e61f4103 100644 --- a/instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-2.6/javaagent/src/test/java/io/opentelemetry/test/annotations/counted/CountedExample.java +++ b/instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-2.6/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/v2_6/counted/CountedExample.java @@ -3,7 +3,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -package io.opentelemetry.test.annotations.counted; +package io.opentelemetry.javaagent.instrumentation.instrumentationannotations.v2_6.counted; import io.opentelemetry.instrumentation.annotations.Counted; diff --git a/instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-2.6/javaagent/src/test/java/io/opentelemetry/test/annotations/counted/CountedInstrumentationTest.java b/instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-2.6/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/v2_6/counted/CountedInstrumentationTest.java similarity index 90% rename from instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-2.6/javaagent/src/test/java/io/opentelemetry/test/annotations/counted/CountedInstrumentationTest.java rename to instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-2.6/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/v2_6/counted/CountedInstrumentationTest.java index f3796189c73f..df2b198a59d8 100644 --- a/instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-2.6/javaagent/src/test/java/io/opentelemetry/test/annotations/counted/CountedInstrumentationTest.java +++ b/instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-2.6/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/v2_6/counted/CountedInstrumentationTest.java @@ -3,11 +3,11 @@ * SPDX-License-Identifier: Apache-2.0 */ -package io.opentelemetry.test.annotations.counted; +package io.opentelemetry.javaagent.instrumentation.instrumentationannotations.v2_6.counted; -import static io.opentelemetry.test.annotations.counted.CountedExample.ANOTHER_NAME_COUNT; -import static io.opentelemetry.test.annotations.counted.CountedExample.METRIC_DESCRIPTION; -import static io.opentelemetry.test.annotations.counted.CountedExample.METRIC_UNIT; +import static io.opentelemetry.javaagent.instrumentation.instrumentationannotations.v2_6.counted.CountedExample.ANOTHER_NAME_COUNT; +import static io.opentelemetry.javaagent.instrumentation.instrumentationannotations.v2_6.counted.CountedExample.METRIC_DESCRIPTION; +import static io.opentelemetry.javaagent.instrumentation.instrumentationannotations.v2_6.counted.CountedExample.METRIC_UNIT; import static org.assertj.core.api.Assertions.assertThat; import io.opentelemetry.api.common.AttributeKey; @@ -21,10 +21,9 @@ class CountedInstrumentationTest { public static final AgentInstrumentationExtension testing = AgentInstrumentationExtension.create(); - public static final String INSTRUMENTATION_NAME = - "io.opentelemetry.opentelemetry-instrumentation-annotation-counted"; - - public static final String COUNTED_DEFAULT_NAME = "method.invocation.count"; + private static final String INSTRUMENTATION_NAME = + "io.opentelemetry.opentelemetry-instrumentation-annotations-2.6"; + private static final String COUNTED_DEFAULT_NAME = "method.invocation.count"; @Test void testDefaultExample() { diff --git a/instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-2.6/javaagent/src/test/java/io/opentelemetry/test/annotations/timed/TimedExample.java b/instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-2.6/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/v2_6/timed/TimedExample.java similarity index 95% rename from instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-2.6/javaagent/src/test/java/io/opentelemetry/test/annotations/timed/TimedExample.java rename to instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-2.6/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/v2_6/timed/TimedExample.java index baa872fa1f26..299f196796a3 100644 --- a/instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-2.6/javaagent/src/test/java/io/opentelemetry/test/annotations/timed/TimedExample.java +++ b/instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-2.6/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/v2_6/timed/TimedExample.java @@ -3,7 +3,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -package io.opentelemetry.test.annotations.timed; +package io.opentelemetry.javaagent.instrumentation.instrumentationannotations.v2_6.timed; import io.opentelemetry.instrumentation.annotations.Timed; import java.util.concurrent.TimeUnit; diff --git a/instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-2.6/javaagent/src/test/java/io/opentelemetry/test/annotations/timed/TimedInstrumentationTest.java b/instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-2.6/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/v2_6/timed/TimedInstrumentationTest.java similarity index 92% rename from instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-2.6/javaagent/src/test/java/io/opentelemetry/test/annotations/timed/TimedInstrumentationTest.java rename to instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-2.6/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/v2_6/timed/TimedInstrumentationTest.java index f93aba564aa3..499c585c6362 100644 --- a/instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-2.6/javaagent/src/test/java/io/opentelemetry/test/annotations/timed/TimedInstrumentationTest.java +++ b/instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-2.6/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/v2_6/timed/TimedInstrumentationTest.java @@ -3,10 +3,10 @@ * SPDX-License-Identifier: Apache-2.0 */ -package io.opentelemetry.test.annotations.timed; +package io.opentelemetry.javaagent.instrumentation.instrumentationannotations.v2_6.timed; -import static io.opentelemetry.test.annotations.timed.TimedExample.ANOTHER_NAME_HISTOGRAM; -import static io.opentelemetry.test.annotations.timed.TimedExample.METRIC_DESCRIPTION; +import static io.opentelemetry.javaagent.instrumentation.instrumentationannotations.v2_6.timed.TimedExample.ANOTHER_NAME_HISTOGRAM; +import static io.opentelemetry.javaagent.instrumentation.instrumentationannotations.v2_6.timed.TimedExample.METRIC_DESCRIPTION; import static org.assertj.core.api.Assertions.assertThat; import io.opentelemetry.api.common.AttributeKey; @@ -20,10 +20,9 @@ class TimedInstrumentationTest { public static final AgentInstrumentationExtension testing = AgentInstrumentationExtension.create(); - public static final String TIMED_DEFAULT_NAME = "method.invocation.duration"; - - public static final String TIMED_INSTRUMENTATION_NAME = - "io.opentelemetry.opentelemetry-instrumentation-annotation-timed"; + private static final String TIMED_INSTRUMENTATION_NAME = + "io.opentelemetry.opentelemetry-instrumentation-annotations-2.6"; + private static final String TIMED_DEFAULT_NAME = "method.invocation.duration"; @Test void testDefaultExample() { From aa3b47cf1cdfca5342d11b08ce453572f5ba6259 Mon Sep 17 00:00:00 2001 From: Lauri Tulmin Date: Tue, 11 Jun 2024 11:09:23 +0300 Subject: [PATCH 05/21] Paratmeter.getName() synthesizes a name when it is not present --- .../v2_6/MetricsAnnotationHelper.java | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-2.6/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/v2_6/MetricsAnnotationHelper.java b/instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-2.6/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/v2_6/MetricsAnnotationHelper.java index 4c95c1e76c90..242ed70ab70b 100644 --- a/instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-2.6/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/v2_6/MetricsAnnotationHelper.java +++ b/instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-2.6/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/v2_6/MetricsAnnotationHelper.java @@ -8,7 +8,6 @@ import application.io.opentelemetry.instrumentation.annotations.MetricAttribute; import io.opentelemetry.api.GlobalOpenTelemetry; import io.opentelemetry.api.common.AttributesBuilder; -import io.opentelemetry.api.internal.StringUtils; import io.opentelemetry.api.metrics.Meter; import io.opentelemetry.javaagent.instrumentation.instrumentationannotations.MethodRequest; import java.lang.reflect.Parameter; @@ -24,10 +23,10 @@ static void extractMetricAttributes( for (int i = 0; i < parameters.length; i++) { if (parameters[i].isAnnotationPresent(MetricAttribute.class)) { MetricAttribute annotation = parameters[i].getAnnotation(MetricAttribute.class); - String attributeKey = ""; - if (!StringUtils.isNullOrEmpty(annotation.value())) { + String attributeKey; + if (!annotation.value().isEmpty()) { attributeKey = annotation.value(); - } else if (!StringUtils.isNullOrEmpty(parameters[i].getName())) { + } else if (parameters[i].isNamePresent()) { attributeKey = parameters[i].getName(); } else { continue; From d954ebebc1540574e71a09bbccc598af483ed6ab Mon Sep 17 00:00:00 2001 From: Lauri Tulmin Date: Tue, 18 Jun 2024 10:55:34 +0300 Subject: [PATCH 06/21] cache counter/histogram per method --- .../v2_6/CountedHelper.java | 50 +++++++-------- .../v2_6/TimedHelper.java | 62 +++++++++---------- .../counted/CountedInstrumentationTest.java | 5 +- .../v2_6/timed/TimedInstrumentationTest.java | 2 + 4 files changed, 58 insertions(+), 61 deletions(-) diff --git a/instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-2.6/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/v2_6/CountedHelper.java b/instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-2.6/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/v2_6/CountedHelper.java index d1c002066fc8..d2d8484676c4 100644 --- a/instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-2.6/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/v2_6/CountedHelper.java +++ b/instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-2.6/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/v2_6/CountedHelper.java @@ -11,13 +11,19 @@ import io.opentelemetry.api.metrics.LongCounter; import io.opentelemetry.javaagent.instrumentation.instrumentationannotations.MethodRequest; import java.lang.reflect.Method; +import java.util.Map; import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.ConcurrentMap; public final class CountedHelper extends MetricsAnnotationHelper { private static final String COUNTED_DEFAULT_NAME = "method.invocation.count"; - private static final ConcurrentMap COUNTERS = new ConcurrentHashMap<>(); + private static final ClassValue> counters = + new ClassValue>() { + @Override + protected Map computeValue(Class type) { + return new ConcurrentHashMap<>(); + } + }; public static void recordCountWithAttributes( MethodRequest methodRequest, Object returnValue, Throwable throwable) { @@ -59,30 +65,22 @@ private static void extractReturnValue( } private static LongCounter getCounter(Method method) { - Counted countedAnnotation = method.getAnnotation(Counted.class); - String metricName = - (null == countedAnnotation.value() || countedAnnotation.value().isEmpty()) - ? COUNTED_DEFAULT_NAME - : countedAnnotation.value(); - if (!COUNTERS.containsKey(metricName)) { - synchronized (metricName) { - if (!COUNTERS.containsKey(metricName)) { - LongCounter longCounter = null; - if (COUNTED_DEFAULT_NAME.equals(metricName)) { - longCounter = METER.counterBuilder(metricName).build(); - } else { - longCounter = - METER - .counterBuilder(metricName) - .setDescription(countedAnnotation.description()) - .setUnit(countedAnnotation.unit()) - .build(); - } - COUNTERS.put(metricName, longCounter); - } - } - } - return COUNTERS.get(metricName); + return counters + .get(method.getDeclaringClass()) + .computeIfAbsent( + method, + m -> { + Counted countedAnnotation = m.getAnnotation(Counted.class); + String metricName = + (null == countedAnnotation.value() || countedAnnotation.value().isEmpty()) + ? COUNTED_DEFAULT_NAME + : countedAnnotation.value(); + return METER + .counterBuilder(metricName) + .setDescription(countedAnnotation.description()) + .setUnit(countedAnnotation.unit()) + .build(); + }); } private CountedHelper() {} diff --git a/instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-2.6/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/v2_6/TimedHelper.java b/instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-2.6/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/v2_6/TimedHelper.java index d8c2a240cfcf..44bf4cf117d2 100644 --- a/instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-2.6/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/v2_6/TimedHelper.java +++ b/instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-2.6/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/v2_6/TimedHelper.java @@ -13,16 +13,20 @@ import io.opentelemetry.api.metrics.DoubleHistogram; import io.opentelemetry.javaagent.instrumentation.instrumentationannotations.MethodRequest; import java.lang.reflect.Method; +import java.util.Map; import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.ConcurrentMap; import java.util.concurrent.TimeUnit; public final class TimedHelper extends MetricsAnnotationHelper { private static final String TIMED_DEFAULT_NAME = "method.invocation.duration"; - - private static final ConcurrentMap HISTOGRAMS = - new ConcurrentHashMap<>(); + private static final ClassValue> histograms = + new ClassValue>() { + @Override + protected Map computeValue(Class type) { + return new ConcurrentHashMap<>(); + } + }; public static void recordHistogramWithAttributes( MethodRequest methodRequest, Throwable throwable, Object returnValue, long startNanoTime) { @@ -31,7 +35,7 @@ public static void recordHistogramWithAttributes( getCommonAttributeBuilder(throwable, returnValue, timedAnnotation); double duration = getTransformedDuration(startNanoTime, timedAnnotation); extractMetricAttributes(methodRequest, attributesBuilder); - getHistogram(timedAnnotation).record(duration, attributesBuilder.build()); + getHistogram(methodRequest.method()).record(duration, attributesBuilder.build()); } public static void recordHistogram( @@ -40,7 +44,7 @@ public static void recordHistogram( AttributesBuilder attributesBuilder = getCommonAttributeBuilder(throwable, returnValue, timedAnnotation); double duration = getTransformedDuration(startNanoTime, timedAnnotation); - getHistogram(timedAnnotation).record(duration, attributesBuilder.build()); + getHistogram(method).record(duration, attributesBuilder.build()); } private static AttributesBuilder getCommonAttributeBuilder( @@ -55,8 +59,7 @@ private static AttributesBuilder getCommonAttributeBuilder( private static double getTransformedDuration(long startNanoTime, Timed timedAnnotation) { TimeUnit unit = extractTimeUnit(timedAnnotation); long nanoDelta = System.nanoTime() - startNanoTime; - double duration = unit.convert(nanoDelta, NANOSECONDS); - return duration; + return unit.convert(nanoDelta, NANOSECONDS); } private static void extractException(Throwable throwable, AttributesBuilder attributesBuilder) { @@ -73,31 +76,24 @@ private static void extractReturnValue( } } - private static DoubleHistogram getHistogram(Timed timedAnnotation) { - String metricName = - (null == timedAnnotation.value() || timedAnnotation.value().isEmpty()) - ? TIMED_DEFAULT_NAME - : timedAnnotation.value(); - if (!HISTOGRAMS.containsKey(metricName)) { - synchronized (metricName) { - if (!HISTOGRAMS.containsKey(metricName)) { - DoubleHistogram doubleHistogram = null; - if (TIMED_DEFAULT_NAME.equals(metricName)) { - doubleHistogram = METER.histogramBuilder(metricName).setUnit("ms").build(); - } else { - String unitStr = extractUnitStr(timedAnnotation); - doubleHistogram = - METER - .histogramBuilder(metricName) - .setDescription(timedAnnotation.description()) - .setUnit(unitStr) - .build(); - } - HISTOGRAMS.put(metricName, doubleHistogram); - } - } - } - return HISTOGRAMS.get(metricName); + private static DoubleHistogram getHistogram(Method method) { + return histograms + .get(method.getDeclaringClass()) + .computeIfAbsent( + method, + m -> { + Timed timedAnnotation = m.getAnnotation(Timed.class); + String metricName = + (null == timedAnnotation.value() || timedAnnotation.value().isEmpty()) + ? TIMED_DEFAULT_NAME + : timedAnnotation.value(); + String unitStr = extractUnitStr(timedAnnotation); + return METER + .histogramBuilder(metricName) + .setDescription(timedAnnotation.description()) + .setUnit(unitStr) + .build(); + }); } private static TimeUnit extractTimeUnit(Timed timedAnnotation) { diff --git a/instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-2.6/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/v2_6/counted/CountedInstrumentationTest.java b/instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-2.6/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/v2_6/counted/CountedInstrumentationTest.java index df2b198a59d8..57fc04ea1c4f 100644 --- a/instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-2.6/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/v2_6/counted/CountedInstrumentationTest.java +++ b/instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-2.6/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/v2_6/counted/CountedInstrumentationTest.java @@ -43,14 +43,15 @@ void testExampleWithAnotherName() { void testExampleWithDescriptionAndDefaultValue() { new CountedExample().exampleWithDescriptionAndDefaultValue(); testing.waitAndAssertMetrics( - INSTRUMENTATION_NAME, metric -> metric.hasName(COUNTED_DEFAULT_NAME).hasDescription("")); + INSTRUMENTATION_NAME, + metric -> metric.hasName(COUNTED_DEFAULT_NAME).hasDescription(METRIC_DESCRIPTION)); } @Test void testExampleWithUnitAndDefaultValue() { new CountedExample().exampleWithUnitAndDefaultValue(); testing.waitAndAssertMetrics( - INSTRUMENTATION_NAME, metric -> metric.hasName(COUNTED_DEFAULT_NAME).hasUnit("")); + INSTRUMENTATION_NAME, metric -> metric.hasName(COUNTED_DEFAULT_NAME).hasUnit(METRIC_UNIT)); } @Test diff --git a/instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-2.6/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/v2_6/timed/TimedInstrumentationTest.java b/instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-2.6/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/v2_6/timed/TimedInstrumentationTest.java index 499c585c6362..07c861cb4121 100644 --- a/instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-2.6/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/v2_6/timed/TimedInstrumentationTest.java +++ b/instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-2.6/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/v2_6/timed/TimedInstrumentationTest.java @@ -38,6 +38,7 @@ void testExampleWithAnotherName() { TIMED_INSTRUMENTATION_NAME, metric -> metric.hasName(ANOTHER_NAME_HISTOGRAM)); } + /* @Test void testExampleWithDescriptionAndDefaultValue() { new TimedExample().exampleWithDescriptionAndDefaultValue(); @@ -52,6 +53,7 @@ void testExampleWithUnitNanoSecondAndDefaultValue() { testing.waitAndAssertMetrics( TIMED_INSTRUMENTATION_NAME, metric -> metric.hasName(TIMED_DEFAULT_NAME).hasUnit("ms")); } + */ @Test void testExampleWithDescription() { From 37733c1da0b1d0f443e66f62e25f7e075d2753ff Mon Sep 17 00:00:00 2001 From: Lauri Tulmin Date: Tue, 18 Jun 2024 12:45:03 +0300 Subject: [PATCH 07/21] make named required for @Counted and @Timed --- .../instrumentation/annotations/Counted.java | 4 +- .../instrumentation/annotations/Timed.java | 4 +- .../v2_6/CountedHelper.java | 7 +- .../v2_6/TimedHelper.java | 7 +- .../v2_6/counted/CountedExample.java | 29 ++-- .../counted/CountedInstrumentationTest.java | 126 +++++++---------- .../v2_6/timed/TimedExample.java | 27 ++-- .../v2_6/timed/TimedInstrumentationTest.java | 133 +++++++----------- 8 files changed, 131 insertions(+), 206 deletions(-) diff --git a/instrumentation-annotations/src/main/java/io/opentelemetry/instrumentation/annotations/Counted.java b/instrumentation-annotations/src/main/java/io/opentelemetry/instrumentation/annotations/Counted.java index 0907f0210ae6..7f2c79906f8f 100644 --- a/instrumentation-annotations/src/main/java/io/opentelemetry/instrumentation/annotations/Counted.java +++ b/instrumentation-annotations/src/main/java/io/opentelemetry/instrumentation/annotations/Counted.java @@ -40,10 +40,8 @@ * *

The name should follow the instrument naming rule: https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/metrics/api.md#instrument-naming-rule - * - *

The default name is {@code method.invocation.count}. */ - String value() default ""; + String value(); /** * Description of the instrument. diff --git a/instrumentation-annotations/src/main/java/io/opentelemetry/instrumentation/annotations/Timed.java b/instrumentation-annotations/src/main/java/io/opentelemetry/instrumentation/annotations/Timed.java index 730dedd5f482..37d621027c90 100644 --- a/instrumentation-annotations/src/main/java/io/opentelemetry/instrumentation/annotations/Timed.java +++ b/instrumentation-annotations/src/main/java/io/opentelemetry/instrumentation/annotations/Timed.java @@ -41,10 +41,8 @@ * *

The name should follow the instrument naming rule: https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/metrics/api.md#instrument-naming-rule - * - *

The default name is {@code method.invocation.duration}. */ - String value() default ""; + String value(); /** * Description for the instrument. diff --git a/instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-2.6/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/v2_6/CountedHelper.java b/instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-2.6/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/v2_6/CountedHelper.java index d2d8484676c4..e87a44e09f6f 100644 --- a/instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-2.6/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/v2_6/CountedHelper.java +++ b/instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-2.6/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/v2_6/CountedHelper.java @@ -16,7 +16,6 @@ public final class CountedHelper extends MetricsAnnotationHelper { - private static final String COUNTED_DEFAULT_NAME = "method.invocation.count"; private static final ClassValue> counters = new ClassValue>() { @Override @@ -71,12 +70,8 @@ private static LongCounter getCounter(Method method) { method, m -> { Counted countedAnnotation = m.getAnnotation(Counted.class); - String metricName = - (null == countedAnnotation.value() || countedAnnotation.value().isEmpty()) - ? COUNTED_DEFAULT_NAME - : countedAnnotation.value(); return METER - .counterBuilder(metricName) + .counterBuilder(countedAnnotation.value()) .setDescription(countedAnnotation.description()) .setUnit(countedAnnotation.unit()) .build(); diff --git a/instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-2.6/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/v2_6/TimedHelper.java b/instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-2.6/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/v2_6/TimedHelper.java index 44bf4cf117d2..634d2d0972f4 100644 --- a/instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-2.6/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/v2_6/TimedHelper.java +++ b/instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-2.6/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/v2_6/TimedHelper.java @@ -19,7 +19,6 @@ public final class TimedHelper extends MetricsAnnotationHelper { - private static final String TIMED_DEFAULT_NAME = "method.invocation.duration"; private static final ClassValue> histograms = new ClassValue>() { @Override @@ -83,13 +82,9 @@ private static DoubleHistogram getHistogram(Method method) { method, m -> { Timed timedAnnotation = m.getAnnotation(Timed.class); - String metricName = - (null == timedAnnotation.value() || timedAnnotation.value().isEmpty()) - ? TIMED_DEFAULT_NAME - : timedAnnotation.value(); String unitStr = extractUnitStr(timedAnnotation); return METER - .histogramBuilder(metricName) + .histogramBuilder(timedAnnotation.value()) .setDescription(timedAnnotation.description()) .setUnit(unitStr) .build(); diff --git a/instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-2.6/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/v2_6/counted/CountedExample.java b/instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-2.6/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/v2_6/counted/CountedExample.java index bfa6e61f4103..840f845d2a46 100644 --- a/instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-2.6/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/v2_6/counted/CountedExample.java +++ b/instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-2.6/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/v2_6/counted/CountedExample.java @@ -9,22 +9,13 @@ public class CountedExample { - public static final String ANOTHER_NAME_COUNT = "another.name.count"; + public static final String METRIC_NAME = "name.count"; public static final String METRIC_DESCRIPTION = "I am the description."; public static final String METRIC_UNIT = "ms"; public static final String RETURN_STRING = "I am a return string."; - @Counted - public void defaultExample() {} - - @Counted(ANOTHER_NAME_COUNT) - public void exampleWithAnotherName() {} - - @Counted(description = METRIC_DESCRIPTION) - public void exampleWithDescriptionAndDefaultValue() {} - - @Counted(unit = METRIC_UNIT) - public void exampleWithUnitAndDefaultValue() {} + @Counted(METRIC_NAME) + public void exampleWithName() {} @Counted(value = "example.with.description.count", description = METRIC_DESCRIPTION) public void exampleWithDescription() {} @@ -32,23 +23,27 @@ public void exampleWithDescription() {} @Counted(value = "example.with.unit.count", unit = METRIC_UNIT) public void exampleWithUnit() {} - @Counted(additionalAttributes = {"key1", "value1", "key2", "value2"}) + @Counted( + value = "example.with.attributes.count", + additionalAttributes = {"key1", "value1", "key2", "value2"}) public void exampleWithAdditionalAttributes1() {} - @Counted(additionalAttributes = {"key1", "value1", "key2", "value2", "key3"}) + @Counted( + value = "example.with.attributes2.count", + additionalAttributes = {"key1", "value1", "key2", "value2", "key3"}) public void exampleWithAdditionalAttributes2() {} - @Counted(returnValueAttribute = "returnValue") + @Counted(value = "example.with.return.count", returnValueAttribute = "returnValue") public ReturnObject exampleWithReturnValueAttribute() { return new ReturnObject(); } - @Counted + @Counted("example.with.exception.count") public void exampleWithException() { throw new IllegalStateException("test exception."); } - @Counted + @Counted("example.ignore.count") public void exampleIgnore() {} public static class ReturnObject { diff --git a/instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-2.6/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/v2_6/counted/CountedInstrumentationTest.java b/instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-2.6/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/v2_6/counted/CountedInstrumentationTest.java index 57fc04ea1c4f..6bf61f72d085 100644 --- a/instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-2.6/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/v2_6/counted/CountedInstrumentationTest.java +++ b/instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-2.6/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/v2_6/counted/CountedInstrumentationTest.java @@ -5,8 +5,8 @@ package io.opentelemetry.javaagent.instrumentation.instrumentationannotations.v2_6.counted; -import static io.opentelemetry.javaagent.instrumentation.instrumentationannotations.v2_6.counted.CountedExample.ANOTHER_NAME_COUNT; import static io.opentelemetry.javaagent.instrumentation.instrumentationannotations.v2_6.counted.CountedExample.METRIC_DESCRIPTION; +import static io.opentelemetry.javaagent.instrumentation.instrumentationannotations.v2_6.counted.CountedExample.METRIC_NAME; import static io.opentelemetry.javaagent.instrumentation.instrumentationannotations.v2_6.counted.CountedExample.METRIC_UNIT; import static org.assertj.core.api.Assertions.assertThat; @@ -18,40 +18,16 @@ class CountedInstrumentationTest { @RegisterExtension - public static final AgentInstrumentationExtension testing = + private static final AgentInstrumentationExtension testing = AgentInstrumentationExtension.create(); private static final String INSTRUMENTATION_NAME = "io.opentelemetry.opentelemetry-instrumentation-annotations-2.6"; - private static final String COUNTED_DEFAULT_NAME = "method.invocation.count"; - - @Test - void testDefaultExample() { - new CountedExample().defaultExample(); - testing.waitAndAssertMetrics( - INSTRUMENTATION_NAME, metric -> metric.hasName(COUNTED_DEFAULT_NAME)); - } @Test void testExampleWithAnotherName() { - new CountedExample().exampleWithAnotherName(); - testing.waitAndAssertMetrics( - INSTRUMENTATION_NAME, metric -> metric.hasName(ANOTHER_NAME_COUNT)); - } - - @Test - void testExampleWithDescriptionAndDefaultValue() { - new CountedExample().exampleWithDescriptionAndDefaultValue(); - testing.waitAndAssertMetrics( - INSTRUMENTATION_NAME, - metric -> metric.hasName(COUNTED_DEFAULT_NAME).hasDescription(METRIC_DESCRIPTION)); - } - - @Test - void testExampleWithUnitAndDefaultValue() { - new CountedExample().exampleWithUnitAndDefaultValue(); - testing.waitAndAssertMetrics( - INSTRUMENTATION_NAME, metric -> metric.hasName(COUNTED_DEFAULT_NAME).hasUnit(METRIC_UNIT)); + new CountedExample().exampleWithName(); + testing.waitAndAssertMetrics(INSTRUMENTATION_NAME, metric -> metric.hasName(METRIC_NAME)); } @Test @@ -78,20 +54,20 @@ void testExampleWithAdditionalAttributes1() { INSTRUMENTATION_NAME, metric -> metric - .hasName(COUNTED_DEFAULT_NAME) + .hasName("example.with.attributes.count") .satisfies( - metricData -> { - assertThat(metricData.getData().getPoints()) - .allMatch( - p -> - "value1" - .equals( - p.getAttributes().get(AttributeKey.stringKey("key1"))) - && "value2" - .equals( - p.getAttributes() - .get(AttributeKey.stringKey("key2")))); - })); + metricData -> + assertThat(metricData.getData().getPoints()) + .allMatch( + p -> + "value1" + .equals( + p.getAttributes() + .get(AttributeKey.stringKey("key1"))) + && "value2" + .equals( + p.getAttributes() + .get(AttributeKey.stringKey("key2")))))); } @Test @@ -101,21 +77,23 @@ void testExampleWithAdditionalAttributes2() { INSTRUMENTATION_NAME, metric -> metric - .hasName(COUNTED_DEFAULT_NAME) + .hasName("example.with.attributes2.count") .satisfies( - metricData -> { - assertThat(metricData.getData().getPoints()) - .allMatch( - p -> - "value1" - .equals( - p.getAttributes().get(AttributeKey.stringKey("key1"))) - && "value2" - .equals( - p.getAttributes().get(AttributeKey.stringKey("key2"))) - && null - == p.getAttributes().get(AttributeKey.stringKey("key3"))); - })); + metricData -> + assertThat(metricData.getData().getPoints()) + .allMatch( + p -> + "value1" + .equals( + p.getAttributes() + .get(AttributeKey.stringKey("key1"))) + && "value2" + .equals( + p.getAttributes() + .get(AttributeKey.stringKey("key2"))) + && null + == p.getAttributes() + .get(AttributeKey.stringKey("key3"))))); } @Test @@ -125,16 +103,15 @@ void testExampleWithReturnAttribute() { INSTRUMENTATION_NAME, metric -> metric - .hasName(COUNTED_DEFAULT_NAME) + .hasName("example.with.return.count") .satisfies( - metricData -> { - assertThat(metricData.getData().getPoints()) - .allMatch( - p -> - CountedExample.RETURN_STRING.equals( - p.getAttributes() - .get(AttributeKey.stringKey("returnValue")))); - })); + metricData -> + assertThat(metricData.getData().getPoints()) + .allMatch( + p -> + CountedExample.RETURN_STRING.equals( + p.getAttributes() + .get(AttributeKey.stringKey("returnValue")))))); } @Test @@ -148,18 +125,17 @@ void testExampleWithException() { INSTRUMENTATION_NAME, metric -> metric - .hasName(COUNTED_DEFAULT_NAME) + .hasName("example.with.exception.count") .satisfies( - metricData -> { - assertThat(metricData.getData().getPoints()) - .allMatch( - p -> - IllegalStateException.class - .getName() - .equals( - p.getAttributes() - .get(AttributeKey.stringKey("exception")))); - })); + metricData -> + assertThat(metricData.getData().getPoints()) + .allMatch( + p -> + IllegalStateException.class + .getName() + .equals( + p.getAttributes() + .get(AttributeKey.stringKey("exception")))))); } @Test diff --git a/instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-2.6/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/v2_6/timed/TimedExample.java b/instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-2.6/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/v2_6/timed/TimedExample.java index 299f196796a3..1317455c1807 100644 --- a/instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-2.6/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/v2_6/timed/TimedExample.java +++ b/instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-2.6/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/v2_6/timed/TimedExample.java @@ -9,22 +9,13 @@ import java.util.concurrent.TimeUnit; public class TimedExample { - public static final String ANOTHER_NAME_HISTOGRAM = "another.name.duration"; + public static final String METRIC_NAME = "name.duration"; public static final String METRIC_DESCRIPTION = "I am the description."; public static final String RETURN_STRING = "I am a return string."; - @Timed - public void defaultExample() {} - - @Timed(ANOTHER_NAME_HISTOGRAM) + @Timed(METRIC_NAME) public void exampleWithAnotherName() {} - @Timed(description = METRIC_DESCRIPTION) - public void exampleWithDescriptionAndDefaultValue() {} - - @Timed(unit = TimeUnit.NANOSECONDS) - public void exampleWithUnitNanoSecondAndDefaultValue() {} - @Timed(value = "example.with.description.duration", description = METRIC_DESCRIPTION) public void exampleWithDescription() {} @@ -33,21 +24,25 @@ public void exampleWithUnitSecondAnd2SecondLatency() throws InterruptedException Thread.sleep(2000); } - @Timed(additionalAttributes = {"key1", "value1", "key2", "value2"}) + @Timed( + value = "example.with.attributes.duration", + additionalAttributes = {"key1", "value1", "key2", "value2"}) public void exampleWithAdditionalAttributes1() {} - @Timed(additionalAttributes = {"key1", "value1", "key2", "value2", "key3"}) + @Timed( + value = "example.with.attributes2.duration", + additionalAttributes = {"key1", "value1", "key2", "value2", "key3"}) public void exampleWithAdditionalAttributes2() {} - @Timed + @Timed("example.ignore.duration") public void exampleIgnore() {} - @Timed + @Timed("example.with.exception.duration") public void exampleWithException() { throw new IllegalStateException("test"); } - @Timed(returnValueAttribute = "returnValue") + @Timed(value = "example.with.return.duration", returnValueAttribute = "returnValue") public ReturnObject exampleWithReturnValueAttribute() { return new ReturnObject(); } diff --git a/instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-2.6/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/v2_6/timed/TimedInstrumentationTest.java b/instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-2.6/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/v2_6/timed/TimedInstrumentationTest.java index 07c861cb4121..0b8727b9725a 100644 --- a/instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-2.6/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/v2_6/timed/TimedInstrumentationTest.java +++ b/instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-2.6/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/v2_6/timed/TimedInstrumentationTest.java @@ -5,8 +5,8 @@ package io.opentelemetry.javaagent.instrumentation.instrumentationannotations.v2_6.timed; -import static io.opentelemetry.javaagent.instrumentation.instrumentationannotations.v2_6.timed.TimedExample.ANOTHER_NAME_HISTOGRAM; import static io.opentelemetry.javaagent.instrumentation.instrumentationannotations.v2_6.timed.TimedExample.METRIC_DESCRIPTION; +import static io.opentelemetry.javaagent.instrumentation.instrumentationannotations.v2_6.timed.TimedExample.METRIC_NAME; import static org.assertj.core.api.Assertions.assertThat; import io.opentelemetry.api.common.AttributeKey; @@ -17,43 +17,17 @@ class TimedInstrumentationTest { @RegisterExtension - public static final AgentInstrumentationExtension testing = + private static final AgentInstrumentationExtension testing = AgentInstrumentationExtension.create(); private static final String TIMED_INSTRUMENTATION_NAME = "io.opentelemetry.opentelemetry-instrumentation-annotations-2.6"; - private static final String TIMED_DEFAULT_NAME = "method.invocation.duration"; - - @Test - void testDefaultExample() { - new TimedExample().defaultExample(); - testing.waitAndAssertMetrics( - TIMED_INSTRUMENTATION_NAME, metric -> metric.hasName(TIMED_DEFAULT_NAME)); - } @Test void testExampleWithAnotherName() { new TimedExample().exampleWithAnotherName(); - testing.waitAndAssertMetrics( - TIMED_INSTRUMENTATION_NAME, metric -> metric.hasName(ANOTHER_NAME_HISTOGRAM)); - } - - /* - @Test - void testExampleWithDescriptionAndDefaultValue() { - new TimedExample().exampleWithDescriptionAndDefaultValue(); - testing.waitAndAssertMetrics( - TIMED_INSTRUMENTATION_NAME, - metric -> metric.hasName(TIMED_DEFAULT_NAME).hasDescription("")); - } - - @Test - void testExampleWithUnitNanoSecondAndDefaultValue() { - new TimedExample().exampleWithUnitNanoSecondAndDefaultValue(); - testing.waitAndAssertMetrics( - TIMED_INSTRUMENTATION_NAME, metric -> metric.hasName(TIMED_DEFAULT_NAME).hasUnit("ms")); + testing.waitAndAssertMetrics(TIMED_INSTRUMENTATION_NAME, metric -> metric.hasName(METRIC_NAME)); } - */ @Test void testExampleWithDescription() { @@ -74,10 +48,9 @@ void testExampleWithUnitSecondAnd2SecondLatency() throws InterruptedException { .hasName("example.with.unit.duration") .hasUnit("s") .satisfies( - metricData -> { - assertThat(metricData.getHistogramData().getPoints()) - .allMatch(p -> p.getMax() < 5 && p.getMin() > 0); - })); + metricData -> + assertThat(metricData.getHistogramData().getPoints()) + .allMatch(p -> p.getMax() < 5 && p.getMin() > 0))); } @Test @@ -87,20 +60,20 @@ void testExampleWithAdditionalAttributes1() { TIMED_INSTRUMENTATION_NAME, metric -> metric - .hasName(TIMED_DEFAULT_NAME) + .hasName("example.with.attributes.duration") .satisfies( - metricData -> { - assertThat(metricData.getData().getPoints()) - .allMatch( - p -> - "value1" - .equals( - p.getAttributes().get(AttributeKey.stringKey("key1"))) - && "value2" - .equals( - p.getAttributes() - .get(AttributeKey.stringKey("key2")))); - })); + metricData -> + assertThat(metricData.getData().getPoints()) + .allMatch( + p -> + "value1" + .equals( + p.getAttributes() + .get(AttributeKey.stringKey("key1"))) + && "value2" + .equals( + p.getAttributes() + .get(AttributeKey.stringKey("key2")))))); } @Test @@ -110,21 +83,23 @@ void testExampleWithAdditionalAttributes2() { TIMED_INSTRUMENTATION_NAME, metric -> metric - .hasName(TIMED_DEFAULT_NAME) + .hasName("example.with.attributes2.duration") .satisfies( - metricData -> { - assertThat(metricData.getData().getPoints()) - .allMatch( - p -> - "value1" - .equals( - p.getAttributes().get(AttributeKey.stringKey("key1"))) - && "value2" - .equals( - p.getAttributes().get(AttributeKey.stringKey("key2"))) - && null - == p.getAttributes().get(AttributeKey.stringKey("key3"))); - })); + metricData -> + assertThat(metricData.getData().getPoints()) + .allMatch( + p -> + "value1" + .equals( + p.getAttributes() + .get(AttributeKey.stringKey("key1"))) + && "value2" + .equals( + p.getAttributes() + .get(AttributeKey.stringKey("key2"))) + && null + == p.getAttributes() + .get(AttributeKey.stringKey("key3"))))); } @Test @@ -145,18 +120,17 @@ void testExampleWithException() { TIMED_INSTRUMENTATION_NAME, metric -> metric - .hasName(TIMED_DEFAULT_NAME) + .hasName("example.with.exception.duration") .satisfies( - metricData -> { - assertThat(metricData.getData().getPoints()) - .allMatch( - p -> - IllegalStateException.class - .getName() - .equals( - p.getAttributes() - .get(AttributeKey.stringKey("exception")))); - })); + metricData -> + assertThat(metricData.getData().getPoints()) + .allMatch( + p -> + IllegalStateException.class + .getName() + .equals( + p.getAttributes() + .get(AttributeKey.stringKey("exception")))))); } @Test @@ -166,15 +140,14 @@ void testExampleWithReturnValueAttribute() { TIMED_INSTRUMENTATION_NAME, metric -> metric - .hasName(TIMED_DEFAULT_NAME) + .hasName("example.with.return.duration") .satisfies( - metricData -> { - assertThat(metricData.getData().getPoints()) - .allMatch( - p -> - TimedExample.RETURN_STRING.equals( - p.getAttributes() - .get(AttributeKey.stringKey("returnValue")))); - })); + metricData -> + assertThat(metricData.getData().getPoints()) + .allMatch( + p -> + TimedExample.RETURN_STRING.equals( + p.getAttributes() + .get(AttributeKey.stringKey("returnValue")))))); } } From 6cdfff94d92eeaac6e1e4ff687c5f9293dbdd285 Mon Sep 17 00:00:00 2001 From: Lauri Tulmin Date: Tue, 18 Jun 2024 13:55:37 +0300 Subject: [PATCH 08/21] change default unit to seconds --- .../instrumentation/annotations/Timed.java | 4 +-- .../v2_6/TimedHelper.java | 29 +++++++++---------- .../v2_6/timed/TimedExample.java | 6 ++-- .../v2_6/timed/TimedInstrumentationTest.java | 15 +++++----- 4 files changed, 27 insertions(+), 27 deletions(-) diff --git a/instrumentation-annotations/src/main/java/io/opentelemetry/instrumentation/annotations/Timed.java b/instrumentation-annotations/src/main/java/io/opentelemetry/instrumentation/annotations/Timed.java index 37d621027c90..7ea5cd22a4ec 100644 --- a/instrumentation-annotations/src/main/java/io/opentelemetry/instrumentation/annotations/Timed.java +++ b/instrumentation-annotations/src/main/java/io/opentelemetry/instrumentation/annotations/Timed.java @@ -55,9 +55,9 @@ /** * The unit for the instrument. * - *

Default is milliseconds. + *

Default is seconds. */ - TimeUnit unit() default TimeUnit.MILLISECONDS; + TimeUnit unit() default TimeUnit.SECONDS; /** * List of key-value pairs to supply additional attributes. diff --git a/instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-2.6/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/v2_6/TimedHelper.java b/instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-2.6/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/v2_6/TimedHelper.java index 634d2d0972f4..f134b61dab1e 100644 --- a/instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-2.6/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/v2_6/TimedHelper.java +++ b/instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-2.6/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/v2_6/TimedHelper.java @@ -56,7 +56,7 @@ private static AttributesBuilder getCommonAttributeBuilder( } private static double getTransformedDuration(long startNanoTime, Timed timedAnnotation) { - TimeUnit unit = extractTimeUnit(timedAnnotation); + TimeUnit unit = timedAnnotation.unit(); long nanoDelta = System.nanoTime() - startNanoTime; return unit.convert(nanoDelta, NANOSECONDS); } @@ -82,33 +82,32 @@ private static DoubleHistogram getHistogram(Method method) { method, m -> { Timed timedAnnotation = m.getAnnotation(Timed.class); - String unitStr = extractUnitStr(timedAnnotation); return METER .histogramBuilder(timedAnnotation.value()) .setDescription(timedAnnotation.description()) - .setUnit(unitStr) + .setUnit(toString(timedAnnotation.unit())) .build(); }); } - private static TimeUnit extractTimeUnit(Timed timedAnnotation) { - if (null == timedAnnotation.unit()) { - return TimeUnit.MILLISECONDS; - } - return timedAnnotation.unit(); - } - - private static String extractUnitStr(Timed timedAnnotation) { - switch (timedAnnotation.unit()) { + private static String toString(TimeUnit timeUnit) { + switch (timeUnit) { case NANOSECONDS: return "ns"; case MICROSECONDS: - return "µs"; + return "us"; + case MILLISECONDS: + return "ms"; case SECONDS: return "s"; - default: - return "ms"; + case MINUTES: + return "min"; + case HOURS: + return "h"; + case DAYS: + return "d"; } + throw new IllegalArgumentException("Unsupported time unit " + timeUnit); } private TimedHelper() {} diff --git a/instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-2.6/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/v2_6/timed/TimedExample.java b/instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-2.6/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/v2_6/timed/TimedExample.java index 1317455c1807..f488223d699a 100644 --- a/instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-2.6/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/v2_6/timed/TimedExample.java +++ b/instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-2.6/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/v2_6/timed/TimedExample.java @@ -14,13 +14,13 @@ public class TimedExample { public static final String RETURN_STRING = "I am a return string."; @Timed(METRIC_NAME) - public void exampleWithAnotherName() {} + public void exampleWithName() {} @Timed(value = "example.with.description.duration", description = METRIC_DESCRIPTION) public void exampleWithDescription() {} - @Timed(value = "example.with.unit.duration", unit = TimeUnit.SECONDS) - public void exampleWithUnitSecondAnd2SecondLatency() throws InterruptedException { + @Timed(value = "example.with.unit.duration", unit = TimeUnit.MILLISECONDS) + public void exampleWithUnit() throws InterruptedException { Thread.sleep(2000); } diff --git a/instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-2.6/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/v2_6/timed/TimedInstrumentationTest.java b/instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-2.6/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/v2_6/timed/TimedInstrumentationTest.java index 0b8727b9725a..b089dcfb8591 100644 --- a/instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-2.6/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/v2_6/timed/TimedInstrumentationTest.java +++ b/instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-2.6/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/v2_6/timed/TimedInstrumentationTest.java @@ -24,9 +24,10 @@ class TimedInstrumentationTest { "io.opentelemetry.opentelemetry-instrumentation-annotations-2.6"; @Test - void testExampleWithAnotherName() { - new TimedExample().exampleWithAnotherName(); - testing.waitAndAssertMetrics(TIMED_INSTRUMENTATION_NAME, metric -> metric.hasName(METRIC_NAME)); + void testExampleWithName() { + new TimedExample().exampleWithName(); + testing.waitAndAssertMetrics( + TIMED_INSTRUMENTATION_NAME, metric -> metric.hasName(METRIC_NAME).hasUnit("s")); } @Test @@ -39,18 +40,18 @@ void testExampleWithDescription() { } @Test - void testExampleWithUnitSecondAnd2SecondLatency() throws InterruptedException { - new TimedExample().exampleWithUnitSecondAnd2SecondLatency(); + void testExampleWithUnit() throws InterruptedException { + new TimedExample().exampleWithUnit(); testing.waitAndAssertMetrics( TIMED_INSTRUMENTATION_NAME, metric -> metric .hasName("example.with.unit.duration") - .hasUnit("s") + .hasUnit("ms") .satisfies( metricData -> assertThat(metricData.getHistogramData().getPoints()) - .allMatch(p -> p.getMax() < 5 && p.getMin() > 0))); + .allMatch(p -> p.getMax() < 5000 && p.getMin() > 0))); } @Test From 771cc58fe5d7902e1ce38bcbce2f14bbac55eb04 Mon Sep 17 00:00:00 2001 From: Lauri Tulmin Date: Tue, 18 Jun 2024 15:59:31 +0300 Subject: [PATCH 09/21] resue code from @WithSpan implementation to extract method paramter attibutes --- .../v2_6/MetricsAnnotationHelper.java | 47 +++++++++++++------ 1 file changed, 32 insertions(+), 15 deletions(-) diff --git a/instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-2.6/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/v2_6/MetricsAnnotationHelper.java b/instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-2.6/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/v2_6/MetricsAnnotationHelper.java index 242ed70ab70b..c1fff4fc5f36 100644 --- a/instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-2.6/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/v2_6/MetricsAnnotationHelper.java +++ b/instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-2.6/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/v2_6/MetricsAnnotationHelper.java @@ -9,31 +9,21 @@ import io.opentelemetry.api.GlobalOpenTelemetry; import io.opentelemetry.api.common.AttributesBuilder; import io.opentelemetry.api.metrics.Meter; +import io.opentelemetry.instrumentation.api.annotation.support.SpanAttributesExtractor; import io.opentelemetry.javaagent.instrumentation.instrumentationannotations.MethodRequest; import java.lang.reflect.Parameter; +import javax.annotation.Nullable; public abstract class MetricsAnnotationHelper { private static final String INSTRUMENTATION_NAME = "io.opentelemetry.opentelemetry-instrumentation-annotations-2.6"; static final Meter METER = GlobalOpenTelemetry.get().getMeter(INSTRUMENTATION_NAME); + private static final SpanAttributesExtractor PARAMETER_ATTRIBUTES = createAttributesExtractor(); static void extractMetricAttributes( MethodRequest methodRequest, AttributesBuilder attributesBuilder) { - Parameter[] parameters = methodRequest.method().getParameters(); - for (int i = 0; i < parameters.length; i++) { - if (parameters[i].isAnnotationPresent(MetricAttribute.class)) { - MetricAttribute annotation = parameters[i].getAnnotation(MetricAttribute.class); - String attributeKey; - if (!annotation.value().isEmpty()) { - attributeKey = annotation.value(); - } else if (parameters[i].isNamePresent()) { - attributeKey = parameters[i].getName(); - } else { - continue; - } - attributesBuilder.put(attributeKey, methodRequest.args()[i].toString()); - } - } + attributesBuilder.putAll( + PARAMETER_ATTRIBUTES.extract(methodRequest.method(), methodRequest.args())); } static void extractAdditionAttributes(String[] attributes, AttributesBuilder attributesBuilder) { @@ -42,4 +32,31 @@ static void extractAdditionAttributes(String[] attributes, AttributesBuilder att attributesBuilder.put(attributes[i], attributes[i + 1]); } } + + private static SpanAttributesExtractor createAttributesExtractor() { + return SpanAttributesExtractor.create( + (method, parameters) -> { + String[] attributeNames = new String[parameters.length]; + for (int i = 0; i < parameters.length; i++) { + attributeNames[i] = attributeName(parameters[i]); + } + return attributeNames; + }); + } + + @Nullable + private static String attributeName(Parameter parameter) { + MetricAttribute annotation = parameter.getDeclaredAnnotation(MetricAttribute.class); + if (annotation == null) { + return null; + } + String value = annotation.value(); + if (!value.isEmpty()) { + return value; + } else if (parameter.isNamePresent()) { + return parameter.getName(); + } else { + return null; + } + } } From 42aa73b74f902a1fb0979159644ac5f02efd3d04 Mon Sep 17 00:00:00 2001 From: Lauri Tulmin Date: Tue, 18 Jun 2024 16:13:47 +0300 Subject: [PATCH 10/21] fractional duration --- .../instrumentationannotations/v2_6/TimedHelper.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-2.6/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/v2_6/TimedHelper.java b/instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-2.6/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/v2_6/TimedHelper.java index f134b61dab1e..43c0a701fb20 100644 --- a/instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-2.6/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/v2_6/TimedHelper.java +++ b/instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-2.6/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/v2_6/TimedHelper.java @@ -58,7 +58,7 @@ private static AttributesBuilder getCommonAttributeBuilder( private static double getTransformedDuration(long startNanoTime, Timed timedAnnotation) { TimeUnit unit = timedAnnotation.unit(); long nanoDelta = System.nanoTime() - startNanoTime; - return unit.convert(nanoDelta, NANOSECONDS); + return (double) nanoDelta / NANOSECONDS.convert(1, unit); } private static void extractException(Throwable throwable, AttributesBuilder attributesBuilder) { From c9ea9a0d060688730b97e5088fbba87584b855a1 Mon Sep 17 00:00:00 2001 From: Lauri Tulmin Date: Tue, 18 Jun 2024 19:24:35 +0300 Subject: [PATCH 11/21] update samples --- .../instrumentation/annotations/CountedUsageExamples.java | 7 ++----- .../instrumentation/annotations/TimedUsageExamples.java | 7 ++----- 2 files changed, 4 insertions(+), 10 deletions(-) diff --git a/instrumentation-annotations/src/test/java/io/opentelemetry/instrumentation/annotations/CountedUsageExamples.java b/instrumentation-annotations/src/test/java/io/opentelemetry/instrumentation/annotations/CountedUsageExamples.java index 46189a4932b1..35b66aeeeeeb 100644 --- a/instrumentation-annotations/src/test/java/io/opentelemetry/instrumentation/annotations/CountedUsageExamples.java +++ b/instrumentation-annotations/src/test/java/io/opentelemetry/instrumentation/annotations/CountedUsageExamples.java @@ -7,13 +7,10 @@ public class CountedUsageExamples { - @Counted() - public void method1() {} - @Counted("customizedName") - public void method2() {} + public void method() {} - @Counted + @Counted("methodWithAttributes") public void attributes( @MetricAttribute String attribute1, @MetricAttribute("attribute2") long attribute2) {} } diff --git a/instrumentation-annotations/src/test/java/io/opentelemetry/instrumentation/annotations/TimedUsageExamples.java b/instrumentation-annotations/src/test/java/io/opentelemetry/instrumentation/annotations/TimedUsageExamples.java index f9fc6ee8c87e..7d33d0adf4f9 100644 --- a/instrumentation-annotations/src/test/java/io/opentelemetry/instrumentation/annotations/TimedUsageExamples.java +++ b/instrumentation-annotations/src/test/java/io/opentelemetry/instrumentation/annotations/TimedUsageExamples.java @@ -7,13 +7,10 @@ public class TimedUsageExamples { - @Timed() - public void method1() {} - @Timed("customizedName") - public void method2() {} + public void method() {} - @Timed + @Timed("methodWithAttributes") public void attributes( @MetricAttribute String attribute1, @MetricAttribute("attribute2") long attribute2) {} } From 43855a5279a866ca692ee8db99750cfe7feb4382 Mon Sep 17 00:00:00 2001 From: Lauri Tulmin Date: Wed, 19 Jun 2024 16:05:27 +0300 Subject: [PATCH 12/21] handle async methods --- .../async/AsyncOperationEndHandler.java | 15 ++++++ .../async/AsyncOperationEndStrategy.java | 30 ++++++++++- .../async/AsyncOperationEndSupport.java | 45 +++++++++++----- .../async/Jdk8AsyncOperationEndStrategy.java | 19 ++++--- .../v10_0/GuavaAsyncOperationEndStrategy.java | 17 +++--- .../javaagent-kotlin/build.gradle.kts | 1 + .../kotlinxcoroutines/flow/FlowUtil.kt | 6 +-- .../flow/FlowInstrumentationHelper.java | 6 +-- .../v2_6/CountedHelper.java | 44 ++++++++++----- .../v2_6/CountedInstrumentation.java | 19 ++----- .../v2_6/TimedHelper.java | 53 +++++++++++++------ .../v2_6/TimedInstrumentation.java | 11 ++-- .../v2_6/counted/CountedExample.java | 6 +++ .../counted/CountedInstrumentationTest.java | 27 ++++++++++ .../v2_6/timed/TimedExample.java | 6 +++ .../v2_6/timed/TimedInstrumentationTest.java | 27 ++++++++++ .../ReactorAsyncOperationEndStrategy.java | 6 +-- .../RxJava2AsyncOperationEndStrategy.java | 6 +-- .../RxJava3AsyncOperationEndStrategy.java | 6 +-- 19 files changed, 249 insertions(+), 101 deletions(-) create mode 100644 instrumentation-annotations-support/src/main/java/io/opentelemetry/instrumentation/api/annotation/support/async/AsyncOperationEndHandler.java diff --git a/instrumentation-annotations-support/src/main/java/io/opentelemetry/instrumentation/api/annotation/support/async/AsyncOperationEndHandler.java b/instrumentation-annotations-support/src/main/java/io/opentelemetry/instrumentation/api/annotation/support/async/AsyncOperationEndHandler.java new file mode 100644 index 000000000000..0d82aa16aa8b --- /dev/null +++ b/instrumentation-annotations-support/src/main/java/io/opentelemetry/instrumentation/api/annotation/support/async/AsyncOperationEndHandler.java @@ -0,0 +1,15 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.instrumentation.api.annotation.support.async; + +import io.opentelemetry.context.Context; +import javax.annotation.Nullable; + +/** Callback that is called when async computation completes. */ +public interface AsyncOperationEndHandler { + void handle( + Context context, REQUEST request, @Nullable RESPONSE response, @Nullable Throwable error); +} diff --git a/instrumentation-annotations-support/src/main/java/io/opentelemetry/instrumentation/api/annotation/support/async/AsyncOperationEndStrategy.java b/instrumentation-annotations-support/src/main/java/io/opentelemetry/instrumentation/api/annotation/support/async/AsyncOperationEndStrategy.java index 01dbaa55eef5..d3bba94fbe6c 100644 --- a/instrumentation-annotations-support/src/main/java/io/opentelemetry/instrumentation/api/annotation/support/async/AsyncOperationEndStrategy.java +++ b/instrumentation-annotations-support/src/main/java/io/opentelemetry/instrumentation/api/annotation/support/async/AsyncOperationEndStrategy.java @@ -11,7 +11,8 @@ /** * Implementations of this interface describe how to compose over {@linkplain #supports(Class) * supported} asynchronous computation types and delay marking the operation as ended by calling - * {@link Instrumenter#end(Context, Object, Object, Throwable)}. + * {@link Instrumenter#end(Context, Object, Object, Throwable)} or {@link + * AsyncOperationEndHandler#handle(Context, Object, Object, Throwable)}. */ public interface AsyncOperationEndStrategy { @@ -36,10 +37,35 @@ public interface AsyncOperationEndStrategy { * @return Either {@code asyncValue} or a value composing over {@code asyncValue} for notification * of completion. */ - Object end( + default Object end( Instrumenter instrumenter, Context context, REQUEST request, Object asyncValue, + Class responseType) { + return end(instrumenter::end, context, request, asyncValue, responseType); + } + + /** + * Composes over {@code asyncValue} and delays the {@link AsyncOperationEndHandler#handle(Context, + * Object, Object, Throwable)} call until after the asynchronous operation represented by {@code + * asyncValue} completes. + * + * @param handler The {@link AsyncOperationEndHandler} to be used to end the operation stored in + * the {@code context}. + * @param asyncValue Return value from the instrumented method. Must be an instance of a {@code + * asyncType} for which {@link #supports(Class)} returned true (in particular it must not be + * {@code null}). + * @param responseType Expected type of the response that should be obtained from the {@code + * asyncValue}. If the result of the async computation is instance of the passed type it will + * be passed when the {@code handler} is called. + * @return Either {@code asyncValue} or a value composing over {@code asyncValue} for notification + * of completion. + */ + Object end( + AsyncOperationEndHandler handler, + Context context, + REQUEST request, + Object asyncValue, Class responseType); } diff --git a/instrumentation-annotations-support/src/main/java/io/opentelemetry/instrumentation/api/annotation/support/async/AsyncOperationEndSupport.java b/instrumentation-annotations-support/src/main/java/io/opentelemetry/instrumentation/api/annotation/support/async/AsyncOperationEndSupport.java index 8bcbd5c3f978..50edfb7ab051 100644 --- a/instrumentation-annotations-support/src/main/java/io/opentelemetry/instrumentation/api/annotation/support/async/AsyncOperationEndSupport.java +++ b/instrumentation-annotations-support/src/main/java/io/opentelemetry/instrumentation/api/annotation/support/async/AsyncOperationEndSupport.java @@ -10,40 +10,59 @@ import javax.annotation.Nullable; /** - * A wrapper over {@link Instrumenter} that is able to defer {@link Instrumenter#end(Context, - * Object, Object, Throwable)} until asynchronous computation finishes. + * A wrapper over {@link AsyncOperationEndHandler} that is able to defer {@link + * AsyncOperationEndHandler#handle(Context, Object, Object, Throwable)} until asynchronous + * computation finishes. */ public final class AsyncOperationEndSupport { /** - * Returns a new {@link AsyncOperationEndSupport} that wraps over passed {@code syncInstrumenter}, + * Returns a new {@link AsyncOperationEndSupport} that wraps over passed {@code instrumenter}, * configured for usage with asynchronous computations that are instances of {@code asyncType}. If * the result of the async computation ends up being an instance of {@code responseType} it will - * be passed as the response to the {@code syncInstrumenter} call; otherwise {@code null} value - * will be used as the response. + * be passed as the response to the {@code instrumenter} call; otherwise {@code null} value will + * be used as the response. */ public static AsyncOperationEndSupport create( - Instrumenter syncInstrumenter, + Instrumenter instrumenter, Class responseType, Class asyncType) { return new AsyncOperationEndSupport<>( - syncInstrumenter, + instrumenter::end, responseType, asyncType, AsyncOperationEndStrategies.instance().resolveStrategy(asyncType)); } - private final Instrumenter instrumenter; + /** + * Returns a new {@link AsyncOperationEndSupport} that wraps over passed {@code handler}, + * configured for usage with asynchronous computations that are instances of {@code asyncType}. If + * the result of the async computation ends up being an instance of {@code responseType} it will + * be passed as the response to the {@code handler} call; otherwise {@code null} value will be + * used as the response. + */ + public static AsyncOperationEndSupport create( + AsyncOperationEndHandler handler, + Class responseType, + Class asyncType) { + return new AsyncOperationEndSupport<>( + handler, + responseType, + asyncType, + AsyncOperationEndStrategies.instance().resolveStrategy(asyncType)); + } + + private final AsyncOperationEndHandler handler; private final Class responseType; private final Class asyncType; @Nullable private final AsyncOperationEndStrategy asyncOperationEndStrategy; private AsyncOperationEndSupport( - Instrumenter instrumenter, + AsyncOperationEndHandler handler, Class responseType, Class asyncType, @Nullable AsyncOperationEndStrategy asyncOperationEndStrategy) { - this.instrumenter = instrumenter; + this.handler = handler; this.responseType = responseType; this.asyncType = asyncType; this.asyncOperationEndStrategy = asyncOperationEndStrategy; @@ -68,18 +87,18 @@ public ASYNC asyncEnd( Context context, REQUEST request, @Nullable ASYNC asyncValue, @Nullable Throwable throwable) { // we can end early if an exception was thrown if (throwable != null) { - instrumenter.end(context, request, null, throwable); + handler.handle(context, request, null, throwable); return asyncValue; } // use the configured strategy to compose over the asyncValue if (asyncOperationEndStrategy != null && asyncType.isInstance(asyncValue)) { return (ASYNC) - asyncOperationEndStrategy.end(instrumenter, context, request, asyncValue, responseType); + asyncOperationEndStrategy.end(handler, context, request, asyncValue, responseType); } // fall back to sync end() if asyncValue type doesn't match - instrumenter.end(context, request, tryToGetResponse(responseType, asyncValue), null); + handler.handle(context, request, tryToGetResponse(responseType, asyncValue), null); return asyncValue; } diff --git a/instrumentation-annotations-support/src/main/java/io/opentelemetry/instrumentation/api/annotation/support/async/Jdk8AsyncOperationEndStrategy.java b/instrumentation-annotations-support/src/main/java/io/opentelemetry/instrumentation/api/annotation/support/async/Jdk8AsyncOperationEndStrategy.java index c1eea3a419ed..38498bbbe894 100644 --- a/instrumentation-annotations-support/src/main/java/io/opentelemetry/instrumentation/api/annotation/support/async/Jdk8AsyncOperationEndStrategy.java +++ b/instrumentation-annotations-support/src/main/java/io/opentelemetry/instrumentation/api/annotation/support/async/Jdk8AsyncOperationEndStrategy.java @@ -8,7 +8,6 @@ import static io.opentelemetry.instrumentation.api.annotation.support.async.AsyncOperationEndSupport.tryToGetResponse; import io.opentelemetry.context.Context; -import io.opentelemetry.instrumentation.api.instrumenter.Instrumenter; import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletionStage; @@ -22,20 +21,20 @@ public boolean supports(Class asyncType) { @Override public Object end( - Instrumenter instrumenter, + AsyncOperationEndHandler handler, Context context, REQUEST request, Object asyncValue, Class responseType) { if (asyncValue instanceof CompletableFuture) { CompletableFuture future = (CompletableFuture) asyncValue; - if (tryToEndSynchronously(instrumenter, context, request, future, responseType)) { + if (tryToEndSynchronously(handler, context, request, future, responseType)) { return future; } - return endWhenComplete(instrumenter, context, request, future, responseType); + return endWhenComplete(handler, context, request, future, responseType); } CompletionStage stage = (CompletionStage) asyncValue; - return endWhenComplete(instrumenter, context, request, stage, responseType); + return endWhenComplete(handler, context, request, stage, responseType); } /** @@ -44,7 +43,7 @@ public Object end( * notification of completion. */ private static boolean tryToEndSynchronously( - Instrumenter instrumenter, + AsyncOperationEndHandler handler, Context context, REQUEST request, CompletableFuture future, @@ -56,9 +55,9 @@ private static boolean tryToEndSynchronously( try { Object potentialResponse = future.join(); - instrumenter.end(context, request, tryToGetResponse(responseType, potentialResponse), null); + handler.handle(context, request, tryToGetResponse(responseType, potentialResponse), null); } catch (Throwable t) { - instrumenter.end(context, request, null, t); + handler.handle(context, request, null, t); } return true; } @@ -68,13 +67,13 @@ private static boolean tryToEndSynchronously( * span will be ended. */ private static CompletionStage endWhenComplete( - Instrumenter instrumenter, + AsyncOperationEndHandler handler, Context context, REQUEST request, CompletionStage stage, Class responseType) { return stage.whenComplete( (result, exception) -> - instrumenter.end(context, request, tryToGetResponse(responseType, result), exception)); + handler.handle(context, request, tryToGetResponse(responseType, result), exception)); } } diff --git a/instrumentation/guava-10.0/library/src/main/java/io/opentelemetry/instrumentation/guava/v10_0/GuavaAsyncOperationEndStrategy.java b/instrumentation/guava-10.0/library/src/main/java/io/opentelemetry/instrumentation/guava/v10_0/GuavaAsyncOperationEndStrategy.java index dbdbff784728..24287d362804 100644 --- a/instrumentation/guava-10.0/library/src/main/java/io/opentelemetry/instrumentation/guava/v10_0/GuavaAsyncOperationEndStrategy.java +++ b/instrumentation/guava-10.0/library/src/main/java/io/opentelemetry/instrumentation/guava/v10_0/GuavaAsyncOperationEndStrategy.java @@ -12,8 +12,8 @@ import io.opentelemetry.api.common.AttributeKey; import io.opentelemetry.api.trace.Span; import io.opentelemetry.context.Context; +import io.opentelemetry.instrumentation.api.annotation.support.async.AsyncOperationEndHandler; import io.opentelemetry.instrumentation.api.annotation.support.async.AsyncOperationEndStrategy; -import io.opentelemetry.instrumentation.api.instrumenter.Instrumenter; public final class GuavaAsyncOperationEndStrategy implements AsyncOperationEndStrategy { // Visible for testing @@ -41,19 +41,19 @@ public boolean supports(Class returnType) { @Override public Object end( - Instrumenter instrumenter, + AsyncOperationEndHandler handler, Context context, REQUEST request, Object asyncValue, Class responseType) { ListenableFuture future = (ListenableFuture) asyncValue; - end(instrumenter, context, request, future, responseType); + end(handler, context, request, future, responseType); return future; } private void end( - Instrumenter instrumenter, + AsyncOperationEndHandler handler, Context context, REQUEST request, ListenableFuture future, @@ -63,18 +63,17 @@ private void end( if (captureExperimentalSpanAttributes) { Span.fromContext(context).setAttribute(CANCELED_ATTRIBUTE_KEY, true); } - instrumenter.end(context, request, null, null); + handler.handle(context, request, null, null); } else { try { Object response = Uninterruptibles.getUninterruptibly(future); - instrumenter.end(context, request, tryToGetResponse(responseType, response), null); + handler.handle(context, request, tryToGetResponse(responseType, response), null); } catch (Throwable exception) { - instrumenter.end(context, request, null, exception); + handler.handle(context, request, null, exception); } } } else { - future.addListener( - () -> end(instrumenter, context, request, future, responseType), Runnable::run); + future.addListener(() -> end(handler, context, request, future, responseType), Runnable::run); } } } diff --git a/instrumentation/kotlinx-coroutines/kotlinx-coroutines-flow-1.3/javaagent-kotlin/build.gradle.kts b/instrumentation/kotlinx-coroutines/kotlinx-coroutines-flow-1.3/javaagent-kotlin/build.gradle.kts index 755a2a9fa85f..1aa3ece053e8 100644 --- a/instrumentation/kotlinx-coroutines/kotlinx-coroutines-flow-1.3/javaagent-kotlin/build.gradle.kts +++ b/instrumentation/kotlinx-coroutines/kotlinx-coroutines-flow-1.3/javaagent-kotlin/build.gradle.kts @@ -12,6 +12,7 @@ dependencies { compileOnly("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.3.0") compileOnly("org.jetbrains.kotlin:kotlin-stdlib-jdk8") compileOnly(project(":instrumentation-api")) + compileOnly(project(":instrumentation-annotations-support")) } kotlin { diff --git a/instrumentation/kotlinx-coroutines/kotlinx-coroutines-flow-1.3/javaagent-kotlin/src/main/kotlin/io/opentelemetry/javaagent/instrumentation/kotlinxcoroutines/flow/FlowUtil.kt b/instrumentation/kotlinx-coroutines/kotlinx-coroutines-flow-1.3/javaagent-kotlin/src/main/kotlin/io/opentelemetry/javaagent/instrumentation/kotlinxcoroutines/flow/FlowUtil.kt index 65008f55ca62..9e44348e3f4c 100644 --- a/instrumentation/kotlinx-coroutines/kotlinx-coroutines-flow-1.3/javaagent-kotlin/src/main/kotlin/io/opentelemetry/javaagent/instrumentation/kotlinxcoroutines/flow/FlowUtil.kt +++ b/instrumentation/kotlinx-coroutines/kotlinx-coroutines-flow-1.3/javaagent-kotlin/src/main/kotlin/io/opentelemetry/javaagent/instrumentation/kotlinxcoroutines/flow/FlowUtil.kt @@ -6,12 +6,12 @@ package io.opentelemetry.javaagent.instrumentation.kotlinxcoroutines.flow import io.opentelemetry.context.Context -import io.opentelemetry.instrumentation.api.instrumenter.Instrumenter +import io.opentelemetry.instrumentation.api.annotation.support.async.AsyncOperationEndHandler import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.onCompletion -fun onComplete(flow: Flow<*>, instrumenter: Instrumenter, context: Context, request: REQUEST & Any): Flow<*> { +fun onComplete(flow: Flow<*>, handler: AsyncOperationEndHandler, context: Context, request: REQUEST & Any): Flow<*> { return flow.onCompletion { cause: Throwable? -> - instrumenter.end(context, request, null, cause) + handler.handle(context, request, null, cause) } } diff --git a/instrumentation/kotlinx-coroutines/kotlinx-coroutines-flow-1.3/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/kotlinxcoroutines/flow/FlowInstrumentationHelper.java b/instrumentation/kotlinx-coroutines/kotlinx-coroutines-flow-1.3/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/kotlinxcoroutines/flow/FlowInstrumentationHelper.java index 02102afe01d0..0f0206d8c9fc 100644 --- a/instrumentation/kotlinx-coroutines/kotlinx-coroutines-flow-1.3/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/kotlinxcoroutines/flow/FlowInstrumentationHelper.java +++ b/instrumentation/kotlinx-coroutines/kotlinx-coroutines-flow-1.3/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/kotlinxcoroutines/flow/FlowInstrumentationHelper.java @@ -6,9 +6,9 @@ package io.opentelemetry.javaagent.instrumentation.kotlinxcoroutines.flow; import io.opentelemetry.context.Context; +import io.opentelemetry.instrumentation.api.annotation.support.async.AsyncOperationEndHandler; import io.opentelemetry.instrumentation.api.annotation.support.async.AsyncOperationEndStrategies; import io.opentelemetry.instrumentation.api.annotation.support.async.AsyncOperationEndStrategy; -import io.opentelemetry.instrumentation.api.instrumenter.Instrumenter; import kotlinx.coroutines.flow.Flow; public final class FlowInstrumentationHelper { @@ -32,13 +32,13 @@ public boolean supports(Class returnType) { @Override public Object end( - Instrumenter instrumenter, + AsyncOperationEndHandler handler, Context context, REQUEST request, Object asyncValue, Class responseType) { Flow flow = (Flow) asyncValue; - return FlowUtilKt.onComplete(flow, instrumenter, context, request); + return FlowUtilKt.onComplete(flow, handler, context, request); } } } diff --git a/instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-2.6/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/v2_6/CountedHelper.java b/instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-2.6/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/v2_6/CountedHelper.java index e87a44e09f6f..6fc4dcfb997a 100644 --- a/instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-2.6/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/v2_6/CountedHelper.java +++ b/instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-2.6/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/v2_6/CountedHelper.java @@ -9,10 +9,13 @@ import io.opentelemetry.api.common.Attributes; import io.opentelemetry.api.common.AttributesBuilder; import io.opentelemetry.api.metrics.LongCounter; +import io.opentelemetry.context.Context; +import io.opentelemetry.instrumentation.api.annotation.support.async.AsyncOperationEndSupport; import io.opentelemetry.javaagent.instrumentation.instrumentationannotations.MethodRequest; import java.lang.reflect.Method; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; +import java.util.function.Consumer; public final class CountedHelper extends MetricsAnnotationHelper { @@ -24,20 +27,36 @@ protected Map computeValue(Class type) { } }; - public static void recordCountWithAttributes( + public static Object recordCountWithAttributes( MethodRequest methodRequest, Object returnValue, Throwable throwable) { - Counted countedAnnotation = methodRequest.method().getAnnotation(Counted.class); - AttributesBuilder attributesBuilder = - getCommonAttributesBuilder(countedAnnotation, returnValue, throwable); - extractMetricAttributes(methodRequest, attributesBuilder); - getCounter(methodRequest.method()).add(1, attributesBuilder.build()); + return recordCount( + methodRequest.method(), + returnValue, + throwable, + attributesBuilder -> extractMetricAttributes(methodRequest, attributesBuilder)); } - public static void recordCount(Method method, Object returnValue, Throwable throwable) { - Counted countedAnnotation = method.getAnnotation(Counted.class); - AttributesBuilder attributesBuilder = - getCommonAttributesBuilder(countedAnnotation, returnValue, throwable); - getCounter(method).add(1, attributesBuilder.build()); + public static Object recordCount(Method method, Object returnValue, Throwable throwable) { + return recordCount(method, returnValue, throwable, attributesBuilder -> {}); + } + + private static Object recordCount( + Method method, + Object returnValue, + Throwable throwable, + Consumer additionalAttributes) { + AsyncOperationEndSupport operationEndSupport = + AsyncOperationEndSupport.create( + (context, method1, object, error) -> { + Counted countedAnnotation = method1.getAnnotation(Counted.class); + AttributesBuilder attributesBuilder = + getCommonAttributesBuilder(countedAnnotation, object, error); + additionalAttributes.accept(attributesBuilder); + getCounter(method1).add(1, attributesBuilder.build()); + }, + Object.class, + method.getReturnType()); + return operationEndSupport.asyncEnd(Context.current(), method, returnValue, throwable); } private static AttributesBuilder getCommonAttributesBuilder( @@ -57,8 +76,7 @@ private static void extractException(Throwable throwable, AttributesBuilder attr private static void extractReturnValue( Counted countedAnnotation, Object returnValue, AttributesBuilder attributesBuilder) { - if (null != countedAnnotation.returnValueAttribute() - && !countedAnnotation.returnValueAttribute().isEmpty()) { + if (returnValue != null && !countedAnnotation.returnValueAttribute().isEmpty()) { attributesBuilder.put(countedAnnotation.returnValueAttribute(), returnValue.toString()); } } diff --git a/instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-2.6/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/v2_6/CountedInstrumentation.java b/instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-2.6/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/v2_6/CountedInstrumentation.java index 51703ab0cb67..9491592b6d37 100644 --- a/instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-2.6/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/v2_6/CountedInstrumentation.java +++ b/instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-2.6/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/v2_6/CountedInstrumentation.java @@ -77,43 +77,32 @@ public static class CountedAttributesAdvice { @Advice.OnMethodEnter(suppress = Throwable.class) public static void onEnter( - @Advice.Origin Method originMethod, - @Advice.Local("otelMethod") Method method, + @Advice.Origin Method method, @Advice.AllArguments(typing = Assigner.Typing.DYNAMIC) Object[] args, @Advice.Local("otelRequest") MethodRequest request) { - // Every usage of @Advice.Origin Method is replaced with a call to Class.getMethod, copy it // to local variable so that there would be only one call to Class.getMethod. - method = originMethod; request = new MethodRequest(method, args); } @Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class) public static void onExit( - @Advice.Local("otelMethod") Method method, @Advice.Local("otelRequest") MethodRequest request, @Advice.Return(typing = Assigner.Typing.DYNAMIC, readOnly = false) Object returnValue, @Advice.Thrown Throwable throwable) { - CountedHelper.recordCountWithAttributes(request, returnValue, throwable); + returnValue = CountedHelper.recordCountWithAttributes(request, returnValue, throwable); } } @SuppressWarnings("unused") public static class CountedAdvice { - @Advice.OnMethodEnter(suppress = Throwable.class) - public static void onEnter( - @Advice.Origin Method originMethod, @Advice.Local("otelMethod") Method method) { - // Every usage of @Advice.Origin Method is replaced with a call to Class.getMethod, copy it - // to local variable so that there would be only one call to Class.getMethod. - method = originMethod; - } @Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class) public static void onExit( - @Advice.Local("otelMethod") Method method, + @Advice.Origin Method method, @Advice.Return(typing = Assigner.Typing.DYNAMIC, readOnly = false) Object returnValue, @Advice.Thrown Throwable throwable) { - CountedHelper.recordCount(method, returnValue, throwable); + returnValue = CountedHelper.recordCount(method, returnValue, throwable); } } } diff --git a/instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-2.6/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/v2_6/TimedHelper.java b/instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-2.6/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/v2_6/TimedHelper.java index 43c0a701fb20..38e470b37d0e 100644 --- a/instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-2.6/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/v2_6/TimedHelper.java +++ b/instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-2.6/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/v2_6/TimedHelper.java @@ -11,11 +11,14 @@ import io.opentelemetry.api.common.Attributes; import io.opentelemetry.api.common.AttributesBuilder; import io.opentelemetry.api.metrics.DoubleHistogram; +import io.opentelemetry.context.Context; +import io.opentelemetry.instrumentation.api.annotation.support.async.AsyncOperationEndSupport; import io.opentelemetry.javaagent.instrumentation.instrumentationannotations.MethodRequest; import java.lang.reflect.Method; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.TimeUnit; +import java.util.function.Consumer; public final class TimedHelper extends MetricsAnnotationHelper { @@ -27,23 +30,40 @@ protected Map computeValue(Class type) { } }; - public static void recordHistogramWithAttributes( - MethodRequest methodRequest, Throwable throwable, Object returnValue, long startNanoTime) { - Timed timedAnnotation = methodRequest.method().getAnnotation(Timed.class); - AttributesBuilder attributesBuilder = - getCommonAttributeBuilder(throwable, returnValue, timedAnnotation); - double duration = getTransformedDuration(startNanoTime, timedAnnotation); - extractMetricAttributes(methodRequest, attributesBuilder); - getHistogram(methodRequest.method()).record(duration, attributesBuilder.build()); + public static Object recordHistogramWithAttributes( + MethodRequest methodRequest, Object returnValue, Throwable throwable, long startNanoTime) { + return recordHistogram( + methodRequest.method(), + returnValue, + throwable, + startNanoTime, + attributesBuilder -> extractMetricAttributes(methodRequest, attributesBuilder)); } - public static void recordHistogram( - Method method, Throwable throwable, Object returnValue, long startNanoTime) { - Timed timedAnnotation = method.getAnnotation(Timed.class); - AttributesBuilder attributesBuilder = - getCommonAttributeBuilder(throwable, returnValue, timedAnnotation); - double duration = getTransformedDuration(startNanoTime, timedAnnotation); - getHistogram(method).record(duration, attributesBuilder.build()); + public static Object recordHistogram( + Method method, Object returnValue, Throwable throwable, long startNanoTime) { + return recordHistogram(method, returnValue, throwable, startNanoTime, attributesBuilder -> {}); + } + + public static Object recordHistogram( + Method method, + Object returnValue, + Throwable throwable, + long startNanoTime, + Consumer additionalAttributes) { + AsyncOperationEndSupport operationEndSupport = + AsyncOperationEndSupport.create( + (context, method1, object, error) -> { + Timed timedAnnotation = method.getAnnotation(Timed.class); + AttributesBuilder attributesBuilder = + getCommonAttributeBuilder(error, object, timedAnnotation); + additionalAttributes.accept(attributesBuilder); + double duration = getTransformedDuration(startNanoTime, timedAnnotation); + getHistogram(method).record(duration, attributesBuilder.build()); + }, + Object.class, + method.getReturnType()); + return operationEndSupport.asyncEnd(Context.current(), method, returnValue, throwable); } private static AttributesBuilder getCommonAttributeBuilder( @@ -69,8 +89,7 @@ private static void extractException(Throwable throwable, AttributesBuilder attr private static void extractReturnValue( Timed countedAnnotation, Object returnValue, AttributesBuilder attributesBuilder) { - if (null != countedAnnotation.returnValueAttribute() - && !countedAnnotation.returnValueAttribute().isEmpty()) { + if (returnValue != null && !countedAnnotation.returnValueAttribute().isEmpty()) { attributesBuilder.put(countedAnnotation.returnValueAttribute(), returnValue.toString()); } } diff --git a/instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-2.6/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/v2_6/TimedInstrumentation.java b/instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-2.6/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/v2_6/TimedInstrumentation.java index a31237351edb..6a40c70125bb 100644 --- a/instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-2.6/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/v2_6/TimedInstrumentation.java +++ b/instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-2.6/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/v2_6/TimedInstrumentation.java @@ -77,27 +77,24 @@ public static class TimedAttributesAdvice { @Advice.OnMethodEnter(suppress = Throwable.class) public static void onEnter( - @Advice.Origin Method originMethod, - @Advice.Local("otelMethod") Method method, + @Advice.Origin Method method, @Advice.AllArguments(typing = Assigner.Typing.DYNAMIC) Object[] args, @Advice.Local("otelRequest") MethodRequest request, @Advice.Local("startNanoTime") long startNanoTime) { - // Every usage of @Advice.Origin Method is replaced with a call to Class.getMethod, copy it // to local variable so that there would be only one call to Class.getMethod. - method = originMethod; request = new MethodRequest(method, args); startNanoTime = System.nanoTime(); } @Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class) public static void onExit( - @Advice.Local("otelMethod") Method method, @Advice.Local("otelRequest") MethodRequest request, @Advice.Local("startNanoTime") long startNanoTime, @Advice.Return(typing = Assigner.Typing.DYNAMIC, readOnly = false) Object returnValue, @Advice.Thrown Throwable throwable) { - TimedHelper.recordHistogramWithAttributes(request, throwable, returnValue, startNanoTime); + returnValue = + TimedHelper.recordHistogramWithAttributes(request, returnValue, throwable, startNanoTime); } } @@ -121,7 +118,7 @@ public static void onExit( @Advice.Local("startNanoTime") long startNanoTime, @Advice.Return(typing = Assigner.Typing.DYNAMIC, readOnly = false) Object returnValue, @Advice.Thrown Throwable throwable) { - TimedHelper.recordHistogram(method, throwable, returnValue, startNanoTime); + returnValue = TimedHelper.recordHistogram(method, returnValue, throwable, startNanoTime); } } } diff --git a/instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-2.6/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/v2_6/counted/CountedExample.java b/instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-2.6/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/v2_6/counted/CountedExample.java index 840f845d2a46..10e8a8d2d51a 100644 --- a/instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-2.6/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/v2_6/counted/CountedExample.java +++ b/instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-2.6/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/v2_6/counted/CountedExample.java @@ -6,6 +6,7 @@ package io.opentelemetry.javaagent.instrumentation.instrumentationannotations.v2_6.counted; import io.opentelemetry.instrumentation.annotations.Counted; +import java.util.concurrent.CompletableFuture; public class CountedExample { @@ -46,6 +47,11 @@ public void exampleWithException() { @Counted("example.ignore.count") public void exampleIgnore() {} + @Counted(value = "example.completable.future.count", returnValueAttribute = "returnValue") + public CompletableFuture completableFuture(CompletableFuture future) { + return future; + } + public static class ReturnObject { @Override public String toString() { diff --git a/instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-2.6/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/v2_6/counted/CountedInstrumentationTest.java b/instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-2.6/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/v2_6/counted/CountedInstrumentationTest.java index 6bf61f72d085..886f62ebc26d 100644 --- a/instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-2.6/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/v2_6/counted/CountedInstrumentationTest.java +++ b/instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-2.6/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/v2_6/counted/CountedInstrumentationTest.java @@ -12,6 +12,7 @@ import io.opentelemetry.api.common.AttributeKey; import io.opentelemetry.instrumentation.testing.junit.AgentInstrumentationExtension; +import java.util.concurrent.CompletableFuture; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.RegisterExtension; @@ -144,4 +145,30 @@ void testExampleIgnore() throws Exception { Thread.sleep(500); // sleep a bit just to make sure no metric is captured assertThat(testing.metrics()).isEmpty(); } + + @Test + void testCompletableFuture() throws Exception { + CompletableFuture future = new CompletableFuture<>(); + new CountedExample().completableFuture(future); + + Thread.sleep(500); // sleep a bit just to make sure no metric is captured + assertThat(testing.metrics()).isEmpty(); + + future.complete("Done"); + + testing.waitAndAssertMetrics( + INSTRUMENTATION_NAME, + metric -> + metric + .hasName("example.completable.future.count") + .satisfies( + metricData -> + assertThat(metricData.getData().getPoints()) + .allMatch( + p -> + "Done" + .equals( + p.getAttributes() + .get(AttributeKey.stringKey("returnValue")))))); + } } diff --git a/instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-2.6/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/v2_6/timed/TimedExample.java b/instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-2.6/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/v2_6/timed/TimedExample.java index f488223d699a..f229f0ea44f7 100644 --- a/instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-2.6/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/v2_6/timed/TimedExample.java +++ b/instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-2.6/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/v2_6/timed/TimedExample.java @@ -6,6 +6,7 @@ package io.opentelemetry.javaagent.instrumentation.instrumentationannotations.v2_6.timed; import io.opentelemetry.instrumentation.annotations.Timed; +import java.util.concurrent.CompletableFuture; import java.util.concurrent.TimeUnit; public class TimedExample { @@ -47,6 +48,11 @@ public ReturnObject exampleWithReturnValueAttribute() { return new ReturnObject(); } + @Timed(value = "example.completable.future.duration", returnValueAttribute = "returnValue") + public CompletableFuture completableFuture(CompletableFuture future) { + return future; + } + public static class ReturnObject { @Override public String toString() { diff --git a/instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-2.6/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/v2_6/timed/TimedInstrumentationTest.java b/instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-2.6/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/v2_6/timed/TimedInstrumentationTest.java index b089dcfb8591..32c7fac73455 100644 --- a/instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-2.6/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/v2_6/timed/TimedInstrumentationTest.java +++ b/instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-2.6/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/v2_6/timed/TimedInstrumentationTest.java @@ -11,6 +11,7 @@ import io.opentelemetry.api.common.AttributeKey; import io.opentelemetry.instrumentation.testing.junit.AgentInstrumentationExtension; +import java.util.concurrent.CompletableFuture; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.RegisterExtension; @@ -151,4 +152,30 @@ void testExampleWithReturnValueAttribute() { p.getAttributes() .get(AttributeKey.stringKey("returnValue")))))); } + + @Test + void testCompletableFuture() throws Exception { + CompletableFuture future = new CompletableFuture<>(); + new TimedExample().completableFuture(future); + + Thread.sleep(500); // sleep a bit just to make sure no metric is captured + assertThat(testing.metrics()).isEmpty(); + + future.complete("Done"); + + testing.waitAndAssertMetrics( + TIMED_INSTRUMENTATION_NAME, + metric -> + metric + .hasName("example.completable.future.duration") + .satisfies( + metricData -> + assertThat(metricData.getData().getPoints()) + .allMatch( + p -> + "Done" + .equals( + p.getAttributes() + .get(AttributeKey.stringKey("returnValue")))))); + } } diff --git a/instrumentation/reactor/reactor-3.1/library/src/main/java/io/opentelemetry/instrumentation/reactor/v3_1/ReactorAsyncOperationEndStrategy.java b/instrumentation/reactor/reactor-3.1/library/src/main/java/io/opentelemetry/instrumentation/reactor/v3_1/ReactorAsyncOperationEndStrategy.java index 49f85ad0aea7..fe1237664f84 100644 --- a/instrumentation/reactor/reactor-3.1/library/src/main/java/io/opentelemetry/instrumentation/reactor/v3_1/ReactorAsyncOperationEndStrategy.java +++ b/instrumentation/reactor/reactor-3.1/library/src/main/java/io/opentelemetry/instrumentation/reactor/v3_1/ReactorAsyncOperationEndStrategy.java @@ -10,8 +10,8 @@ import io.opentelemetry.api.common.AttributeKey; import io.opentelemetry.api.trace.Span; import io.opentelemetry.context.Context; +import io.opentelemetry.instrumentation.api.annotation.support.async.AsyncOperationEndHandler; import io.opentelemetry.instrumentation.api.annotation.support.async.AsyncOperationEndStrategy; -import io.opentelemetry.instrumentation.api.instrumenter.Instrumenter; import java.util.concurrent.atomic.AtomicBoolean; import java.util.function.Consumer; import org.reactivestreams.Publisher; @@ -44,7 +44,7 @@ public boolean supports(Class returnType) { @Override public Object end( - Instrumenter instrumenter, + AsyncOperationEndHandler handler, Context context, REQUEST request, Object asyncValue, @@ -54,7 +54,7 @@ public Object end( new EndOnFirstNotificationConsumer(context) { @Override protected void end(Object result, Throwable error) { - instrumenter.end(context, request, tryToGetResponse(responseType, result), error); + handler.handle(context, request, tryToGetResponse(responseType, result), error); } }; diff --git a/instrumentation/rxjava/rxjava-2.0/library/src/main/java/io/opentelemetry/instrumentation/rxjava/v2_0/RxJava2AsyncOperationEndStrategy.java b/instrumentation/rxjava/rxjava-2.0/library/src/main/java/io/opentelemetry/instrumentation/rxjava/v2_0/RxJava2AsyncOperationEndStrategy.java index a66bda61749a..3c46a1277c42 100644 --- a/instrumentation/rxjava/rxjava-2.0/library/src/main/java/io/opentelemetry/instrumentation/rxjava/v2_0/RxJava2AsyncOperationEndStrategy.java +++ b/instrumentation/rxjava/rxjava-2.0/library/src/main/java/io/opentelemetry/instrumentation/rxjava/v2_0/RxJava2AsyncOperationEndStrategy.java @@ -10,8 +10,8 @@ import io.opentelemetry.api.common.AttributeKey; import io.opentelemetry.api.trace.Span; import io.opentelemetry.context.Context; +import io.opentelemetry.instrumentation.api.annotation.support.async.AsyncOperationEndHandler; import io.opentelemetry.instrumentation.api.annotation.support.async.AsyncOperationEndStrategy; -import io.opentelemetry.instrumentation.api.instrumenter.Instrumenter; import io.reactivex.Completable; import io.reactivex.Flowable; import io.reactivex.Maybe; @@ -55,7 +55,7 @@ public boolean supports(Class returnType) { @Override public Object end( - Instrumenter instrumenter, + AsyncOperationEndHandler handler, Context context, REQUEST request, Object asyncValue, @@ -65,7 +65,7 @@ public Object end( new EndOnFirstNotificationConsumer(context) { @Override protected void end(Object response, Throwable error) { - instrumenter.end(context, request, tryToGetResponse(responseType, response), error); + handler.handle(context, request, tryToGetResponse(responseType, response), error); } }; diff --git a/instrumentation/rxjava/rxjava-3-common/library/src/main/java/io/opentelemetry/instrumentation/rxjava/v3/common/RxJava3AsyncOperationEndStrategy.java b/instrumentation/rxjava/rxjava-3-common/library/src/main/java/io/opentelemetry/instrumentation/rxjava/v3/common/RxJava3AsyncOperationEndStrategy.java index 2814a15f42dc..c3aedd9f8fe8 100644 --- a/instrumentation/rxjava/rxjava-3-common/library/src/main/java/io/opentelemetry/instrumentation/rxjava/v3/common/RxJava3AsyncOperationEndStrategy.java +++ b/instrumentation/rxjava/rxjava-3-common/library/src/main/java/io/opentelemetry/instrumentation/rxjava/v3/common/RxJava3AsyncOperationEndStrategy.java @@ -10,8 +10,8 @@ import io.opentelemetry.api.common.AttributeKey; import io.opentelemetry.api.trace.Span; import io.opentelemetry.context.Context; +import io.opentelemetry.instrumentation.api.annotation.support.async.AsyncOperationEndHandler; import io.opentelemetry.instrumentation.api.annotation.support.async.AsyncOperationEndStrategy; -import io.opentelemetry.instrumentation.api.instrumenter.Instrumenter; import io.reactivex.rxjava3.core.Completable; import io.reactivex.rxjava3.core.Flowable; import io.reactivex.rxjava3.core.Maybe; @@ -55,7 +55,7 @@ public boolean supports(Class returnType) { @Override public Object end( - Instrumenter instrumenter, + AsyncOperationEndHandler handler, Context context, REQUEST request, Object asyncValue, @@ -65,7 +65,7 @@ public Object end( new EndOnFirstNotificationConsumer(context) { @Override protected void end(Object response, Throwable error) { - instrumenter.end(context, request, tryToGetResponse(responseType, response), error); + handler.handle(context, request, tryToGetResponse(responseType, response), error); } }; From a844fa34e50230bd4965790f5773603597dde056 Mon Sep 17 00:00:00 2001 From: Lauri Tulmin Date: Thu, 20 Jun 2024 16:17:08 +0300 Subject: [PATCH 13/21] move new annotations to incubator module --- .../kotlin/otel.java-conventions.gradle.kts | 1 + ...ntelemetry-instrumentation-annotations.txt | 36 +------------------ .../build.gradle.kts | 13 +++++++ .../instrumentation/annotations/Counted.java | 0 .../annotations/MetricAttribute.java | 0 .../instrumentation/annotations/Timed.java | 0 .../annotations/CountedUsageExamples.java | 0 .../annotations/TimedUsageExamples.java | 0 .../javaagent/build.gradle.kts | 4 +-- .../build.gradle.kts | 1 + settings.gradle.kts | 1 + 11 files changed, 19 insertions(+), 37 deletions(-) create mode 100644 instrumentation-annotations-incubator/build.gradle.kts rename {instrumentation-annotations => instrumentation-annotations-incubator}/src/main/java/io/opentelemetry/instrumentation/annotations/Counted.java (100%) rename {instrumentation-annotations => instrumentation-annotations-incubator}/src/main/java/io/opentelemetry/instrumentation/annotations/MetricAttribute.java (100%) rename {instrumentation-annotations => instrumentation-annotations-incubator}/src/main/java/io/opentelemetry/instrumentation/annotations/Timed.java (100%) rename {instrumentation-annotations => instrumentation-annotations-incubator}/src/test/java/io/opentelemetry/instrumentation/annotations/CountedUsageExamples.java (100%) rename {instrumentation-annotations => instrumentation-annotations-incubator}/src/test/java/io/opentelemetry/instrumentation/annotations/TimedUsageExamples.java (100%) diff --git a/conventions/src/main/kotlin/otel.java-conventions.gradle.kts b/conventions/src/main/kotlin/otel.java-conventions.gradle.kts index 94b35baa54dc..c1b51f385bb6 100644 --- a/conventions/src/main/kotlin/otel.java-conventions.gradle.kts +++ b/conventions/src/main/kotlin/otel.java-conventions.gradle.kts @@ -467,6 +467,7 @@ configurations.configureEach { substitute(module("io.opentelemetry.instrumentation:opentelemetry-instrumentation-api")).using(project(":instrumentation-api")) substitute(module("io.opentelemetry.instrumentation:opentelemetry-instrumentation-api-incubator")).using(project(":instrumentation-api-incubator")) substitute(module("io.opentelemetry.instrumentation:opentelemetry-instrumentation-annotations")).using(project(":instrumentation-annotations")) + substitute(module("io.opentelemetry.instrumentation:opentelemetry-instrumentation-annotations-incubator")).using(project(":instrumentation-annotations-incubator")) substitute(module("io.opentelemetry.instrumentation:opentelemetry-instrumentation-annotations-support")).using( project(":instrumentation-annotations-support") ) diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-instrumentation-annotations.txt b/docs/apidiffs/current_vs_latest/opentelemetry-instrumentation-annotations.txt index 400966d1597a..a326f57f6bd0 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-instrumentation-annotations.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-instrumentation-annotations.txt @@ -1,36 +1,2 @@ Comparing source compatibility of opentelemetry-instrumentation-annotations-2.6.0-SNAPSHOT.jar against opentelemetry-instrumentation-annotations-2.5.0.jar -+++ NEW ANNOTATION: PUBLIC(+) ABSTRACT(+) io.opentelemetry.instrumentation.annotations.Counted (not serializable) - +++ CLASS FILE FORMAT VERSION: 52.0 <- n.a. - +++ NEW INTERFACE: java.lang.annotation.Annotation - +++ NEW SUPERCLASS: java.lang.Object - +++ NEW METHOD: PUBLIC(+) ABSTRACT(+) java.lang.String[] additionalAttributes() - +++ NEW METHOD: PUBLIC(+) ABSTRACT(+) java.lang.String description() - +++ NEW METHOD: PUBLIC(+) ABSTRACT(+) java.lang.String returnValueAttribute() - +++ NEW METHOD: PUBLIC(+) ABSTRACT(+) java.lang.String unit() - +++ NEW METHOD: PUBLIC(+) ABSTRACT(+) java.lang.String value() - +++ NEW ANNOTATION: java.lang.annotation.Target - +++ NEW ELEMENT: value=java.lang.annotation.ElementType.METHOD,java.lang.annotation.ElementType.CONSTRUCTOR (+) - +++ NEW ANNOTATION: java.lang.annotation.Retention - +++ NEW ELEMENT: value=java.lang.annotation.RetentionPolicy.RUNTIME (+) -+++ NEW ANNOTATION: PUBLIC(+) ABSTRACT(+) io.opentelemetry.instrumentation.annotations.MetricAttribute (not serializable) - +++ CLASS FILE FORMAT VERSION: 52.0 <- n.a. - +++ NEW INTERFACE: java.lang.annotation.Annotation - +++ NEW SUPERCLASS: java.lang.Object - +++ NEW METHOD: PUBLIC(+) ABSTRACT(+) java.lang.String value() - +++ NEW ANNOTATION: java.lang.annotation.Target - +++ NEW ELEMENT: value=java.lang.annotation.ElementType.PARAMETER (+) - +++ NEW ANNOTATION: java.lang.annotation.Retention - +++ NEW ELEMENT: value=java.lang.annotation.RetentionPolicy.RUNTIME (+) -+++ NEW ANNOTATION: PUBLIC(+) ABSTRACT(+) io.opentelemetry.instrumentation.annotations.Timed (not serializable) - +++ CLASS FILE FORMAT VERSION: 52.0 <- n.a. - +++ NEW INTERFACE: java.lang.annotation.Annotation - +++ NEW SUPERCLASS: java.lang.Object - +++ NEW METHOD: PUBLIC(+) ABSTRACT(+) java.lang.String[] additionalAttributes() - +++ NEW METHOD: PUBLIC(+) ABSTRACT(+) java.lang.String description() - +++ NEW METHOD: PUBLIC(+) ABSTRACT(+) java.lang.String returnValueAttribute() - +++ NEW METHOD: PUBLIC(+) ABSTRACT(+) java.util.concurrent.TimeUnit unit() - +++ NEW METHOD: PUBLIC(+) ABSTRACT(+) java.lang.String value() - +++ NEW ANNOTATION: java.lang.annotation.Target - +++ NEW ELEMENT: value=java.lang.annotation.ElementType.METHOD,java.lang.annotation.ElementType.CONSTRUCTOR (+) - +++ NEW ANNOTATION: java.lang.annotation.Retention - +++ NEW ELEMENT: value=java.lang.annotation.RetentionPolicy.RUNTIME (+) +No changes. \ No newline at end of file diff --git a/instrumentation-annotations-incubator/build.gradle.kts b/instrumentation-annotations-incubator/build.gradle.kts new file mode 100644 index 000000000000..321ea11d7f85 --- /dev/null +++ b/instrumentation-annotations-incubator/build.gradle.kts @@ -0,0 +1,13 @@ +plugins { + id("otel.java-conventions") + id("otel.japicmp-conventions") + id("otel.publish-conventions") + + id("otel.animalsniffer-conventions") +} + +group = "io.opentelemetry.instrumentation" + +dependencies { + api("io.opentelemetry:opentelemetry-api") +} diff --git a/instrumentation-annotations/src/main/java/io/opentelemetry/instrumentation/annotations/Counted.java b/instrumentation-annotations-incubator/src/main/java/io/opentelemetry/instrumentation/annotations/Counted.java similarity index 100% rename from instrumentation-annotations/src/main/java/io/opentelemetry/instrumentation/annotations/Counted.java rename to instrumentation-annotations-incubator/src/main/java/io/opentelemetry/instrumentation/annotations/Counted.java diff --git a/instrumentation-annotations/src/main/java/io/opentelemetry/instrumentation/annotations/MetricAttribute.java b/instrumentation-annotations-incubator/src/main/java/io/opentelemetry/instrumentation/annotations/MetricAttribute.java similarity index 100% rename from instrumentation-annotations/src/main/java/io/opentelemetry/instrumentation/annotations/MetricAttribute.java rename to instrumentation-annotations-incubator/src/main/java/io/opentelemetry/instrumentation/annotations/MetricAttribute.java diff --git a/instrumentation-annotations/src/main/java/io/opentelemetry/instrumentation/annotations/Timed.java b/instrumentation-annotations-incubator/src/main/java/io/opentelemetry/instrumentation/annotations/Timed.java similarity index 100% rename from instrumentation-annotations/src/main/java/io/opentelemetry/instrumentation/annotations/Timed.java rename to instrumentation-annotations-incubator/src/main/java/io/opentelemetry/instrumentation/annotations/Timed.java diff --git a/instrumentation-annotations/src/test/java/io/opentelemetry/instrumentation/annotations/CountedUsageExamples.java b/instrumentation-annotations-incubator/src/test/java/io/opentelemetry/instrumentation/annotations/CountedUsageExamples.java similarity index 100% rename from instrumentation-annotations/src/test/java/io/opentelemetry/instrumentation/annotations/CountedUsageExamples.java rename to instrumentation-annotations-incubator/src/test/java/io/opentelemetry/instrumentation/annotations/CountedUsageExamples.java diff --git a/instrumentation-annotations/src/test/java/io/opentelemetry/instrumentation/annotations/TimedUsageExamples.java b/instrumentation-annotations-incubator/src/test/java/io/opentelemetry/instrumentation/annotations/TimedUsageExamples.java similarity index 100% rename from instrumentation-annotations/src/test/java/io/opentelemetry/instrumentation/annotations/TimedUsageExamples.java rename to instrumentation-annotations-incubator/src/test/java/io/opentelemetry/instrumentation/annotations/TimedUsageExamples.java diff --git a/instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-2.6/javaagent/build.gradle.kts b/instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-2.6/javaagent/build.gradle.kts index 521fb5ef4de3..5e7a75094e16 100644 --- a/instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-2.6/javaagent/build.gradle.kts +++ b/instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-2.6/javaagent/build.gradle.kts @@ -9,7 +9,7 @@ plugins { muzzle { pass { group.set("io.opentelemetry") - module.set("opentelemetry-instrumentation-annotations") + module.set("opentelemetry-instrumentation-annotations-incubator") versions.set("(,)") } } @@ -25,7 +25,7 @@ dependencies { // see the comment in opentelemetry-api-1.0.gradle for more details compileOnly(project(":opentelemetry-instrumentation-annotations-shaded-for-instrumenting", configuration = "shadow")) - testImplementation(project(":instrumentation-annotations")) + testImplementation(project(":instrumentation-annotations-incubator")) testImplementation(project(":instrumentation-annotations-support")) } diff --git a/opentelemetry-instrumentation-annotations-shaded-for-instrumenting/build.gradle.kts b/opentelemetry-instrumentation-annotations-shaded-for-instrumenting/build.gradle.kts index 3dc29118754b..c1d3e35bd85d 100644 --- a/opentelemetry-instrumentation-annotations-shaded-for-instrumenting/build.gradle.kts +++ b/opentelemetry-instrumentation-annotations-shaded-for-instrumenting/build.gradle.kts @@ -9,6 +9,7 @@ group = "io.opentelemetry.javaagent" dependencies { implementation("io.opentelemetry.instrumentation:opentelemetry-instrumentation-annotations") + implementation("io.opentelemetry.instrumentation:opentelemetry-instrumentation-annotations-incubator") } // OpenTelemetry Instrumentation Annotations shaded so that it can be used in instrumentation of diff --git a/settings.gradle.kts b/settings.gradle.kts index f48d89b1a0e8..21e2447bfa1c 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -131,6 +131,7 @@ include(":bom-alpha") include(":instrumentation-api") include(":instrumentation-api-incubator") include(":instrumentation-annotations") +include(":instrumentation-annotations-incubator") include(":instrumentation-annotations-support") include(":instrumentation-annotations-support-testing") From 2c2c3d593062e7e57ddeaf9f302b29d9898fc64c Mon Sep 17 00:00:00 2001 From: Lauri Tulmin Date: Fri, 21 Jun 2024 16:03:30 +0300 Subject: [PATCH 14/21] rework static attribute support --- .../instrumentation/annotations/Counted.java | 24 +--- .../annotations/StaticMetricAttribute.java | 35 ++++++ .../annotations/StaticMetricAttributes.java | 30 +++++ .../instrumentation/annotations/Timed.java | 28 +---- .../api/annotation/support/MethodBinder.java | 37 ++++++ .../v2_6/CountedHelper.java | 85 +++++-------- .../v2_6/CountedInstrumentation.java | 4 +- .../v2_6/MetricsAnnotationHelper.java | 79 ++++++++---- .../v2_6/TimedHelper.java | 112 +++++++----------- .../v2_6/TimedInstrumentation.java | 4 +- .../v2_6/counted/CountedExample.java | 13 +- .../counted/CountedInstrumentationTest.java | 28 +---- .../v2_6/timed/TimedExample.java | 12 +- .../v2_6/timed/TimedInstrumentationTest.java | 28 +---- 14 files changed, 257 insertions(+), 262 deletions(-) create mode 100644 instrumentation-annotations-incubator/src/main/java/io/opentelemetry/instrumentation/annotations/StaticMetricAttribute.java create mode 100644 instrumentation-annotations-incubator/src/main/java/io/opentelemetry/instrumentation/annotations/StaticMetricAttributes.java create mode 100644 instrumentation-annotations-support/src/main/java/io/opentelemetry/instrumentation/api/annotation/support/MethodBinder.java diff --git a/instrumentation-annotations-incubator/src/main/java/io/opentelemetry/instrumentation/annotations/Counted.java b/instrumentation-annotations-incubator/src/main/java/io/opentelemetry/instrumentation/annotations/Counted.java index 7f2c79906f8f..63a60771836c 100644 --- a/instrumentation-annotations-incubator/src/main/java/io/opentelemetry/instrumentation/annotations/Counted.java +++ b/instrumentation-annotations-incubator/src/main/java/io/opentelemetry/instrumentation/annotations/Counted.java @@ -18,10 +18,9 @@ * *
    *
  • code.namespace: The fully qualified name of the class whose method is invoked. - *
  • code.function: The name of the annotated method, or "new" if the annotation is on a - * constructor. + *
  • code.function: The name of the annotated method. *
  • exception.type: This is only present if an Exception is thrown, and contains the - * {@link Class#getCanonicalName() canonical name} of the Exception. + * {@link Class#getName name} of the Exception class. *
* *

Application developers can use this annotation to signal OpenTelemetry auto-instrumentation @@ -63,28 +62,13 @@ */ String unit() default "{invocation}"; - /** - * List of key-value pairs to supply additional attributes. - * - *

Example: - * - *

-   * {@literal @}Counted(
-   *     additionalAttributes = {
-   *       "key1", "value1",
-   *       "key2", "value2",
-   * })
-   * 
- */ - String[] additionalAttributes() default {}; - /** * Attribute name for the return value. * *

The name of the attribute for the return value of the method call. {@link Object#toString()} - * will be called on the return value to convert it to a String. + * may be called on the return value to convert it to a String. * - *

By default, the instrument will not have an attribute with the return value. + *

By default, the instrument will not record an attribute with the return value. * *

Warning: be careful to fill it because it might cause an explosion of the cardinality on * your metric diff --git a/instrumentation-annotations-incubator/src/main/java/io/opentelemetry/instrumentation/annotations/StaticMetricAttribute.java b/instrumentation-annotations-incubator/src/main/java/io/opentelemetry/instrumentation/annotations/StaticMetricAttribute.java new file mode 100644 index 000000000000..9af9fbf18da8 --- /dev/null +++ b/instrumentation-annotations-incubator/src/main/java/io/opentelemetry/instrumentation/annotations/StaticMetricAttribute.java @@ -0,0 +1,35 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.instrumentation.annotations; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Repeatable; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * This annotation allows for adding attributes to the metrics recorded using {@link Timed} and + * {@link Counted} annotations. + * + *

Application developers can use this annotation to signal OpenTelemetry auto-instrumentation + * that the attribute should be created. + * + *

If you are a library developer, then probably you should NOT use this annotation, because it + * is non-functional without the OpenTelemetry auto-instrumentation agent, or some other annotation + * processor. + */ +@Target(ElementType.METHOD) +@Retention(RetentionPolicy.RUNTIME) +@Repeatable(StaticMetricAttributes.class) +public @interface StaticMetricAttribute { + + /** Name of the attribute. */ + String name(); + + /** Value of the attribute. */ + String value(); +} diff --git a/instrumentation-annotations-incubator/src/main/java/io/opentelemetry/instrumentation/annotations/StaticMetricAttributes.java b/instrumentation-annotations-incubator/src/main/java/io/opentelemetry/instrumentation/annotations/StaticMetricAttributes.java new file mode 100644 index 000000000000..7904538279c2 --- /dev/null +++ b/instrumentation-annotations-incubator/src/main/java/io/opentelemetry/instrumentation/annotations/StaticMetricAttributes.java @@ -0,0 +1,30 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.instrumentation.annotations; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * This annotation allows for adding attributes to the metrics recorded using {@link Timed} and + * {@link Counted} annotations. + * + *

Application developers can use this annotation to signal OpenTelemetry auto-instrumentation + * that the attribute should be created. + * + *

If you are a library developer, then probably you should NOT use this annotation, because it + * is non-functional without the OpenTelemetry auto-instrumentation agent, or some other annotation + * processor. + */ +@Target(ElementType.METHOD) +@Retention(RetentionPolicy.RUNTIME) +public @interface StaticMetricAttributes { + + /** Array of {@link StaticMetricAttribute} annotations describing the added attributes. */ + StaticMetricAttribute[] value(); +} diff --git a/instrumentation-annotations-incubator/src/main/java/io/opentelemetry/instrumentation/annotations/Timed.java b/instrumentation-annotations-incubator/src/main/java/io/opentelemetry/instrumentation/annotations/Timed.java index 7ea5cd22a4ec..9dff708284a7 100644 --- a/instrumentation-annotations-incubator/src/main/java/io/opentelemetry/instrumentation/annotations/Timed.java +++ b/instrumentation-annotations-incubator/src/main/java/io/opentelemetry/instrumentation/annotations/Timed.java @@ -12,17 +12,16 @@ import java.util.concurrent.TimeUnit; /** - * This annotation creates a {@link io.opentelemetry.api.metrics.LongHistogram Histogram} instrument - * observing the duration of invocations of the annotated method or constructor. + * This annotation creates a {@link io.opentelemetry.api.metrics.DoubleHistogram Histogram} + * instrument observing the duration of invocations of the annotated method or constructor. * *

By default, the Histogram instrument will have the following attributes: * *

    *
  • code.namespace: The fully qualified name of the class whose method is invoked. - *
  • code.function: The name of the annotated method, or "new" of the annotation is on a - * constructor. + *
  • code.function: The name of the annotated method. *
  • exception.type: This is only present if an Exception is thrown, and contains the - * {@link Class#getCanonicalName canonical name} of the Exception. + * {@link Class#getName name} of the Exception class. *
* *

Application developers can use this annotation to signal OpenTelemetry auto-instrumentation @@ -59,28 +58,13 @@ */ TimeUnit unit() default TimeUnit.SECONDS; - /** - * List of key-value pairs to supply additional attributes. - * - *

Example: - * - *

-   * {@literal @}Timed(
-   *     additionalAttributes = {
-   *       "key1", "value1",
-   *       "key2", "value2",
-   * })
-   * 
- */ - String[] additionalAttributes() default {}; - /** * Attribute name for the return value. * *

The name of the attribute for the return value of the method call. {@link Object#toString()} - * will be called on the return value to convert it to a String. + * may be called on the return value to convert it to a String. * - *

By default, the instrument will not have an attribute with the return value. + *

By default, the instrument will not record an attribute with the return value. * *

Warning: be careful to fill it because it might cause an explosion of the cardinality on * your metric diff --git a/instrumentation-annotations-support/src/main/java/io/opentelemetry/instrumentation/api/annotation/support/MethodBinder.java b/instrumentation-annotations-support/src/main/java/io/opentelemetry/instrumentation/api/annotation/support/MethodBinder.java new file mode 100644 index 000000000000..f52c4183407e --- /dev/null +++ b/instrumentation-annotations-support/src/main/java/io/opentelemetry/instrumentation/api/annotation/support/MethodBinder.java @@ -0,0 +1,37 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.instrumentation.api.annotation.support; + +import io.opentelemetry.api.common.AttributesBuilder; +import java.lang.reflect.Method; +import java.util.function.BiConsumer; +import javax.annotation.Nullable; + +public final class MethodBinder { + + @Nullable + public static BiConsumer bindReturnValue( + Method method, String attributeName) { + Class returnType = method.getReturnType(); + if (returnType == void.class) { + return null; + } + AttributeBinding binding = AttributeBindingFactory.createBinding(attributeName, returnType); + return binding::apply; + } + + @Nullable + public static BiConsumer bindParameters( + Method method, ParameterAttributeNamesExtractor parameterAttributeNamesExtractor) { + AttributeBindings bindings = AttributeBindings.bind(method, parameterAttributeNamesExtractor); + if (bindings.isEmpty()) { + return null; + } + return bindings::apply; + } + + private MethodBinder() {} +} diff --git a/instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-2.6/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/v2_6/CountedHelper.java b/instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-2.6/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/v2_6/CountedHelper.java index 6fc4dcfb997a..2261932e6c21 100644 --- a/instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-2.6/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/v2_6/CountedHelper.java +++ b/instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-2.6/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/v2_6/CountedHelper.java @@ -6,8 +6,6 @@ package io.opentelemetry.javaagent.instrumentation.instrumentationannotations.v2_6; import application.io.opentelemetry.instrumentation.annotations.Counted; -import io.opentelemetry.api.common.Attributes; -import io.opentelemetry.api.common.AttributesBuilder; import io.opentelemetry.api.metrics.LongCounter; import io.opentelemetry.context.Context; import io.opentelemetry.instrumentation.api.annotation.support.async.AsyncOperationEndSupport; @@ -15,85 +13,60 @@ import java.lang.reflect.Method; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; -import java.util.function.Consumer; public final class CountedHelper extends MetricsAnnotationHelper { - private static final ClassValue> counters = - new ClassValue>() { + private static final ClassValue> counters = + new ClassValue>() { @Override - protected Map computeValue(Class type) { + protected Map computeValue(Class type) { return new ConcurrentHashMap<>(); } }; - public static Object recordCountWithAttributes( + public static Object recordWithAttributes( MethodRequest methodRequest, Object returnValue, Throwable throwable) { - return recordCount( - methodRequest.method(), - returnValue, - throwable, - attributesBuilder -> extractMetricAttributes(methodRequest, attributesBuilder)); + return record(methodRequest.method(), returnValue, throwable, methodRequest.args()); } - public static Object recordCount(Method method, Object returnValue, Throwable throwable) { - return recordCount(method, returnValue, throwable, attributesBuilder -> {}); + public static Object record(Method method, Object returnValue, Throwable throwable) { + return record(method, returnValue, throwable, null); } - private static Object recordCount( - Method method, - Object returnValue, - Throwable throwable, - Consumer additionalAttributes) { + private static Object record( + Method method, Object returnValue, Throwable throwable, Object[] arguments) { AsyncOperationEndSupport operationEndSupport = AsyncOperationEndSupport.create( - (context, method1, object, error) -> { - Counted countedAnnotation = method1.getAnnotation(Counted.class); - AttributesBuilder attributesBuilder = - getCommonAttributesBuilder(countedAnnotation, object, error); - additionalAttributes.accept(attributesBuilder); - getCounter(method1).add(1, attributesBuilder.build()); - }, + (context, m, object, error) -> getMethodCounter(m).record(object, arguments, error), Object.class, method.getReturnType()); return operationEndSupport.asyncEnd(Context.current(), method, returnValue, throwable); } - private static AttributesBuilder getCommonAttributesBuilder( - Counted countedAnnotation, Object returnValue, Throwable throwable) { - AttributesBuilder attributesBuilder = Attributes.builder(); - extractAdditionAttributes(countedAnnotation.additionalAttributes(), attributesBuilder); - extractReturnValue(countedAnnotation, returnValue, attributesBuilder); - extractException(throwable, attributesBuilder); - return attributesBuilder; + private static MethodCounter getMethodCounter(Method method) { + return counters.get(method.getDeclaringClass()).computeIfAbsent(method, MethodCounter::new); } - private static void extractException(Throwable throwable, AttributesBuilder attributesBuilder) { - if (null != throwable) { - attributesBuilder.put("exception", throwable.getClass().getName()); - } - } + private static class MethodCounter { + private final LongCounter counter; + private final MetricAttributeHelper attributeHelper; + + MethodCounter(Method method) { + Counted countedAnnotation = method.getAnnotation(Counted.class); + counter = + METER + .counterBuilder(countedAnnotation.value()) + .setDescription(countedAnnotation.description()) + .setUnit(countedAnnotation.unit()) + .build(); - private static void extractReturnValue( - Counted countedAnnotation, Object returnValue, AttributesBuilder attributesBuilder) { - if (returnValue != null && !countedAnnotation.returnValueAttribute().isEmpty()) { - attributesBuilder.put(countedAnnotation.returnValueAttribute(), returnValue.toString()); + String returnValueAttribute = countedAnnotation.returnValueAttribute(); + attributeHelper = new MetricAttributeHelper(method, returnValueAttribute); } - } - private static LongCounter getCounter(Method method) { - return counters - .get(method.getDeclaringClass()) - .computeIfAbsent( - method, - m -> { - Counted countedAnnotation = m.getAnnotation(Counted.class); - return METER - .counterBuilder(countedAnnotation.value()) - .setDescription(countedAnnotation.description()) - .setUnit(countedAnnotation.unit()) - .build(); - }); + void record(Object returnValue, Object[] arguments, Throwable throwable) { + counter.add(1, attributeHelper.getAttributes(returnValue, arguments, throwable)); + } } private CountedHelper() {} diff --git a/instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-2.6/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/v2_6/CountedInstrumentation.java b/instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-2.6/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/v2_6/CountedInstrumentation.java index 9491592b6d37..1c199a3868e9 100644 --- a/instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-2.6/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/v2_6/CountedInstrumentation.java +++ b/instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-2.6/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/v2_6/CountedInstrumentation.java @@ -90,7 +90,7 @@ public static void onExit( @Advice.Local("otelRequest") MethodRequest request, @Advice.Return(typing = Assigner.Typing.DYNAMIC, readOnly = false) Object returnValue, @Advice.Thrown Throwable throwable) { - returnValue = CountedHelper.recordCountWithAttributes(request, returnValue, throwable); + returnValue = CountedHelper.recordWithAttributes(request, returnValue, throwable); } } @@ -102,7 +102,7 @@ public static void onExit( @Advice.Origin Method method, @Advice.Return(typing = Assigner.Typing.DYNAMIC, readOnly = false) Object returnValue, @Advice.Thrown Throwable throwable) { - returnValue = CountedHelper.recordCount(method, returnValue, throwable); + returnValue = CountedHelper.record(method, returnValue, throwable); } } } diff --git a/instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-2.6/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/v2_6/MetricsAnnotationHelper.java b/instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-2.6/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/v2_6/MetricsAnnotationHelper.java index c1fff4fc5f36..9d1accc92c31 100644 --- a/instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-2.6/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/v2_6/MetricsAnnotationHelper.java +++ b/instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-2.6/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/v2_6/MetricsAnnotationHelper.java @@ -6,44 +6,44 @@ package io.opentelemetry.javaagent.instrumentation.instrumentationannotations.v2_6; import application.io.opentelemetry.instrumentation.annotations.MetricAttribute; +import application.io.opentelemetry.instrumentation.annotations.StaticMetricAttribute; import io.opentelemetry.api.GlobalOpenTelemetry; +import io.opentelemetry.api.common.Attributes; import io.opentelemetry.api.common.AttributesBuilder; import io.opentelemetry.api.metrics.Meter; -import io.opentelemetry.instrumentation.api.annotation.support.SpanAttributesExtractor; -import io.opentelemetry.javaagent.instrumentation.instrumentationannotations.MethodRequest; +import io.opentelemetry.instrumentation.api.annotation.support.MethodBinder; +import io.opentelemetry.instrumentation.api.annotation.support.ParameterAttributeNamesExtractor; +import io.opentelemetry.semconv.incubating.CodeIncubatingAttributes; +import java.lang.reflect.Method; import java.lang.reflect.Parameter; +import java.util.function.BiConsumer; import javax.annotation.Nullable; public abstract class MetricsAnnotationHelper { private static final String INSTRUMENTATION_NAME = "io.opentelemetry.opentelemetry-instrumentation-annotations-2.6"; static final Meter METER = GlobalOpenTelemetry.get().getMeter(INSTRUMENTATION_NAME); - private static final SpanAttributesExtractor PARAMETER_ATTRIBUTES = createAttributesExtractor(); + static final ParameterAttributeNamesExtractor PARAMETER_ATTRIBUTE_NAMES_EXTRACTOR = + (method, parameters) -> { + String[] attributeNames = new String[parameters.length]; + for (int i = 0; i < parameters.length; i++) { + attributeNames[i] = attributeName(parameters[i]); + } + return attributeNames; + }; - static void extractMetricAttributes( - MethodRequest methodRequest, AttributesBuilder attributesBuilder) { - attributesBuilder.putAll( - PARAMETER_ATTRIBUTES.extract(methodRequest.method(), methodRequest.args())); - } + static void addStaticAttributes(Method method, AttributesBuilder attributesBuilder) { + attributesBuilder.put( + CodeIncubatingAttributes.CODE_NAMESPACE, method.getDeclaringClass().getName()); + attributesBuilder.put(CodeIncubatingAttributes.CODE_FUNCTION, method.getName()); - static void extractAdditionAttributes(String[] attributes, AttributesBuilder attributesBuilder) { - int length = attributes.length; - for (int i = 0; i + 1 < length; i += 2) { - attributesBuilder.put(attributes[i], attributes[i + 1]); + StaticMetricAttribute[] staticMetricAttributes = + method.getDeclaredAnnotationsByType(StaticMetricAttribute.class); + for (StaticMetricAttribute staticMetricAttribute : staticMetricAttributes) { + attributesBuilder.put(staticMetricAttribute.name(), staticMetricAttribute.value()); } } - private static SpanAttributesExtractor createAttributesExtractor() { - return SpanAttributesExtractor.create( - (method, parameters) -> { - String[] attributeNames = new String[parameters.length]; - for (int i = 0; i < parameters.length; i++) { - attributeNames[i] = attributeName(parameters[i]); - } - return attributeNames; - }); - } - @Nullable private static String attributeName(Parameter parameter) { MetricAttribute annotation = parameter.getDeclaredAnnotation(MetricAttribute.class); @@ -59,4 +59,37 @@ private static String attributeName(Parameter parameter) { return null; } } + + static class MetricAttributeHelper { + private final BiConsumer bindParameters; + private final BiConsumer bindReturn; + private final Attributes staticAttributes; + + MetricAttributeHelper(Method method, String returnValueAttribute) { + bindParameters = MethodBinder.bindParameters(method, PARAMETER_ATTRIBUTE_NAMES_EXTRACTOR); + bindReturn = + !returnValueAttribute.isEmpty() + ? MethodBinder.bindReturnValue(method, returnValueAttribute) + : null; + + AttributesBuilder attributesBuilder = Attributes.builder(); + addStaticAttributes(method, attributesBuilder); + staticAttributes = attributesBuilder.build(); + } + + Attributes getAttributes(Object returnValue, Object[] arguments, Throwable throwable) { + AttributesBuilder attributesBuilder = Attributes.builder(); + attributesBuilder.putAll(staticAttributes); + if (arguments != null && bindParameters != null) { + bindParameters.accept(attributesBuilder, arguments); + } + if (returnValue != null && bindReturn != null) { + bindReturn.accept(attributesBuilder, returnValue); + } + if (throwable != null) { + attributesBuilder.put("exception.type", throwable.getClass().getName()); + } + return attributesBuilder.build(); + } + } } diff --git a/instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-2.6/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/v2_6/TimedHelper.java b/instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-2.6/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/v2_6/TimedHelper.java index 38e470b37d0e..07d11e4c3961 100644 --- a/instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-2.6/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/v2_6/TimedHelper.java +++ b/instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-2.6/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/v2_6/TimedHelper.java @@ -8,8 +8,6 @@ import static java.util.concurrent.TimeUnit.NANOSECONDS; import application.io.opentelemetry.instrumentation.annotations.Timed; -import io.opentelemetry.api.common.Attributes; -import io.opentelemetry.api.common.AttributesBuilder; import io.opentelemetry.api.metrics.DoubleHistogram; import io.opentelemetry.context.Context; import io.opentelemetry.instrumentation.api.annotation.support.async.AsyncOperationEndSupport; @@ -18,98 +16,48 @@ import java.util.Map; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.TimeUnit; -import java.util.function.Consumer; public final class TimedHelper extends MetricsAnnotationHelper { - private static final ClassValue> histograms = - new ClassValue>() { + private static final ClassValue> timers = + new ClassValue>() { @Override - protected Map computeValue(Class type) { + protected Map computeValue(Class type) { return new ConcurrentHashMap<>(); } }; - public static Object recordHistogramWithAttributes( + public static Object recordWithAttributes( MethodRequest methodRequest, Object returnValue, Throwable throwable, long startNanoTime) { - return recordHistogram( - methodRequest.method(), - returnValue, - throwable, - startNanoTime, - attributesBuilder -> extractMetricAttributes(methodRequest, attributesBuilder)); + return record( + methodRequest.method(), returnValue, throwable, startNanoTime, methodRequest.args()); } - public static Object recordHistogram( + public static Object record( Method method, Object returnValue, Throwable throwable, long startNanoTime) { - return recordHistogram(method, returnValue, throwable, startNanoTime, attributesBuilder -> {}); + return record(method, returnValue, throwable, startNanoTime, null); } - public static Object recordHistogram( + private static Object record( Method method, Object returnValue, Throwable throwable, long startNanoTime, - Consumer additionalAttributes) { + Object[] arguments) { AsyncOperationEndSupport operationEndSupport = AsyncOperationEndSupport.create( - (context, method1, object, error) -> { - Timed timedAnnotation = method.getAnnotation(Timed.class); - AttributesBuilder attributesBuilder = - getCommonAttributeBuilder(error, object, timedAnnotation); - additionalAttributes.accept(attributesBuilder); - double duration = getTransformedDuration(startNanoTime, timedAnnotation); - getHistogram(method).record(duration, attributesBuilder.build()); - }, + (context, m, object, error) -> + getMethodTimer(m).record(object, arguments, error, startNanoTime), Object.class, method.getReturnType()); return operationEndSupport.asyncEnd(Context.current(), method, returnValue, throwable); } - private static AttributesBuilder getCommonAttributeBuilder( - Throwable throwable, Object returnValue, Timed timedAnnotation) { - AttributesBuilder attributesBuilder = Attributes.builder(); - extractAdditionAttributes(timedAnnotation.additionalAttributes(), attributesBuilder); - extractReturnValue(timedAnnotation, returnValue, attributesBuilder); - extractException(throwable, attributesBuilder); - return attributesBuilder; + private static MethodTimer getMethodTimer(Method method) { + return timers.get(method.getDeclaringClass()).computeIfAbsent(method, MethodTimer::new); } - private static double getTransformedDuration(long startNanoTime, Timed timedAnnotation) { - TimeUnit unit = timedAnnotation.unit(); - long nanoDelta = System.nanoTime() - startNanoTime; - return (double) nanoDelta / NANOSECONDS.convert(1, unit); - } - - private static void extractException(Throwable throwable, AttributesBuilder attributesBuilder) { - if (null != throwable) { - attributesBuilder.put("exception", throwable.getClass().getName()); - } - } - - private static void extractReturnValue( - Timed countedAnnotation, Object returnValue, AttributesBuilder attributesBuilder) { - if (returnValue != null && !countedAnnotation.returnValueAttribute().isEmpty()) { - attributesBuilder.put(countedAnnotation.returnValueAttribute(), returnValue.toString()); - } - } - - private static DoubleHistogram getHistogram(Method method) { - return histograms - .get(method.getDeclaringClass()) - .computeIfAbsent( - method, - m -> { - Timed timedAnnotation = m.getAnnotation(Timed.class); - return METER - .histogramBuilder(timedAnnotation.value()) - .setDescription(timedAnnotation.description()) - .setUnit(toString(timedAnnotation.unit())) - .build(); - }); - } - - private static String toString(TimeUnit timeUnit) { + private static String timeUnitToString(TimeUnit timeUnit) { switch (timeUnit) { case NANOSECONDS: return "ns"; @@ -129,5 +77,35 @@ private static String toString(TimeUnit timeUnit) { throw new IllegalArgumentException("Unsupported time unit " + timeUnit); } + private static double getDuration(long startNanoTime, TimeUnit unit) { + long nanoDelta = System.nanoTime() - startNanoTime; + return (double) nanoDelta / NANOSECONDS.convert(1, unit); + } + + private static class MethodTimer { + private final TimeUnit unit; + private final DoubleHistogram histogram; + private final MetricAttributeHelper attributeHelper; + + MethodTimer(Method method) { + Timed timedAnnotation = method.getAnnotation(Timed.class); + unit = timedAnnotation.unit(); + histogram = + METER + .histogramBuilder(timedAnnotation.value()) + .setDescription(timedAnnotation.description()) + .setUnit(timeUnitToString(unit)) + .build(); + + String returnValueAttribute = timedAnnotation.returnValueAttribute(); + attributeHelper = new MetricAttributeHelper(method, returnValueAttribute); + } + + void record(Object returnValue, Object[] arguments, Throwable throwable, long startNanoTime) { + double duration = getDuration(startNanoTime, unit); + histogram.record(duration, attributeHelper.getAttributes(returnValue, arguments, throwable)); + } + } + private TimedHelper() {} } diff --git a/instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-2.6/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/v2_6/TimedInstrumentation.java b/instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-2.6/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/v2_6/TimedInstrumentation.java index 6a40c70125bb..3b66154a1d75 100644 --- a/instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-2.6/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/v2_6/TimedInstrumentation.java +++ b/instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-2.6/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/v2_6/TimedInstrumentation.java @@ -94,7 +94,7 @@ public static void onExit( @Advice.Return(typing = Assigner.Typing.DYNAMIC, readOnly = false) Object returnValue, @Advice.Thrown Throwable throwable) { returnValue = - TimedHelper.recordHistogramWithAttributes(request, returnValue, throwable, startNanoTime); + TimedHelper.recordWithAttributes(request, returnValue, throwable, startNanoTime); } } @@ -118,7 +118,7 @@ public static void onExit( @Advice.Local("startNanoTime") long startNanoTime, @Advice.Return(typing = Assigner.Typing.DYNAMIC, readOnly = false) Object returnValue, @Advice.Thrown Throwable throwable) { - returnValue = TimedHelper.recordHistogram(method, returnValue, throwable, startNanoTime); + returnValue = TimedHelper.record(method, returnValue, throwable, startNanoTime); } } } diff --git a/instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-2.6/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/v2_6/counted/CountedExample.java b/instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-2.6/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/v2_6/counted/CountedExample.java index 10e8a8d2d51a..b4d875681416 100644 --- a/instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-2.6/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/v2_6/counted/CountedExample.java +++ b/instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-2.6/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/v2_6/counted/CountedExample.java @@ -6,6 +6,7 @@ package io.opentelemetry.javaagent.instrumentation.instrumentationannotations.v2_6.counted; import io.opentelemetry.instrumentation.annotations.Counted; +import io.opentelemetry.instrumentation.annotations.StaticMetricAttribute; import java.util.concurrent.CompletableFuture; public class CountedExample { @@ -24,16 +25,12 @@ public void exampleWithDescription() {} @Counted(value = "example.with.unit.count", unit = METRIC_UNIT) public void exampleWithUnit() {} - @Counted( - value = "example.with.attributes.count", - additionalAttributes = {"key1", "value1", "key2", "value2"}) + @Counted("example.with.attributes.count") + @StaticMetricAttribute(name = "key1", value = "value1") + @StaticMetricAttribute(name = "key2", value = "value2") + @StaticMetricAttribute(name = "key2", value = "value2") public void exampleWithAdditionalAttributes1() {} - @Counted( - value = "example.with.attributes2.count", - additionalAttributes = {"key1", "value1", "key2", "value2", "key3"}) - public void exampleWithAdditionalAttributes2() {} - @Counted(value = "example.with.return.count", returnValueAttribute = "returnValue") public ReturnObject exampleWithReturnValueAttribute() { return new ReturnObject(); diff --git a/instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-2.6/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/v2_6/counted/CountedInstrumentationTest.java b/instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-2.6/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/v2_6/counted/CountedInstrumentationTest.java index 886f62ebc26d..85a3de21f36e 100644 --- a/instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-2.6/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/v2_6/counted/CountedInstrumentationTest.java +++ b/instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-2.6/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/v2_6/counted/CountedInstrumentationTest.java @@ -71,32 +71,6 @@ void testExampleWithAdditionalAttributes1() { .get(AttributeKey.stringKey("key2")))))); } - @Test - void testExampleWithAdditionalAttributes2() { - new CountedExample().exampleWithAdditionalAttributes2(); - testing.waitAndAssertMetrics( - INSTRUMENTATION_NAME, - metric -> - metric - .hasName("example.with.attributes2.count") - .satisfies( - metricData -> - assertThat(metricData.getData().getPoints()) - .allMatch( - p -> - "value1" - .equals( - p.getAttributes() - .get(AttributeKey.stringKey("key1"))) - && "value2" - .equals( - p.getAttributes() - .get(AttributeKey.stringKey("key2"))) - && null - == p.getAttributes() - .get(AttributeKey.stringKey("key3"))))); - } - @Test void testExampleWithReturnAttribute() { new CountedExample().exampleWithReturnValueAttribute(); @@ -136,7 +110,7 @@ void testExampleWithException() { .getName() .equals( p.getAttributes() - .get(AttributeKey.stringKey("exception")))))); + .get(AttributeKey.stringKey("exception.type")))))); } @Test diff --git a/instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-2.6/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/v2_6/timed/TimedExample.java b/instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-2.6/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/v2_6/timed/TimedExample.java index f229f0ea44f7..5bfca8b7a40f 100644 --- a/instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-2.6/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/v2_6/timed/TimedExample.java +++ b/instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-2.6/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/v2_6/timed/TimedExample.java @@ -5,6 +5,7 @@ package io.opentelemetry.javaagent.instrumentation.instrumentationannotations.v2_6.timed; +import io.opentelemetry.instrumentation.annotations.StaticMetricAttribute; import io.opentelemetry.instrumentation.annotations.Timed; import java.util.concurrent.CompletableFuture; import java.util.concurrent.TimeUnit; @@ -25,16 +26,11 @@ public void exampleWithUnit() throws InterruptedException { Thread.sleep(2000); } - @Timed( - value = "example.with.attributes.duration", - additionalAttributes = {"key1", "value1", "key2", "value2"}) + @Timed("example.with.attributes.duration") + @StaticMetricAttribute(name = "key1", value = "value1") + @StaticMetricAttribute(name = "key2", value = "value2") public void exampleWithAdditionalAttributes1() {} - @Timed( - value = "example.with.attributes2.duration", - additionalAttributes = {"key1", "value1", "key2", "value2", "key3"}) - public void exampleWithAdditionalAttributes2() {} - @Timed("example.ignore.duration") public void exampleIgnore() {} diff --git a/instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-2.6/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/v2_6/timed/TimedInstrumentationTest.java b/instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-2.6/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/v2_6/timed/TimedInstrumentationTest.java index 32c7fac73455..9b2bd56af656 100644 --- a/instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-2.6/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/v2_6/timed/TimedInstrumentationTest.java +++ b/instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-2.6/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/v2_6/timed/TimedInstrumentationTest.java @@ -78,32 +78,6 @@ void testExampleWithAdditionalAttributes1() { .get(AttributeKey.stringKey("key2")))))); } - @Test - void testExampleWithAdditionalAttributes2() { - new TimedExample().exampleWithAdditionalAttributes2(); - testing.waitAndAssertMetrics( - TIMED_INSTRUMENTATION_NAME, - metric -> - metric - .hasName("example.with.attributes2.duration") - .satisfies( - metricData -> - assertThat(metricData.getData().getPoints()) - .allMatch( - p -> - "value1" - .equals( - p.getAttributes() - .get(AttributeKey.stringKey("key1"))) - && "value2" - .equals( - p.getAttributes() - .get(AttributeKey.stringKey("key2"))) - && null - == p.getAttributes() - .get(AttributeKey.stringKey("key3"))))); - } - @Test void testExampleIgnore() throws Exception { new TimedExample().exampleIgnore(); @@ -132,7 +106,7 @@ void testExampleWithException() { .getName() .equals( p.getAttributes() - .get(AttributeKey.stringKey("exception")))))); + .get(AttributeKey.stringKey("exception.type")))))); } @Test From 3e3b10099ee4e552c356d3c0f7f6d21c14fca1c6 Mon Sep 17 00:00:00 2001 From: Lauri Tulmin Date: Fri, 21 Jun 2024 16:52:11 +0300 Subject: [PATCH 15/21] disable indy --- .../v2_6/MetricsAnnotationInstrumentationModule.java | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-2.6/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/v2_6/MetricsAnnotationInstrumentationModule.java b/instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-2.6/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/v2_6/MetricsAnnotationInstrumentationModule.java index f2e1dbb28320..f8e5128a162d 100644 --- a/instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-2.6/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/v2_6/MetricsAnnotationInstrumentationModule.java +++ b/instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-2.6/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/v2_6/MetricsAnnotationInstrumentationModule.java @@ -40,6 +40,12 @@ public ElementMatcher.Junction classLoaderMatcher() { return hasClassesNamed("application.io.opentelemetry.instrumentation.annotations.Counted"); } + @Override + public boolean isIndyModule() { + // TimedInstrumentation does not work with indy + return false; + } + @Override public List typeInstrumentations() { return asList(new CountedInstrumentation(), new TimedInstrumentation()); From de28d298eeb6084c88c895eebdc7eda42d22a742 Mon Sep 17 00:00:00 2001 From: Lauri Tulmin Date: Wed, 26 Jun 2024 15:18:43 +0300 Subject: [PATCH 16/21] add javadoc --- .../instrumentation/api/annotation/support/MethodBinder.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/instrumentation-annotations-support/src/main/java/io/opentelemetry/instrumentation/api/annotation/support/MethodBinder.java b/instrumentation-annotations-support/src/main/java/io/opentelemetry/instrumentation/api/annotation/support/MethodBinder.java index f52c4183407e..0413b3298feb 100644 --- a/instrumentation-annotations-support/src/main/java/io/opentelemetry/instrumentation/api/annotation/support/MethodBinder.java +++ b/instrumentation-annotations-support/src/main/java/io/opentelemetry/instrumentation/api/annotation/support/MethodBinder.java @@ -10,8 +10,10 @@ import java.util.function.BiConsumer; import javax.annotation.Nullable; +/** Helper class for binding method parameters and return value to attributes. */ public final class MethodBinder { + /** Create binding for method return value. */ @Nullable public static BiConsumer bindReturnValue( Method method, String attributeName) { @@ -23,6 +25,7 @@ public static BiConsumer bindReturnValue( return binding::apply; } + /** Create binding for method parameters. */ @Nullable public static BiConsumer bindParameters( Method method, ParameterAttributeNamesExtractor parameterAttributeNamesExtractor) { From 8a01999446c93c4be4d0c9389aeb52983a811b4f Mon Sep 17 00:00:00 2001 From: Lauri Tulmin Date: Wed, 10 Jul 2024 12:42:51 +0300 Subject: [PATCH 17/21] move classes to incubator package --- .../annotations/{ => incubator}/Counted.java | 2 +- .../{ => incubator}/MetricAttribute.java | 2 +- .../{ => incubator}/StaticMetricAttribute.java | 2 +- .../{ => incubator}/StaticMetricAttributes.java | 2 +- .../annotations/{ => incubator}/Timed.java | 2 +- .../{ => incubator}/CountedUsageExamples.java | 2 +- .../{ => incubator}/TimedUsageExamples.java | 2 +- .../javaagent/build.gradle.kts | 2 +- .../incubator}/CountedHelper.java | 4 ++-- .../incubator}/CountedInstrumentation.java | 7 ++++--- .../incubator}/MetricsAnnotationHelper.java | 8 ++++---- .../MetricsAnnotationInstrumentationModule.java | 16 ++++++++++------ .../incubator}/TimedHelper.java | 4 ++-- .../incubator}/TimedInstrumentation.java | 7 ++++--- .../incubator}/counted/CountedExample.java | 6 +++--- .../counted/CountedInstrumentationTest.java | 10 +++++----- .../incubator}/timed/TimedExample.java | 6 +++--- .../timed/TimedInstrumentationTest.java | 8 ++++---- javaagent/build.gradle.kts | 2 +- settings.gradle.kts | 2 +- 20 files changed, 51 insertions(+), 45 deletions(-) rename instrumentation-annotations-incubator/src/main/java/io/opentelemetry/instrumentation/annotations/{ => incubator}/Counted.java (98%) rename instrumentation-annotations-incubator/src/main/java/io/opentelemetry/instrumentation/annotations/{ => incubator}/MetricAttribute.java (95%) rename instrumentation-annotations-incubator/src/main/java/io/opentelemetry/instrumentation/annotations/{ => incubator}/StaticMetricAttribute.java (94%) rename instrumentation-annotations-incubator/src/main/java/io/opentelemetry/instrumentation/annotations/{ => incubator}/StaticMetricAttributes.java (93%) rename instrumentation-annotations-incubator/src/main/java/io/opentelemetry/instrumentation/annotations/{ => incubator}/Timed.java (97%) rename instrumentation-annotations-incubator/src/test/java/io/opentelemetry/instrumentation/annotations/{ => incubator}/CountedUsageExamples.java (84%) rename instrumentation-annotations-incubator/src/test/java/io/opentelemetry/instrumentation/annotations/{ => incubator}/TimedUsageExamples.java (83%) rename instrumentation/opentelemetry-instrumentation-annotations/{opentelemetry-instrumentation-annotations-2.6 => opentelemetry-instrumentation-annotations-incubator}/javaagent/build.gradle.kts (88%) rename instrumentation/opentelemetry-instrumentation-annotations/{opentelemetry-instrumentation-annotations-2.6/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/v2_6 => opentelemetry-instrumentation-annotations-incubator/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/incubator}/CountedHelper.java (98%) rename instrumentation/opentelemetry-instrumentation-annotations/{opentelemetry-instrumentation-annotations-2.6/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/v2_6 => opentelemetry-instrumentation-annotations-incubator/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/incubator}/CountedInstrumentation.java (96%) rename instrumentation/opentelemetry-instrumentation-annotations/{opentelemetry-instrumentation-annotations-2.6/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/v2_6 => opentelemetry-instrumentation-annotations-incubator/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/incubator}/MetricsAnnotationHelper.java (97%) rename instrumentation/opentelemetry-instrumentation-annotations/{opentelemetry-instrumentation-annotations-2.6/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/v2_6 => opentelemetry-instrumentation-annotations-incubator/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/incubator}/MetricsAnnotationInstrumentationModule.java (82%) rename instrumentation/opentelemetry-instrumentation-annotations/{opentelemetry-instrumentation-annotations-2.6/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/v2_6 => opentelemetry-instrumentation-annotations-incubator/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/incubator}/TimedHelper.java (98%) rename instrumentation/opentelemetry-instrumentation-annotations/{opentelemetry-instrumentation-annotations-2.6/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/v2_6 => opentelemetry-instrumentation-annotations-incubator/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/incubator}/TimedInstrumentation.java (96%) rename instrumentation/opentelemetry-instrumentation-annotations/{opentelemetry-instrumentation-annotations-2.6/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/v2_6 => opentelemetry-instrumentation-annotations-incubator/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/incubator}/counted/CountedExample.java (90%) rename instrumentation/opentelemetry-instrumentation-annotations/{opentelemetry-instrumentation-annotations-2.6/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/v2_6 => opentelemetry-instrumentation-annotations-incubator/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/incubator}/counted/CountedInstrumentationTest.java (95%) rename instrumentation/opentelemetry-instrumentation-annotations/{opentelemetry-instrumentation-annotations-2.6/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/v2_6 => opentelemetry-instrumentation-annotations-incubator/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/incubator}/timed/TimedExample.java (90%) rename instrumentation/opentelemetry-instrumentation-annotations/{opentelemetry-instrumentation-annotations-2.6/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/v2_6 => opentelemetry-instrumentation-annotations-incubator/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/incubator}/timed/TimedInstrumentationTest.java (96%) diff --git a/instrumentation-annotations-incubator/src/main/java/io/opentelemetry/instrumentation/annotations/Counted.java b/instrumentation-annotations-incubator/src/main/java/io/opentelemetry/instrumentation/annotations/incubator/Counted.java similarity index 98% rename from instrumentation-annotations-incubator/src/main/java/io/opentelemetry/instrumentation/annotations/Counted.java rename to instrumentation-annotations-incubator/src/main/java/io/opentelemetry/instrumentation/annotations/incubator/Counted.java index 63a60771836c..35e5cc3b001b 100644 --- a/instrumentation-annotations-incubator/src/main/java/io/opentelemetry/instrumentation/annotations/Counted.java +++ b/instrumentation-annotations-incubator/src/main/java/io/opentelemetry/instrumentation/annotations/incubator/Counted.java @@ -3,7 +3,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -package io.opentelemetry.instrumentation.annotations; +package io.opentelemetry.instrumentation.annotations.incubator; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; diff --git a/instrumentation-annotations-incubator/src/main/java/io/opentelemetry/instrumentation/annotations/MetricAttribute.java b/instrumentation-annotations-incubator/src/main/java/io/opentelemetry/instrumentation/annotations/incubator/MetricAttribute.java similarity index 95% rename from instrumentation-annotations-incubator/src/main/java/io/opentelemetry/instrumentation/annotations/MetricAttribute.java rename to instrumentation-annotations-incubator/src/main/java/io/opentelemetry/instrumentation/annotations/incubator/MetricAttribute.java index 39b753fb9b9e..975638922c30 100644 --- a/instrumentation-annotations-incubator/src/main/java/io/opentelemetry/instrumentation/annotations/MetricAttribute.java +++ b/instrumentation-annotations-incubator/src/main/java/io/opentelemetry/instrumentation/annotations/incubator/MetricAttribute.java @@ -3,7 +3,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -package io.opentelemetry.instrumentation.annotations; +package io.opentelemetry.instrumentation.annotations.incubator; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; diff --git a/instrumentation-annotations-incubator/src/main/java/io/opentelemetry/instrumentation/annotations/StaticMetricAttribute.java b/instrumentation-annotations-incubator/src/main/java/io/opentelemetry/instrumentation/annotations/incubator/StaticMetricAttribute.java similarity index 94% rename from instrumentation-annotations-incubator/src/main/java/io/opentelemetry/instrumentation/annotations/StaticMetricAttribute.java rename to instrumentation-annotations-incubator/src/main/java/io/opentelemetry/instrumentation/annotations/incubator/StaticMetricAttribute.java index 9af9fbf18da8..b65881016374 100644 --- a/instrumentation-annotations-incubator/src/main/java/io/opentelemetry/instrumentation/annotations/StaticMetricAttribute.java +++ b/instrumentation-annotations-incubator/src/main/java/io/opentelemetry/instrumentation/annotations/incubator/StaticMetricAttribute.java @@ -3,7 +3,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -package io.opentelemetry.instrumentation.annotations; +package io.opentelemetry.instrumentation.annotations.incubator; import java.lang.annotation.ElementType; import java.lang.annotation.Repeatable; diff --git a/instrumentation-annotations-incubator/src/main/java/io/opentelemetry/instrumentation/annotations/StaticMetricAttributes.java b/instrumentation-annotations-incubator/src/main/java/io/opentelemetry/instrumentation/annotations/incubator/StaticMetricAttributes.java similarity index 93% rename from instrumentation-annotations-incubator/src/main/java/io/opentelemetry/instrumentation/annotations/StaticMetricAttributes.java rename to instrumentation-annotations-incubator/src/main/java/io/opentelemetry/instrumentation/annotations/incubator/StaticMetricAttributes.java index 7904538279c2..904c3daf81b7 100644 --- a/instrumentation-annotations-incubator/src/main/java/io/opentelemetry/instrumentation/annotations/StaticMetricAttributes.java +++ b/instrumentation-annotations-incubator/src/main/java/io/opentelemetry/instrumentation/annotations/incubator/StaticMetricAttributes.java @@ -3,7 +3,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -package io.opentelemetry.instrumentation.annotations; +package io.opentelemetry.instrumentation.annotations.incubator; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; diff --git a/instrumentation-annotations-incubator/src/main/java/io/opentelemetry/instrumentation/annotations/Timed.java b/instrumentation-annotations-incubator/src/main/java/io/opentelemetry/instrumentation/annotations/incubator/Timed.java similarity index 97% rename from instrumentation-annotations-incubator/src/main/java/io/opentelemetry/instrumentation/annotations/Timed.java rename to instrumentation-annotations-incubator/src/main/java/io/opentelemetry/instrumentation/annotations/incubator/Timed.java index 9dff708284a7..0944cc8b5311 100644 --- a/instrumentation-annotations-incubator/src/main/java/io/opentelemetry/instrumentation/annotations/Timed.java +++ b/instrumentation-annotations-incubator/src/main/java/io/opentelemetry/instrumentation/annotations/incubator/Timed.java @@ -3,7 +3,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -package io.opentelemetry.instrumentation.annotations; +package io.opentelemetry.instrumentation.annotations.incubator; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; diff --git a/instrumentation-annotations-incubator/src/test/java/io/opentelemetry/instrumentation/annotations/CountedUsageExamples.java b/instrumentation-annotations-incubator/src/test/java/io/opentelemetry/instrumentation/annotations/incubator/CountedUsageExamples.java similarity index 84% rename from instrumentation-annotations-incubator/src/test/java/io/opentelemetry/instrumentation/annotations/CountedUsageExamples.java rename to instrumentation-annotations-incubator/src/test/java/io/opentelemetry/instrumentation/annotations/incubator/CountedUsageExamples.java index 35b66aeeeeeb..0cd9adf68120 100644 --- a/instrumentation-annotations-incubator/src/test/java/io/opentelemetry/instrumentation/annotations/CountedUsageExamples.java +++ b/instrumentation-annotations-incubator/src/test/java/io/opentelemetry/instrumentation/annotations/incubator/CountedUsageExamples.java @@ -3,7 +3,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -package io.opentelemetry.instrumentation.annotations; +package io.opentelemetry.instrumentation.annotations.incubator; public class CountedUsageExamples { diff --git a/instrumentation-annotations-incubator/src/test/java/io/opentelemetry/instrumentation/annotations/TimedUsageExamples.java b/instrumentation-annotations-incubator/src/test/java/io/opentelemetry/instrumentation/annotations/incubator/TimedUsageExamples.java similarity index 83% rename from instrumentation-annotations-incubator/src/test/java/io/opentelemetry/instrumentation/annotations/TimedUsageExamples.java rename to instrumentation-annotations-incubator/src/test/java/io/opentelemetry/instrumentation/annotations/incubator/TimedUsageExamples.java index 7d33d0adf4f9..793c55f8de4b 100644 --- a/instrumentation-annotations-incubator/src/test/java/io/opentelemetry/instrumentation/annotations/TimedUsageExamples.java +++ b/instrumentation-annotations-incubator/src/test/java/io/opentelemetry/instrumentation/annotations/incubator/TimedUsageExamples.java @@ -3,7 +3,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -package io.opentelemetry.instrumentation.annotations; +package io.opentelemetry.instrumentation.annotations.incubator; public class TimedUsageExamples { diff --git a/instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-2.6/javaagent/build.gradle.kts b/instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-incubator/javaagent/build.gradle.kts similarity index 88% rename from instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-2.6/javaagent/build.gradle.kts rename to instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-incubator/javaagent/build.gradle.kts index 5e7a75094e16..f5e3d05ae1f4 100644 --- a/instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-2.6/javaagent/build.gradle.kts +++ b/instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-incubator/javaagent/build.gradle.kts @@ -35,7 +35,7 @@ tasks { } test { jvmArgs( - "-Dotel.instrumentation.opentelemetry-instrumentation-annotations.exclude-methods=io.opentelemetry.javaagent.instrumentation.instrumentationannotations.v2_6.counted.CountedExample[exampleIgnore];io.opentelemetry.javaagent.instrumentation.instrumentationannotations.v2_6.timed.TimedExample[exampleIgnore]" + "-Dotel.instrumentation.opentelemetry-instrumentation-annotations.exclude-methods=io.opentelemetry.javaagent.instrumentation.instrumentationannotations.incubator.counted.CountedExample[exampleIgnore];io.opentelemetry.javaagent.instrumentation.instrumentationannotations.incubator.timed.TimedExample[exampleIgnore]" ) } } diff --git a/instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-2.6/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/v2_6/CountedHelper.java b/instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-incubator/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/incubator/CountedHelper.java similarity index 98% rename from instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-2.6/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/v2_6/CountedHelper.java rename to instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-incubator/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/incubator/CountedHelper.java index 2261932e6c21..cb0ac6493338 100644 --- a/instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-2.6/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/v2_6/CountedHelper.java +++ b/instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-incubator/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/incubator/CountedHelper.java @@ -3,9 +3,9 @@ * SPDX-License-Identifier: Apache-2.0 */ -package io.opentelemetry.javaagent.instrumentation.instrumentationannotations.v2_6; +package io.opentelemetry.javaagent.instrumentation.instrumentationannotations.incubator; -import application.io.opentelemetry.instrumentation.annotations.Counted; +import application.io.opentelemetry.instrumentation.annotations.incubator.Counted; import io.opentelemetry.api.metrics.LongCounter; import io.opentelemetry.context.Context; import io.opentelemetry.instrumentation.api.annotation.support.async.AsyncOperationEndSupport; diff --git a/instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-2.6/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/v2_6/CountedInstrumentation.java b/instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-incubator/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/incubator/CountedInstrumentation.java similarity index 96% rename from instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-2.6/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/v2_6/CountedInstrumentation.java rename to instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-incubator/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/incubator/CountedInstrumentation.java index 1c199a3868e9..d18e6283f162 100644 --- a/instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-2.6/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/v2_6/CountedInstrumentation.java +++ b/instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-incubator/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/incubator/CountedInstrumentation.java @@ -3,7 +3,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -package io.opentelemetry.javaagent.instrumentation.instrumentationannotations.v2_6; +package io.opentelemetry.javaagent.instrumentation.instrumentationannotations.incubator; import static io.opentelemetry.javaagent.instrumentation.instrumentationannotations.KotlinCoroutineUtil.isKotlinSuspendMethod; import static net.bytebuddy.matcher.ElementMatchers.declaresMethod; @@ -34,13 +34,14 @@ public class CountedInstrumentation implements TypeInstrumentation { CountedInstrumentation() { annotatedMethodMatcher = - isAnnotatedWith(named("application.io.opentelemetry.instrumentation.annotations.Counted")); + isAnnotatedWith( + named("application.io.opentelemetry.instrumentation.annotations.incubator.Counted")); annotatedParametersMatcher = hasParameters( whereAny( isAnnotatedWith( named( - "application.io.opentelemetry.instrumentation.annotations.MetricAttribute")))); + "application.io.opentelemetry.instrumentation.annotations.incubator.MetricAttribute")))); // exclude all kotlin suspend methods, these are handle in kotlinx-coroutines instrumentation excludedMethodsMatcher = AnnotationExcludedMethods.configureExcludedMethods().or(isKotlinSuspendMethod()); diff --git a/instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-2.6/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/v2_6/MetricsAnnotationHelper.java b/instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-incubator/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/incubator/MetricsAnnotationHelper.java similarity index 97% rename from instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-2.6/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/v2_6/MetricsAnnotationHelper.java rename to instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-incubator/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/incubator/MetricsAnnotationHelper.java index 9d1accc92c31..37417fea71dc 100644 --- a/instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-2.6/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/v2_6/MetricsAnnotationHelper.java +++ b/instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-incubator/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/incubator/MetricsAnnotationHelper.java @@ -3,10 +3,10 @@ * SPDX-License-Identifier: Apache-2.0 */ -package io.opentelemetry.javaagent.instrumentation.instrumentationannotations.v2_6; +package io.opentelemetry.javaagent.instrumentation.instrumentationannotations.incubator; -import application.io.opentelemetry.instrumentation.annotations.MetricAttribute; -import application.io.opentelemetry.instrumentation.annotations.StaticMetricAttribute; +import application.io.opentelemetry.instrumentation.annotations.incubator.MetricAttribute; +import application.io.opentelemetry.instrumentation.annotations.incubator.StaticMetricAttribute; import io.opentelemetry.api.GlobalOpenTelemetry; import io.opentelemetry.api.common.Attributes; import io.opentelemetry.api.common.AttributesBuilder; @@ -21,7 +21,7 @@ public abstract class MetricsAnnotationHelper { private static final String INSTRUMENTATION_NAME = - "io.opentelemetry.opentelemetry-instrumentation-annotations-2.6"; + "io.opentelemetry.opentelemetry-instrumentation-annotations-incubator"; static final Meter METER = GlobalOpenTelemetry.get().getMeter(INSTRUMENTATION_NAME); static final ParameterAttributeNamesExtractor PARAMETER_ATTRIBUTE_NAMES_EXTRACTOR = (method, parameters) -> { diff --git a/instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-2.6/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/v2_6/MetricsAnnotationInstrumentationModule.java b/instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-incubator/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/incubator/MetricsAnnotationInstrumentationModule.java similarity index 82% rename from instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-2.6/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/v2_6/MetricsAnnotationInstrumentationModule.java rename to instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-incubator/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/incubator/MetricsAnnotationInstrumentationModule.java index f8e5128a162d..dce08cd60a6e 100644 --- a/instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-2.6/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/v2_6/MetricsAnnotationInstrumentationModule.java +++ b/instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-incubator/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/incubator/MetricsAnnotationInstrumentationModule.java @@ -3,14 +3,14 @@ * SPDX-License-Identifier: Apache-2.0 */ -package io.opentelemetry.javaagent.instrumentation.instrumentationannotations.v2_6; +package io.opentelemetry.javaagent.instrumentation.instrumentationannotations.incubator; import static io.opentelemetry.javaagent.extension.matcher.AgentElementMatchers.hasClassesNamed; import static java.util.Arrays.asList; -import application.io.opentelemetry.instrumentation.annotations.Counted; -import application.io.opentelemetry.instrumentation.annotations.MetricAttribute; -import application.io.opentelemetry.instrumentation.annotations.Timed; +import application.io.opentelemetry.instrumentation.annotations.incubator.Counted; +import application.io.opentelemetry.instrumentation.annotations.incubator.MetricAttribute; +import application.io.opentelemetry.instrumentation.annotations.incubator.Timed; import com.google.auto.service.AutoService; import io.opentelemetry.javaagent.extension.instrumentation.InstrumentationModule; import io.opentelemetry.javaagent.extension.instrumentation.TypeInstrumentation; @@ -25,7 +25,10 @@ public class MetricsAnnotationInstrumentationModule extends InstrumentationModule { public MetricsAnnotationInstrumentationModule() { - super("opentelemetry-instrumentation-annotations", "metrics-annotations"); + super( + "opentelemetry-instrumentation-annotations", + "opentelemetry-instrumentation-annotations-incubator", + "metrics-annotations"); } @Override @@ -37,7 +40,8 @@ public int order() { @Override public ElementMatcher.Junction classLoaderMatcher() { - return hasClassesNamed("application.io.opentelemetry.instrumentation.annotations.Counted"); + return hasClassesNamed( + "application.io.opentelemetry.instrumentation.annotations.incubator.Counted"); } @Override diff --git a/instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-2.6/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/v2_6/TimedHelper.java b/instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-incubator/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/incubator/TimedHelper.java similarity index 98% rename from instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-2.6/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/v2_6/TimedHelper.java rename to instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-incubator/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/incubator/TimedHelper.java index 07d11e4c3961..f32c2b789f7d 100644 --- a/instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-2.6/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/v2_6/TimedHelper.java +++ b/instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-incubator/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/incubator/TimedHelper.java @@ -3,11 +3,11 @@ * SPDX-License-Identifier: Apache-2.0 */ -package io.opentelemetry.javaagent.instrumentation.instrumentationannotations.v2_6; +package io.opentelemetry.javaagent.instrumentation.instrumentationannotations.incubator; import static java.util.concurrent.TimeUnit.NANOSECONDS; -import application.io.opentelemetry.instrumentation.annotations.Timed; +import application.io.opentelemetry.instrumentation.annotations.incubator.Timed; import io.opentelemetry.api.metrics.DoubleHistogram; import io.opentelemetry.context.Context; import io.opentelemetry.instrumentation.api.annotation.support.async.AsyncOperationEndSupport; diff --git a/instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-2.6/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/v2_6/TimedInstrumentation.java b/instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-incubator/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/incubator/TimedInstrumentation.java similarity index 96% rename from instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-2.6/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/v2_6/TimedInstrumentation.java rename to instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-incubator/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/incubator/TimedInstrumentation.java index 3b66154a1d75..94c31d0c2d70 100644 --- a/instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-2.6/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/v2_6/TimedInstrumentation.java +++ b/instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-incubator/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/incubator/TimedInstrumentation.java @@ -3,7 +3,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -package io.opentelemetry.javaagent.instrumentation.instrumentationannotations.v2_6; +package io.opentelemetry.javaagent.instrumentation.instrumentationannotations.incubator; import static io.opentelemetry.javaagent.instrumentation.instrumentationannotations.KotlinCoroutineUtil.isKotlinSuspendMethod; import static net.bytebuddy.matcher.ElementMatchers.declaresMethod; @@ -34,13 +34,14 @@ public class TimedInstrumentation implements TypeInstrumentation { TimedInstrumentation() { annotatedMethodMatcher = - isAnnotatedWith(named("application.io.opentelemetry.instrumentation.annotations.Timed")); + isAnnotatedWith( + named("application.io.opentelemetry.instrumentation.annotations.incubator.Timed")); annotatedParametersMatcher = hasParameters( whereAny( isAnnotatedWith( named( - "application.io.opentelemetry.instrumentation.annotations.MetricAttribute")))); + "application.io.opentelemetry.instrumentation.annotations.incubator.MetricAttribute")))); // exclude all kotlin suspend methods, these are handle in kotlinx-coroutines instrumentation excludedMethodsMatcher = AnnotationExcludedMethods.configureExcludedMethods().or(isKotlinSuspendMethod()); diff --git a/instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-2.6/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/v2_6/counted/CountedExample.java b/instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-incubator/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/incubator/counted/CountedExample.java similarity index 90% rename from instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-2.6/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/v2_6/counted/CountedExample.java rename to instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-incubator/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/incubator/counted/CountedExample.java index b4d875681416..d25083b343a1 100644 --- a/instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-2.6/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/v2_6/counted/CountedExample.java +++ b/instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-incubator/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/incubator/counted/CountedExample.java @@ -3,10 +3,10 @@ * SPDX-License-Identifier: Apache-2.0 */ -package io.opentelemetry.javaagent.instrumentation.instrumentationannotations.v2_6.counted; +package io.opentelemetry.javaagent.instrumentation.instrumentationannotations.incubator.counted; -import io.opentelemetry.instrumentation.annotations.Counted; -import io.opentelemetry.instrumentation.annotations.StaticMetricAttribute; +import io.opentelemetry.instrumentation.annotations.incubator.Counted; +import io.opentelemetry.instrumentation.annotations.incubator.StaticMetricAttribute; import java.util.concurrent.CompletableFuture; public class CountedExample { diff --git a/instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-2.6/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/v2_6/counted/CountedInstrumentationTest.java b/instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-incubator/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/incubator/counted/CountedInstrumentationTest.java similarity index 95% rename from instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-2.6/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/v2_6/counted/CountedInstrumentationTest.java rename to instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-incubator/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/incubator/counted/CountedInstrumentationTest.java index 85a3de21f36e..5e10d4c9da8c 100644 --- a/instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-2.6/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/v2_6/counted/CountedInstrumentationTest.java +++ b/instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-incubator/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/incubator/counted/CountedInstrumentationTest.java @@ -3,11 +3,11 @@ * SPDX-License-Identifier: Apache-2.0 */ -package io.opentelemetry.javaagent.instrumentation.instrumentationannotations.v2_6.counted; +package io.opentelemetry.javaagent.instrumentation.instrumentationannotations.incubator.counted; -import static io.opentelemetry.javaagent.instrumentation.instrumentationannotations.v2_6.counted.CountedExample.METRIC_DESCRIPTION; -import static io.opentelemetry.javaagent.instrumentation.instrumentationannotations.v2_6.counted.CountedExample.METRIC_NAME; -import static io.opentelemetry.javaagent.instrumentation.instrumentationannotations.v2_6.counted.CountedExample.METRIC_UNIT; +import static io.opentelemetry.javaagent.instrumentation.instrumentationannotations.incubator.counted.CountedExample.METRIC_DESCRIPTION; +import static io.opentelemetry.javaagent.instrumentation.instrumentationannotations.incubator.counted.CountedExample.METRIC_NAME; +import static io.opentelemetry.javaagent.instrumentation.instrumentationannotations.incubator.counted.CountedExample.METRIC_UNIT; import static org.assertj.core.api.Assertions.assertThat; import io.opentelemetry.api.common.AttributeKey; @@ -23,7 +23,7 @@ class CountedInstrumentationTest { AgentInstrumentationExtension.create(); private static final String INSTRUMENTATION_NAME = - "io.opentelemetry.opentelemetry-instrumentation-annotations-2.6"; + "io.opentelemetry.opentelemetry-instrumentation-annotations-incubator"; @Test void testExampleWithAnotherName() { diff --git a/instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-2.6/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/v2_6/timed/TimedExample.java b/instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-incubator/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/incubator/timed/TimedExample.java similarity index 90% rename from instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-2.6/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/v2_6/timed/TimedExample.java rename to instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-incubator/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/incubator/timed/TimedExample.java index 5bfca8b7a40f..561ac764e134 100644 --- a/instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-2.6/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/v2_6/timed/TimedExample.java +++ b/instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-incubator/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/incubator/timed/TimedExample.java @@ -3,10 +3,10 @@ * SPDX-License-Identifier: Apache-2.0 */ -package io.opentelemetry.javaagent.instrumentation.instrumentationannotations.v2_6.timed; +package io.opentelemetry.javaagent.instrumentation.instrumentationannotations.incubator.timed; -import io.opentelemetry.instrumentation.annotations.StaticMetricAttribute; -import io.opentelemetry.instrumentation.annotations.Timed; +import io.opentelemetry.instrumentation.annotations.incubator.StaticMetricAttribute; +import io.opentelemetry.instrumentation.annotations.incubator.Timed; import java.util.concurrent.CompletableFuture; import java.util.concurrent.TimeUnit; diff --git a/instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-2.6/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/v2_6/timed/TimedInstrumentationTest.java b/instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-incubator/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/incubator/timed/TimedInstrumentationTest.java similarity index 96% rename from instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-2.6/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/v2_6/timed/TimedInstrumentationTest.java rename to instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-incubator/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/incubator/timed/TimedInstrumentationTest.java index 9b2bd56af656..134ccadf8faa 100644 --- a/instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-2.6/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/v2_6/timed/TimedInstrumentationTest.java +++ b/instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-incubator/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/incubator/timed/TimedInstrumentationTest.java @@ -3,10 +3,10 @@ * SPDX-License-Identifier: Apache-2.0 */ -package io.opentelemetry.javaagent.instrumentation.instrumentationannotations.v2_6.timed; +package io.opentelemetry.javaagent.instrumentation.instrumentationannotations.incubator.timed; -import static io.opentelemetry.javaagent.instrumentation.instrumentationannotations.v2_6.timed.TimedExample.METRIC_DESCRIPTION; -import static io.opentelemetry.javaagent.instrumentation.instrumentationannotations.v2_6.timed.TimedExample.METRIC_NAME; +import static io.opentelemetry.javaagent.instrumentation.instrumentationannotations.incubator.timed.TimedExample.METRIC_DESCRIPTION; +import static io.opentelemetry.javaagent.instrumentation.instrumentationannotations.incubator.timed.TimedExample.METRIC_NAME; import static org.assertj.core.api.Assertions.assertThat; import io.opentelemetry.api.common.AttributeKey; @@ -22,7 +22,7 @@ class TimedInstrumentationTest { AgentInstrumentationExtension.create(); private static final String TIMED_INSTRUMENTATION_NAME = - "io.opentelemetry.opentelemetry-instrumentation-annotations-2.6"; + "io.opentelemetry.opentelemetry-instrumentation-annotations-incubator"; @Test void testExampleWithName() { diff --git a/javaagent/build.gradle.kts b/javaagent/build.gradle.kts index f827214b1a5c..e801fd7cfd83 100644 --- a/javaagent/build.gradle.kts +++ b/javaagent/build.gradle.kts @@ -76,7 +76,7 @@ dependencies { baseJavaagentLibs(project(":instrumentation:opentelemetry-api:opentelemetry-api-1.4:javaagent")) baseJavaagentLibs(project(":instrumentation:opentelemetry-instrumentation-api:javaagent")) baseJavaagentLibs(project(":instrumentation:opentelemetry-instrumentation-annotations:opentelemetry-instrumentation-annotations-1.16:javaagent")) - baseJavaagentLibs(project(":instrumentation:opentelemetry-instrumentation-annotations:opentelemetry-instrumentation-annotations-2.6:javaagent")) + baseJavaagentLibs(project(":instrumentation:opentelemetry-instrumentation-annotations:opentelemetry-instrumentation-annotations-incubator:javaagent")) baseJavaagentLibs(project(":instrumentation:executors:javaagent")) baseJavaagentLibs(project(":instrumentation:internal:internal-application-logger:javaagent")) baseJavaagentLibs(project(":instrumentation:internal:internal-class-loader:javaagent")) diff --git a/settings.gradle.kts b/settings.gradle.kts index 07174d810ee8..7a42e9854bd3 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -459,8 +459,8 @@ include(":instrumentation:opentelemetry-api:opentelemetry-api-1.38:javaagent") include(":instrumentation:opentelemetry-extension-annotations-1.0:javaagent") include(":instrumentation:opentelemetry-extension-kotlin-1.0:javaagent") include(":instrumentation:opentelemetry-instrumentation-annotations:opentelemetry-instrumentation-annotations-1.16:javaagent") -include(":instrumentation:opentelemetry-instrumentation-annotations:opentelemetry-instrumentation-annotations-2.6:javaagent") include(":instrumentation:opentelemetry-instrumentation-annotations:opentelemetry-instrumentation-annotations-common:javaagent") +include(":instrumentation:opentelemetry-instrumentation-annotations:opentelemetry-instrumentation-annotations-incubator:javaagent") include(":instrumentation:opentelemetry-instrumentation-api:javaagent") include(":instrumentation:opentelemetry-instrumentation-api:testing") include(":instrumentation:oracle-ucp-11.2:javaagent") From 6ba7771280b3fc3c0d5a7ed216c2c5a54783f90d Mon Sep 17 00:00:00 2001 From: Lauri Tulmin Date: Tue, 13 Aug 2024 19:11:02 +0300 Subject: [PATCH 18/21] address review comment --- .../instrumentation/annotations/incubator/Counted.java | 2 +- .../annotations/incubator/MetricAttribute.java | 7 +++---- .../instrumentation/annotations/incubator/Timed.java | 2 +- 3 files changed, 5 insertions(+), 6 deletions(-) diff --git a/instrumentation-annotations-incubator/src/main/java/io/opentelemetry/instrumentation/annotations/incubator/Counted.java b/instrumentation-annotations-incubator/src/main/java/io/opentelemetry/instrumentation/annotations/incubator/Counted.java index 35e5cc3b001b..3071a53c78f6 100644 --- a/instrumentation-annotations-incubator/src/main/java/io/opentelemetry/instrumentation/annotations/incubator/Counted.java +++ b/instrumentation-annotations-incubator/src/main/java/io/opentelemetry/instrumentation/annotations/incubator/Counted.java @@ -70,7 +70,7 @@ * *

By default, the instrument will not record an attribute with the return value. * - *

Warning: be careful to fill it because it might cause an explosion of the cardinality on + *

Warning: be careful using this because it might cause an explosion of the cardinality on * your metric */ String returnValueAttribute() default ""; diff --git a/instrumentation-annotations-incubator/src/main/java/io/opentelemetry/instrumentation/annotations/incubator/MetricAttribute.java b/instrumentation-annotations-incubator/src/main/java/io/opentelemetry/instrumentation/annotations/incubator/MetricAttribute.java index 975638922c30..484db7b89516 100644 --- a/instrumentation-annotations-incubator/src/main/java/io/opentelemetry/instrumentation/annotations/incubator/MetricAttribute.java +++ b/instrumentation-annotations-incubator/src/main/java/io/opentelemetry/instrumentation/annotations/incubator/MetricAttribute.java @@ -20,20 +20,19 @@ *

If you are a library developer, then probably you should NOT use this annotation, because it * is non-functional without the OpenTelemetry auto-instrumentation agent, or some other annotation * processor. + * + *

Warning: be careful using this because it might cause an explosion of the cardinality on your + * metric. */ @Target(ElementType.PARAMETER) @Retention(RetentionPolicy.RUNTIME) public @interface MetricAttribute { - /** * Optional name of the attribute. * *

If not specified and the code is compiled using the `{@code -parameters}` argument to * `javac`, the parameter name will be used instead. If the parameter name is not available, e.g., * because the code was not compiled with that flag, the attribute will be ignored. - * - *

Warning: be careful to fill it because it might cause an explosion of the cardinality on - * your metric */ String value() default ""; } diff --git a/instrumentation-annotations-incubator/src/main/java/io/opentelemetry/instrumentation/annotations/incubator/Timed.java b/instrumentation-annotations-incubator/src/main/java/io/opentelemetry/instrumentation/annotations/incubator/Timed.java index 0944cc8b5311..d096defcde3f 100644 --- a/instrumentation-annotations-incubator/src/main/java/io/opentelemetry/instrumentation/annotations/incubator/Timed.java +++ b/instrumentation-annotations-incubator/src/main/java/io/opentelemetry/instrumentation/annotations/incubator/Timed.java @@ -66,7 +66,7 @@ * *

By default, the instrument will not record an attribute with the return value. * - *

Warning: be careful to fill it because it might cause an explosion of the cardinality on + *

Warning: be careful using this because it might cause an explosion of the cardinality on * your metric */ String returnValueAttribute() default ""; From 00103678737b245b61df817c4d8c4d9df1f02468 Mon Sep 17 00:00:00 2001 From: Lauri Tulmin Date: Wed, 14 Aug 2024 16:19:08 +0300 Subject: [PATCH 19/21] move return value attribute to separate annotation --- .../annotations/incubator/Counted.java | 13 ------- .../incubator/MetricAttribute.java | 1 + .../MetricAttributeForReturnValue.java | 38 +++++++++++++++++++ .../annotations/incubator/Timed.java | 13 ------- .../incubator/CountedHelper.java | 4 +- .../incubator/MetricsAnnotationHelper.java | 9 +++-- .../incubator/TimedHelper.java | 4 +- .../incubator/counted/CountedExample.java | 7 +++- .../incubator/timed/TimedExample.java | 7 +++- 9 files changed, 57 insertions(+), 39 deletions(-) create mode 100644 instrumentation-annotations-incubator/src/main/java/io/opentelemetry/instrumentation/annotations/incubator/MetricAttributeForReturnValue.java diff --git a/instrumentation-annotations-incubator/src/main/java/io/opentelemetry/instrumentation/annotations/incubator/Counted.java b/instrumentation-annotations-incubator/src/main/java/io/opentelemetry/instrumentation/annotations/incubator/Counted.java index 3071a53c78f6..f5dcf2d39a4a 100644 --- a/instrumentation-annotations-incubator/src/main/java/io/opentelemetry/instrumentation/annotations/incubator/Counted.java +++ b/instrumentation-annotations-incubator/src/main/java/io/opentelemetry/instrumentation/annotations/incubator/Counted.java @@ -61,17 +61,4 @@ *

This property would not take effect if the value is not specified. */ String unit() default "{invocation}"; - - /** - * Attribute name for the return value. - * - *

The name of the attribute for the return value of the method call. {@link Object#toString()} - * may be called on the return value to convert it to a String. - * - *

By default, the instrument will not record an attribute with the return value. - * - *

Warning: be careful using this because it might cause an explosion of the cardinality on - * your metric - */ - String returnValueAttribute() default ""; } diff --git a/instrumentation-annotations-incubator/src/main/java/io/opentelemetry/instrumentation/annotations/incubator/MetricAttribute.java b/instrumentation-annotations-incubator/src/main/java/io/opentelemetry/instrumentation/annotations/incubator/MetricAttribute.java index 484db7b89516..d12ca1770eb1 100644 --- a/instrumentation-annotations-incubator/src/main/java/io/opentelemetry/instrumentation/annotations/incubator/MetricAttribute.java +++ b/instrumentation-annotations-incubator/src/main/java/io/opentelemetry/instrumentation/annotations/incubator/MetricAttribute.java @@ -27,6 +27,7 @@ @Target(ElementType.PARAMETER) @Retention(RetentionPolicy.RUNTIME) public @interface MetricAttribute { + /** * Optional name of the attribute. * diff --git a/instrumentation-annotations-incubator/src/main/java/io/opentelemetry/instrumentation/annotations/incubator/MetricAttributeForReturnValue.java b/instrumentation-annotations-incubator/src/main/java/io/opentelemetry/instrumentation/annotations/incubator/MetricAttributeForReturnValue.java new file mode 100644 index 000000000000..fbb6de40c52e --- /dev/null +++ b/instrumentation-annotations-incubator/src/main/java/io/opentelemetry/instrumentation/annotations/incubator/MetricAttributeForReturnValue.java @@ -0,0 +1,38 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.instrumentation.annotations.incubator; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * This annotation allows for adding method return value as attribute to the metrics recorded using + * {@link Timed} and {@link Counted} annotations. + * + *

Application developers can use this annotation to signal OpenTelemetry auto-instrumentation + * that the attribute should be created. + * + *

If you are a library developer, then probably you should NOT use this annotation, because it + * is non-functional without the OpenTelemetry auto-instrumentation agent, or some other annotation + * processor. + * + *

Warning: be careful using this because it might cause an explosion of the cardinality on your + * metric. + */ +@Target(ElementType.METHOD) +@Retention(RetentionPolicy.RUNTIME) +public @interface MetricAttributeForReturnValue { + + /** + * Attribute name for the return value. + * + *

The name of the attribute for the return value of the method call. {@link Object#toString()} + * may be called on the return value to convert it to a String. + */ + String value(); +} diff --git a/instrumentation-annotations-incubator/src/main/java/io/opentelemetry/instrumentation/annotations/incubator/Timed.java b/instrumentation-annotations-incubator/src/main/java/io/opentelemetry/instrumentation/annotations/incubator/Timed.java index d096defcde3f..761b231741d0 100644 --- a/instrumentation-annotations-incubator/src/main/java/io/opentelemetry/instrumentation/annotations/incubator/Timed.java +++ b/instrumentation-annotations-incubator/src/main/java/io/opentelemetry/instrumentation/annotations/incubator/Timed.java @@ -57,17 +57,4 @@ *

Default is seconds. */ TimeUnit unit() default TimeUnit.SECONDS; - - /** - * Attribute name for the return value. - * - *

The name of the attribute for the return value of the method call. {@link Object#toString()} - * may be called on the return value to convert it to a String. - * - *

By default, the instrument will not record an attribute with the return value. - * - *

Warning: be careful using this because it might cause an explosion of the cardinality on - * your metric - */ - String returnValueAttribute() default ""; } diff --git a/instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-incubator/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/incubator/CountedHelper.java b/instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-incubator/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/incubator/CountedHelper.java index cb0ac6493338..c54187c6c534 100644 --- a/instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-incubator/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/incubator/CountedHelper.java +++ b/instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-incubator/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/incubator/CountedHelper.java @@ -59,9 +59,7 @@ private static class MethodCounter { .setDescription(countedAnnotation.description()) .setUnit(countedAnnotation.unit()) .build(); - - String returnValueAttribute = countedAnnotation.returnValueAttribute(); - attributeHelper = new MetricAttributeHelper(method, returnValueAttribute); + attributeHelper = new MetricAttributeHelper(method); } void record(Object returnValue, Object[] arguments, Throwable throwable) { diff --git a/instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-incubator/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/incubator/MetricsAnnotationHelper.java b/instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-incubator/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/incubator/MetricsAnnotationHelper.java index 37417fea71dc..440925bd1f8c 100644 --- a/instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-incubator/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/incubator/MetricsAnnotationHelper.java +++ b/instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-incubator/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/incubator/MetricsAnnotationHelper.java @@ -6,6 +6,7 @@ package io.opentelemetry.javaagent.instrumentation.instrumentationannotations.incubator; import application.io.opentelemetry.instrumentation.annotations.incubator.MetricAttribute; +import application.io.opentelemetry.instrumentation.annotations.incubator.MetricAttributeForReturnValue; import application.io.opentelemetry.instrumentation.annotations.incubator.StaticMetricAttribute; import io.opentelemetry.api.GlobalOpenTelemetry; import io.opentelemetry.api.common.Attributes; @@ -65,11 +66,13 @@ static class MetricAttributeHelper { private final BiConsumer bindReturn; private final Attributes staticAttributes; - MetricAttributeHelper(Method method, String returnValueAttribute) { + MetricAttributeHelper(Method method) { bindParameters = MethodBinder.bindParameters(method, PARAMETER_ATTRIBUTE_NAMES_EXTRACTOR); + MetricAttributeForReturnValue returnValueAttribute = + method.getAnnotation(MetricAttributeForReturnValue.class); bindReturn = - !returnValueAttribute.isEmpty() - ? MethodBinder.bindReturnValue(method, returnValueAttribute) + returnValueAttribute != null + ? MethodBinder.bindReturnValue(method, returnValueAttribute.value()) : null; AttributesBuilder attributesBuilder = Attributes.builder(); diff --git a/instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-incubator/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/incubator/TimedHelper.java b/instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-incubator/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/incubator/TimedHelper.java index f32c2b789f7d..537d0e4efa1b 100644 --- a/instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-incubator/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/incubator/TimedHelper.java +++ b/instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-incubator/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/incubator/TimedHelper.java @@ -96,9 +96,7 @@ private static class MethodTimer { .setDescription(timedAnnotation.description()) .setUnit(timeUnitToString(unit)) .build(); - - String returnValueAttribute = timedAnnotation.returnValueAttribute(); - attributeHelper = new MetricAttributeHelper(method, returnValueAttribute); + attributeHelper = new MetricAttributeHelper(method); } void record(Object returnValue, Object[] arguments, Throwable throwable, long startNanoTime) { diff --git a/instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-incubator/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/incubator/counted/CountedExample.java b/instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-incubator/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/incubator/counted/CountedExample.java index d25083b343a1..915933c53b3c 100644 --- a/instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-incubator/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/incubator/counted/CountedExample.java +++ b/instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-incubator/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/incubator/counted/CountedExample.java @@ -6,6 +6,7 @@ package io.opentelemetry.javaagent.instrumentation.instrumentationannotations.incubator.counted; import io.opentelemetry.instrumentation.annotations.incubator.Counted; +import io.opentelemetry.instrumentation.annotations.incubator.MetricAttributeForReturnValue; import io.opentelemetry.instrumentation.annotations.incubator.StaticMetricAttribute; import java.util.concurrent.CompletableFuture; @@ -31,7 +32,8 @@ public void exampleWithUnit() {} @StaticMetricAttribute(name = "key2", value = "value2") public void exampleWithAdditionalAttributes1() {} - @Counted(value = "example.with.return.count", returnValueAttribute = "returnValue") + @Counted(value = "example.with.return.count") + @MetricAttributeForReturnValue("returnValue") public ReturnObject exampleWithReturnValueAttribute() { return new ReturnObject(); } @@ -44,7 +46,8 @@ public void exampleWithException() { @Counted("example.ignore.count") public void exampleIgnore() {} - @Counted(value = "example.completable.future.count", returnValueAttribute = "returnValue") + @Counted(value = "example.completable.future.count") + @MetricAttributeForReturnValue("returnValue") public CompletableFuture completableFuture(CompletableFuture future) { return future; } diff --git a/instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-incubator/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/incubator/timed/TimedExample.java b/instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-incubator/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/incubator/timed/TimedExample.java index 561ac764e134..ae9f4ce93ef0 100644 --- a/instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-incubator/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/incubator/timed/TimedExample.java +++ b/instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-incubator/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/incubator/timed/TimedExample.java @@ -5,6 +5,7 @@ package io.opentelemetry.javaagent.instrumentation.instrumentationannotations.incubator.timed; +import io.opentelemetry.instrumentation.annotations.incubator.MetricAttributeForReturnValue; import io.opentelemetry.instrumentation.annotations.incubator.StaticMetricAttribute; import io.opentelemetry.instrumentation.annotations.incubator.Timed; import java.util.concurrent.CompletableFuture; @@ -39,12 +40,14 @@ public void exampleWithException() { throw new IllegalStateException("test"); } - @Timed(value = "example.with.return.duration", returnValueAttribute = "returnValue") + @Timed(value = "example.with.return.duration") + @MetricAttributeForReturnValue("returnValue") public ReturnObject exampleWithReturnValueAttribute() { return new ReturnObject(); } - @Timed(value = "example.completable.future.duration", returnValueAttribute = "returnValue") + @Timed(value = "example.completable.future.duration") + @MetricAttributeForReturnValue("returnValue") public CompletableFuture completableFuture(CompletableFuture future) { return future; } From 04e3c4965eda563af49cfd747eb2491f25a45c51 Mon Sep 17 00:00:00 2001 From: Duncan-tree-zhou Date: Mon, 6 Jan 2025 23:28:45 +0800 Subject: [PATCH 20/21] rerun test --- .github/scripts/check-javaagent-suppression-keys.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/scripts/check-javaagent-suppression-keys.sh b/.github/scripts/check-javaagent-suppression-keys.sh index 0501ee6a3f4f..be82cf77f2c2 100755 --- a/.github/scripts/check-javaagent-suppression-keys.sh +++ b/.github/scripts/check-javaagent-suppression-keys.sh @@ -42,8 +42,8 @@ for file in $(find instrumentation -name "*Module.java"); do else expected="super\(\n? *\"$simple_module_name\",\n? *\"$module_name\"" fi - - echo "$module_name" + echo "simple_module_name: $simple_module_name" + echo "module_name: $module_name" matches=$(perl -0 -ne "print if /$expected/" "$file" | wc -l) if [ "$matches" == 0 ]; then From 40760c0bf4094794ab4e4cd53c12796b1702dd2e Mon Sep 17 00:00:00 2001 From: Duncan-tree-zhou Date: Tue, 7 Jan 2025 00:44:32 +0800 Subject: [PATCH 21/21] rerun test --- .../incubator/MetricsAnnotationInstrumentationModule.java | 1 - 1 file changed, 1 deletion(-) diff --git a/instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-incubator/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/incubator/MetricsAnnotationInstrumentationModule.java b/instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-incubator/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/incubator/MetricsAnnotationInstrumentationModule.java index dce08cd60a6e..05a790b5c8ff 100644 --- a/instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-incubator/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/incubator/MetricsAnnotationInstrumentationModule.java +++ b/instrumentation/opentelemetry-instrumentation-annotations/opentelemetry-instrumentation-annotations-incubator/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/incubator/MetricsAnnotationInstrumentationModule.java @@ -26,7 +26,6 @@ public class MetricsAnnotationInstrumentationModule extends InstrumentationModul public MetricsAnnotationInstrumentationModule() { super( - "opentelemetry-instrumentation-annotations", "opentelemetry-instrumentation-annotations-incubator", "metrics-annotations"); }