diff --git a/instrumentation-annotations/build.gradle.kts b/instrumentation-annotations/build.gradle.kts new file mode 100644 index 0000000000..242b44c527 --- /dev/null +++ b/instrumentation-annotations/build.gradle.kts @@ -0,0 +1,12 @@ +plugins { + id("otel.java-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/SpanAttribute.java b/instrumentation-annotations/src/main/java/io/opentelemetry/instrumentation/annotations/SpanAttribute.java new file mode 100644 index 0000000000..5a005213ab --- /dev/null +++ b/instrumentation-annotations/src/main/java/io/opentelemetry/instrumentation/annotations/SpanAttribute.java @@ -0,0 +1,36 @@ +/* + * 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 annotated by the {@link WithSpan} annotation + * should be added as an attribute to the newly created {@link io.opentelemetry.api.trace.Span}. + * Using this annotation is equivalent to calling {@code Span.currentSpan().setAttribute(...)} + * within the body of the method. + * + *
Application developers can use this annotation to signal OpenTelemetry auto-instrumentation + * that a new span attribute should be added to a span created when the parent method is executed. + * + *
If you are a library developer, then probably you should NOT use this annotation, because it + * is non-functional without some form of auto-instrumentation. + */ +@Target(ElementType.PARAMETER) +@Retention(RetentionPolicy.RUNTIME) +public @interface SpanAttribute { + /** + * 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. + */ + String value() default ""; +} diff --git a/instrumentation-annotations/src/main/java/io/opentelemetry/instrumentation/annotations/WithSpan.java b/instrumentation-annotations/src/main/java/io/opentelemetry/instrumentation/annotations/WithSpan.java new file mode 100644 index 0000000000..6b4cf4fefb --- /dev/null +++ b/instrumentation-annotations/src/main/java/io/opentelemetry/instrumentation/annotations/WithSpan.java @@ -0,0 +1,37 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.instrumentation.annotations; + +import io.opentelemetry.api.trace.SpanKind; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * This annotation marks that an execution of this method or constructor should result in a new + * {@link io.opentelemetry.api.trace.Span}. + * + *
Application developers can use this annotation to signal OpenTelemetry auto-instrumentation + * that a new span should be created whenever marked method is executed. + * + *
If you are a library developer, then probably you should NOT use this annotation, because it + * is non-functional without some form of auto-instrumentation. + */ +@Target({ElementType.METHOD, ElementType.CONSTRUCTOR}) +@Retention(RetentionPolicy.RUNTIME) +public @interface WithSpan { + /** + * Optional name of the created span. + * + *
If not specified, an appropriate default name should be created by auto-instrumentation. + * E.g. {@code "className"."method"} + */ + String value() default ""; + + /** Specify the {@link SpanKind} of span to be created. Defaults to {@link SpanKind#INTERNAL}. */ + SpanKind kind() default SpanKind.INTERNAL; +} diff --git a/instrumentation-annotations/src/main/java/io/opentelemetry/instrumentation/annotations/package-info.java b/instrumentation-annotations/src/main/java/io/opentelemetry/instrumentation/annotations/package-info.java new file mode 100644 index 0000000000..eadba12114 --- /dev/null +++ b/instrumentation-annotations/src/main/java/io/opentelemetry/instrumentation/annotations/package-info.java @@ -0,0 +1,18 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +/** + * This module contains various annotations that can be used by clients of OpenTelemetry API. They + * don't provide any functionality by themselves, but other modules, e.g. OpenTelemetry + * auto-instrumentation, can use them to enhance their functionality. + * + *
Note: If you are a library developer, then you should NOT use this module, because it is + * useless without some kind of annotation processing, such as bytecode manipulation during runtime. + * You cannot guarantee that users of your library will use that in their production system. + */ +@ParametersAreNonnullByDefault +package io.opentelemetry.instrumentation.annotations; + +import javax.annotation.ParametersAreNonnullByDefault; diff --git a/instrumentation-annotations/src/test/java/io/opentelemetry/instrumentation/annotations/WithSpanUsageExamples.java b/instrumentation-annotations/src/test/java/io/opentelemetry/instrumentation/annotations/WithSpanUsageExamples.java new file mode 100644 index 0000000000..1e4a92388c --- /dev/null +++ b/instrumentation-annotations/src/test/java/io/opentelemetry/instrumentation/annotations/WithSpanUsageExamples.java @@ -0,0 +1,47 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.instrumentation.annotations; + +import io.opentelemetry.api.trace.Span; +import io.opentelemetry.api.trace.SpanKind; + +/** + * This class is not a classical test. It's just a demonstration of possible usages of {@link + * WithSpan} annotation together with some explanations. The goal of this class is to serve as an + * early detection system for inconvenient API and unintended API breakage. + */ +@SuppressWarnings("unused") +public class WithSpanUsageExamples { + + /** + * A new {@link Span} will be created for this method's execution. The span's name will be + * automatically generated by OpenTelemetry auto-instrumentation, probably as + * "WithSpanUsageExamples.method1". + */ + @WithSpan + public void method1() {} + + /** Name of the generated span will be "shinyName". */ + @WithSpan("shinyName") + public void method2() {} + + /** + * A {@link Span} with the default name, and a {@link SpanKind} of {@link SpanKind#CONSUMER} will + * be created for this method. + */ + @WithSpan(kind = SpanKind.CONSUMER) + public void consume() {} + + /** + * A {@link Span} with the default name and kind and with default span attributes. + * + * @param attribute1 A span attribute with the default name of {@code attribute1}. + * @param value A span attribute with the name "attribute2". + */ + @WithSpan + public void attributes( + @SpanAttribute String attribute1, @SpanAttribute("attribute2") long value) {} +} diff --git a/settings.gradle.kts b/settings.gradle.kts index 24f973553a..f112967fd0 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -110,6 +110,7 @@ include(":instrumentation-api") include(":instrumentation-api-semconv") include(":instrumentation-appender-api-internal") include(":instrumentation-appender-sdk-internal") +include(":instrumentation-annotations") include(":instrumentation-api-annotation-support") // misc