diff --git a/instrumentation/aws-lambda/aws-lambda-core-1.0/library/build.gradle.kts b/instrumentation/aws-lambda/aws-lambda-core-1.0/library/build.gradle.kts index 7f08a41a962b..4fcb6700fd01 100644 --- a/instrumentation/aws-lambda/aws-lambda-core-1.0/library/build.gradle.kts +++ b/instrumentation/aws-lambda/aws-lambda-core-1.0/library/build.gradle.kts @@ -11,8 +11,6 @@ dependencies { library("com.amazonaws:aws-lambda-java-core:1.0.0") - implementation("io.opentelemetry.contrib:opentelemetry-aws-xray-propagator") - // We do lightweight parsing of JSON to extract HTTP headers from requests for propagation. // This will be commonly needed even for users that don't use events, but luckily it's not too big. // Note that Lambda itself uses Jackson, but does not expose it to the function so we need to include @@ -22,6 +20,7 @@ dependencies { // allows to get the function ARN testLibrary("com.amazonaws:aws-lambda-java-core:1.2.1") + testImplementation("io.opentelemetry.contrib:opentelemetry-aws-xray-propagator") testImplementation("io.opentelemetry:opentelemetry-sdk-extension-autoconfigure") testImplementation("io.opentelemetry:opentelemetry-extension-trace-propagators") testImplementation("com.google.guava:guava") diff --git a/instrumentation/aws-lambda/aws-lambda-core-1.0/library/src/main/java/io/opentelemetry/instrumentation/awslambdacore/v1_0/internal/AwsLambdaFunctionInstrumenterFactory.java b/instrumentation/aws-lambda/aws-lambda-core-1.0/library/src/main/java/io/opentelemetry/instrumentation/awslambdacore/v1_0/internal/AwsLambdaFunctionInstrumenterFactory.java index aeb828b8e743..277c358ca8e2 100644 --- a/instrumentation/aws-lambda/aws-lambda-core-1.0/library/src/main/java/io/opentelemetry/instrumentation/awslambdacore/v1_0/internal/AwsLambdaFunctionInstrumenterFactory.java +++ b/instrumentation/aws-lambda/aws-lambda-core-1.0/library/src/main/java/io/opentelemetry/instrumentation/awslambdacore/v1_0/internal/AwsLambdaFunctionInstrumenterFactory.java @@ -23,7 +23,6 @@ public static AwsLambdaFunctionInstrumenter createInstrumenter(OpenTelemetry ope openTelemetry, "io.opentelemetry.aws-lambda-core-1.0", AwsLambdaFunctionInstrumenterFactory::spanName) - .addSpanLinksExtractor(new AwsXrayEnvSpanLinksExtractor()) .addAttributesExtractor(new AwsLambdaFunctionAttributesExtractor()) .buildInstrumenter(SpanKindExtractor.alwaysServer())); } diff --git a/instrumentation/aws-lambda/aws-lambda-core-1.0/library/src/main/java/io/opentelemetry/instrumentation/awslambdacore/v1_0/internal/AwsXrayEnvSpanLinksExtractor.java b/instrumentation/aws-lambda/aws-lambda-core-1.0/library/src/main/java/io/opentelemetry/instrumentation/awslambdacore/v1_0/internal/AwsXrayEnvSpanLinksExtractor.java deleted file mode 100644 index c88cf20c917d..000000000000 --- a/instrumentation/aws-lambda/aws-lambda-core-1.0/library/src/main/java/io/opentelemetry/instrumentation/awslambdacore/v1_0/internal/AwsXrayEnvSpanLinksExtractor.java +++ /dev/null @@ -1,84 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -package io.opentelemetry.instrumentation.awslambdacore.v1_0.internal; - -import io.opentelemetry.api.common.AttributeKey; -import io.opentelemetry.api.common.Attributes; -import io.opentelemetry.api.trace.Span; -import io.opentelemetry.api.trace.SpanContext; -import io.opentelemetry.context.Context; -import io.opentelemetry.context.propagation.TextMapGetter; -import io.opentelemetry.contrib.awsxray.propagator.AwsXrayPropagator; -import io.opentelemetry.instrumentation.api.instrumenter.SpanLinksBuilder; -import io.opentelemetry.instrumentation.api.instrumenter.SpanLinksExtractor; -import io.opentelemetry.instrumentation.awslambdacore.v1_0.AwsLambdaRequest; -import java.util.Collections; -import java.util.Locale; -import java.util.Map; - -/** - * This class is internal and is hence not for public use. Its APIs are unstable and can change at - * any time. - */ -final class AwsXrayEnvSpanLinksExtractor implements SpanLinksExtractor { - - private static final String AWS_TRACE_HEADER_ENV_KEY = "_X_AMZN_TRACE_ID"; - private static final String AWS_TRACE_HEADER_PROP = "com.amazonaws.xray.traceHeader"; - // lower-case map getter used for extraction - private static final String AWS_TRACE_HEADER_PROPAGATOR_KEY = "x-amzn-trace-id"; - - private static final Attributes LINK_ATTRIBUTES = - Attributes.of(AttributeKey.stringKey("source"), "x-ray-env"); - - @Override - public void extract( - SpanLinksBuilder spanLinks, - io.opentelemetry.context.Context parentContext, - AwsLambdaRequest awsLambdaRequest) { - extract(spanLinks); - } - - public static void extract(SpanLinksBuilder spanLinks) { - Map contextMap = getTraceHeaderMap(); - if (contextMap.isEmpty()) { - return; - } - Context xrayContext = - AwsXrayPropagator.getInstance().extract(Context.root(), contextMap, MapGetter.INSTANCE); - SpanContext envVarSpanCtx = Span.fromContext(xrayContext).getSpanContext(); - if (envVarSpanCtx.isValid()) { - spanLinks.addLink(envVarSpanCtx, LINK_ATTRIBUTES); - } - } - - private static Map getTraceHeaderMap() { - String traceHeader = System.getProperty(AWS_TRACE_HEADER_PROP); - if (isEmptyOrNull(traceHeader)) { - traceHeader = System.getenv(AWS_TRACE_HEADER_ENV_KEY); - } - return isEmptyOrNull(traceHeader) - ? Collections.emptyMap() - : Collections.singletonMap(AWS_TRACE_HEADER_PROPAGATOR_KEY, traceHeader); - } - - private static boolean isEmptyOrNull(String value) { - return value == null || value.isEmpty(); - } - - private enum MapGetter implements TextMapGetter> { - INSTANCE; - - @Override - public Iterable keys(Map map) { - return map.keySet(); - } - - @Override - public String get(Map map, String s) { - return map.get(s.toLowerCase(Locale.ROOT)); - } - } -} diff --git a/instrumentation/aws-lambda/aws-lambda-core-1.0/library/src/test/java/io/opentelemetry/instrumentation/awslambdacore/v1_0/internal/AwsXrayEnvSpanLinksExtractorTest.java b/instrumentation/aws-lambda/aws-lambda-core-1.0/library/src/test/java/io/opentelemetry/instrumentation/awslambdacore/v1_0/internal/AwsXrayEnvSpanLinksExtractorTest.java deleted file mode 100644 index 509bfbd05eaf..000000000000 --- a/instrumentation/aws-lambda/aws-lambda-core-1.0/library/src/test/java/io/opentelemetry/instrumentation/awslambdacore/v1_0/internal/AwsXrayEnvSpanLinksExtractorTest.java +++ /dev/null @@ -1,128 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -package io.opentelemetry.instrumentation.awslambdacore.v1_0.internal; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.ArgumentMatchers.eq; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.verifyNoInteractions; - -import io.opentelemetry.api.common.AttributeKey; -import io.opentelemetry.api.common.Attributes; -import io.opentelemetry.api.trace.SpanContext; -import io.opentelemetry.instrumentation.api.instrumenter.SpanLinksBuilder; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; -import org.mockito.ArgumentCaptor; -import uk.org.webcompere.systemstubs.environment.EnvironmentVariables; -import uk.org.webcompere.systemstubs.jupiter.SystemStub; -import uk.org.webcompere.systemstubs.jupiter.SystemStubsExtension; -import uk.org.webcompere.systemstubs.properties.SystemProperties; - -/** - * This class is internal and is hence not for public use. Its APIs are unstable and can change at - * any time. - */ -@ExtendWith(SystemStubsExtension.class) -class AwsXrayEnvSpanLinksExtractorTest { - private static final Attributes EXPECTED_LINK_ATTRIBUTES = - Attributes.of(AttributeKey.stringKey("source"), "x-ray-env"); - - @SystemStub final EnvironmentVariables environmentVariables = new EnvironmentVariables(); - @SystemStub final SystemProperties systemProperties = new SystemProperties(); - - @Test - void shouldIgnoreIfEnvVarAndSystemPropertyEmpty() { - // given - SpanLinksBuilder spanLinksBuilder = mock(SpanLinksBuilder.class); - environmentVariables.set("_X_AMZN_TRACE_ID", ""); - systemProperties.set("com.amazonaws.xray.traceHeader", ""); - // when - AwsXrayEnvSpanLinksExtractor.extract(spanLinksBuilder); - // then - verifyNoInteractions(spanLinksBuilder); - } - - @Test - void shouldLinkAwsParentHeaderAndChooseSystemPropertyIfValidAndNotSampled() { - // given - SpanLinksBuilder spanLinksBuilder = mock(SpanLinksBuilder.class); - environmentVariables.set( - "_X_AMZN_TRACE_ID", - "Root=1-8a3c60f7-d188f8fa79d48a391a778fa6;Parent=0000000000000456;Sampled=0"); - systemProperties.set( - "com.amazonaws.xray.traceHeader", - "Root=1-8a3c60f7-d188f8fa79d48a391a778fa7;Parent=0000000000000789;Sampled=0"); - // when - AwsXrayEnvSpanLinksExtractor.extract(spanLinksBuilder); - // then - ArgumentCaptor captor = ArgumentCaptor.forClass(SpanContext.class); - verify(spanLinksBuilder).addLink(captor.capture(), eq(EXPECTED_LINK_ATTRIBUTES)); - SpanContext spanContext = captor.getValue(); - assertThat(spanContext.isValid()).isTrue(); - assertThat(spanContext.isSampled()).isFalse(); - assertThat(spanContext.getSpanId()).isEqualTo("0000000000000789"); - assertThat(spanContext.getTraceId()).isEqualTo("8a3c60f7d188f8fa79d48a391a778fa7"); - } - - @Test - void shouldLinkAwsParentHeaderIfValidAndNotSampled() { - // given - SpanLinksBuilder spanLinksBuilder = mock(SpanLinksBuilder.class); - environmentVariables.set( - "_X_AMZN_TRACE_ID", - "Root=1-8a3c60f7-d188f8fa79d48a391a778fa6;Parent=0000000000000456;Sampled=0"); - // when - AwsXrayEnvSpanLinksExtractor.extract(spanLinksBuilder); - // then - ArgumentCaptor captor = ArgumentCaptor.forClass(SpanContext.class); - verify(spanLinksBuilder).addLink(captor.capture(), eq(EXPECTED_LINK_ATTRIBUTES)); - SpanContext spanContext = captor.getValue(); - assertThat(spanContext.isValid()).isTrue(); - assertThat(spanContext.isSampled()).isFalse(); - assertThat(spanContext.getSpanId()).isEqualTo("0000000000000456"); - assertThat(spanContext.getTraceId()).isEqualTo("8a3c60f7d188f8fa79d48a391a778fa6"); - } - - @Test - void shouldLinkAwsParentHeaderIfValidAndNotSampledSystemProperty() { - // given - SpanLinksBuilder spanLinksBuilder = mock(SpanLinksBuilder.class); - systemProperties.set( - "com.amazonaws.xray.traceHeader", - "Root=1-8a3c60f7-d188f8fa79d48a391a778fa6;Parent=0000000000000456;Sampled=0"); - // when - AwsXrayEnvSpanLinksExtractor.extract(spanLinksBuilder); - // then - ArgumentCaptor captor = ArgumentCaptor.forClass(SpanContext.class); - verify(spanLinksBuilder).addLink(captor.capture(), eq(EXPECTED_LINK_ATTRIBUTES)); - SpanContext spanContext = captor.getValue(); - assertThat(spanContext.isValid()).isTrue(); - assertThat(spanContext.isSampled()).isFalse(); - assertThat(spanContext.getSpanId()).isEqualTo("0000000000000456"); - assertThat(spanContext.getTraceId()).isEqualTo("8a3c60f7d188f8fa79d48a391a778fa6"); - } - - @Test - void shouldLinkAwsParentHeaderIfValidAndSampledSystemProperty() { - // given - SpanLinksBuilder spanLinksBuilder = mock(SpanLinksBuilder.class); - systemProperties.set( - "com.amazonaws.xray.traceHeader", - "Root=1-8a3c60f7-d188f8fa79d48a391a778fa6;Parent=0000000000000456;Sampled=1"); - // when - AwsXrayEnvSpanLinksExtractor.extract(spanLinksBuilder); - // then - ArgumentCaptor captor = ArgumentCaptor.forClass(SpanContext.class); - verify(spanLinksBuilder).addLink(captor.capture(), eq(EXPECTED_LINK_ATTRIBUTES)); - SpanContext spanContext = captor.getValue(); - assertThat(spanContext.isValid()).isTrue(); - assertThat(spanContext.isSampled()).isTrue(); - assertThat(spanContext.getSpanId()).isEqualTo("0000000000000456"); - assertThat(spanContext.getTraceId()).isEqualTo("8a3c60f7d188f8fa79d48a391a778fa6"); - } -} diff --git a/instrumentation/aws-lambda/aws-lambda-core-1.0/testing/src/main/java/io/opentelemetry/instrumentation/awslambdacore/v1_0/AbstractAwsLambdaTest.java b/instrumentation/aws-lambda/aws-lambda-core-1.0/testing/src/main/java/io/opentelemetry/instrumentation/awslambdacore/v1_0/AbstractAwsLambdaTest.java index 25a32896aad5..32cfe1742e6d 100644 --- a/instrumentation/aws-lambda/aws-lambda-core-1.0/testing/src/main/java/io/opentelemetry/instrumentation/awslambdacore/v1_0/AbstractAwsLambdaTest.java +++ b/instrumentation/aws-lambda/aws-lambda-core-1.0/testing/src/main/java/io/opentelemetry/instrumentation/awslambdacore/v1_0/AbstractAwsLambdaTest.java @@ -12,8 +12,6 @@ import com.amazonaws.services.lambda.runtime.Context; import com.amazonaws.services.lambda.runtime.RequestHandler; -import io.opentelemetry.api.common.AttributeKey; -import io.opentelemetry.api.common.Attributes; import io.opentelemetry.api.trace.SpanKind; import io.opentelemetry.instrumentation.testing.junit.InstrumentationExtension; import io.opentelemetry.sdk.trace.data.StatusData; @@ -91,11 +89,15 @@ void handlerTracedWithException() { equalTo(SemanticAttributes.FAAS_INVOCATION_ID, "1-22-333")))); } + /** + * For more details about active tracing see + * https://docs.aws.amazon.com/lambda/latest/dg/services-xray.html + */ @Test @SetEnvironmentVariable( key = "_X_AMZN_TRACE_ID", value = "Root=1-8a3c60f7-d188f8fa79d48a391a778fa6;Parent=0000000000000456;Sampled=1") - void handlerLinksToInfrastructureTrace() { + void handlerDoesNotLinkToActiveTracingSpan() { String result = handler().handleRequest("hello", context); assertThat(result).isEqualTo("world"); @@ -106,22 +108,8 @@ void handlerLinksToInfrastructureTrace() { span -> span.hasName("my_function") .hasKind(SpanKind.SERVER) - .hasLinksSatisfying( - links -> - assertThat(links) - .singleElement() - .satisfies( - link -> { - assertThat(link.getSpanContext().getTraceId()) - .isEqualTo("8a3c60f7d188f8fa79d48a391a778fa6"); - assertThat(link.getSpanContext().getSpanId()) - .isEqualTo("0000000000000456"); - assertThat(link.getAttributes()) - .isEqualTo( - Attributes.of( - AttributeKey.stringKey("source"), - "x-ray-env")); - })) + .hasNoParent() + .hasLinks() .hasAttributesSatisfyingExactly( equalTo(SemanticAttributes.FAAS_INVOCATION_ID, "1-22-333")))); }