From 6f13fa2bed9bbcab8145d0c3aa8e5bcdc489d29d Mon Sep 17 00:00:00 2001 From: Gregor Zeitlinger Date: Tue, 23 Sep 2025 15:48:23 +0200 Subject: [PATCH 1/5] add declarative config support for AWS X-Ray --- aws-xray/build.gradle.kts | 2 + .../contrib/awsxray/AwsXrayRemoteSampler.java | 7 +++ ...AwsXrayRemoteSamplerComponentProvider.java | 45 +++++++++++++++++++ ...rayRemoteSamplerComponentProviderTest.java | 33 ++++++++++++++ 4 files changed, 87 insertions(+) create mode 100644 aws-xray/src/main/java/io/opentelemetry/contrib/awsxray/AwsXrayRemoteSamplerComponentProvider.java create mode 100644 aws-xray/src/test/java/io/opentelemetry/contrib/awsxray/AwsXrayRemoteSamplerComponentProviderTest.java diff --git a/aws-xray/build.gradle.kts b/aws-xray/build.gradle.kts index 34751549e..ed9787c06 100644 --- a/aws-xray/build.gradle.kts +++ b/aws-xray/build.gradle.kts @@ -12,6 +12,7 @@ dependencies { compileOnly("io.opentelemetry:opentelemetry-sdk-extension-autoconfigure") implementation("io.opentelemetry.semconv:opentelemetry-semconv:1.37.0") + compileOnly("io.opentelemetry:opentelemetry-sdk-extension-incubator") implementation("com.squareup.okhttp3:okhttp") implementation("io.opentelemetry.semconv:opentelemetry-semconv") @@ -30,6 +31,7 @@ dependencies { testImplementation("com.linecorp.armeria:armeria-junit5") testImplementation("io.opentelemetry:opentelemetry-sdk-extension-autoconfigure") + testImplementation("io.opentelemetry:opentelemetry-sdk-extension-incubator") testImplementation("io.opentelemetry:opentelemetry-sdk-testing") testImplementation("com.google.guava:guava") testImplementation("org.slf4j:slf4j-simple") diff --git a/aws-xray/src/main/java/io/opentelemetry/contrib/awsxray/AwsXrayRemoteSampler.java b/aws-xray/src/main/java/io/opentelemetry/contrib/awsxray/AwsXrayRemoteSampler.java index bfb2eee66..06d35e3a5 100644 --- a/aws-xray/src/main/java/io/opentelemetry/contrib/awsxray/AwsXrayRemoteSampler.java +++ b/aws-xray/src/main/java/io/opentelemetry/contrib/awsxray/AwsXrayRemoteSampler.java @@ -58,6 +58,7 @@ public final class AwsXrayRemoteSampler implements Sampler, Closeable { private final Resource resource; private final Clock clock; + private final String endpoint; private final Sampler initialSampler; private final XraySamplerClient client; private final ScheduledExecutorService executor; @@ -92,6 +93,7 @@ public static AwsXrayRemoteSamplerBuilder newBuilder(Resource resource) { long pollingIntervalNanos) { this.resource = resource; this.clock = clock; + this.endpoint = endpoint; this.initialSampler = initialSampler; client = new XraySamplerClient(endpoint); executor = @@ -296,4 +298,9 @@ XraySamplerClient getClient() { Resource getResource() { return resource; } + + @Override + public String toString() { + return "AwsXrayRemoteSampler{endpoint=" + endpoint + '}'; + } } diff --git a/aws-xray/src/main/java/io/opentelemetry/contrib/awsxray/AwsXrayRemoteSamplerComponentProvider.java b/aws-xray/src/main/java/io/opentelemetry/contrib/awsxray/AwsXrayRemoteSamplerComponentProvider.java new file mode 100644 index 000000000..f1d320cf3 --- /dev/null +++ b/aws-xray/src/main/java/io/opentelemetry/contrib/awsxray/AwsXrayRemoteSamplerComponentProvider.java @@ -0,0 +1,45 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.contrib.awsxray; + +import com.google.auto.service.AutoService; +import io.opentelemetry.api.incubator.config.DeclarativeConfigProperties; +import io.opentelemetry.sdk.autoconfigure.spi.internal.ComponentProvider; +import io.opentelemetry.sdk.resources.Resource; +import io.opentelemetry.sdk.trace.samplers.Sampler; + +/** + * File configuration SPI implementation for {@link AwsXrayRemoteSampler}. + * + *

This class is internal and is hence not for public use. Its APIs are unstable and can change + * at any time. + */ +@SuppressWarnings("rawtypes") +@AutoService(ComponentProvider.class) +public class AwsXrayRemoteSamplerComponentProvider implements ComponentProvider { + @Override + public Class getType() { + return Sampler.class; + } + + @Override + public String getName() { + return "xray"; + } + + @Override + public Sampler create(DeclarativeConfigProperties config) { + Resource resource = io.opentelemetry.contrib.awsxray.ResourceHolder.getResource(); + AwsXrayRemoteSamplerBuilder builder = AwsXrayRemoteSampler.newBuilder(resource); + + String endpoint = config.getString("endpoint"); + if (endpoint != null) { + builder.setEndpoint(endpoint); + } + + return builder.build(); + } +} diff --git a/aws-xray/src/test/java/io/opentelemetry/contrib/awsxray/AwsXrayRemoteSamplerComponentProviderTest.java b/aws-xray/src/test/java/io/opentelemetry/contrib/awsxray/AwsXrayRemoteSamplerComponentProviderTest.java new file mode 100644 index 000000000..bc68ab4ee --- /dev/null +++ b/aws-xray/src/test/java/io/opentelemetry/contrib/awsxray/AwsXrayRemoteSamplerComponentProviderTest.java @@ -0,0 +1,33 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.contrib.awsxray; + +import static org.assertj.core.api.Assertions.assertThat; + +import io.opentelemetry.sdk.OpenTelemetrySdk; +import io.opentelemetry.sdk.extension.incubator.fileconfig.DeclarativeConfiguration; +import java.io.ByteArrayInputStream; +import java.nio.charset.StandardCharsets; +import org.junit.jupiter.api.Test; + +class AwsXrayRemoteSamplerComponentProviderTest { + @Test + void endToEnd() { + String yaml = + "file_format: 1.0-rc.1\n" + + "tracer_provider:\n" + + " sampler:\n" + + " xray:\n" + + " endpoint: 'https://example.com'\n"; + + OpenTelemetrySdk openTelemetrySdk = + DeclarativeConfiguration.parseAndCreate( + new ByteArrayInputStream(yaml.getBytes(StandardCharsets.UTF_8))); + + assertThat(openTelemetrySdk.getSdkTracerProvider().toString()) + .contains("AwsXrayRemoteSampler{endpoint=https://example.com}"); + } +} From b912491305b9376b8922dcea357400ebc26719aa Mon Sep 17 00:00:00 2001 From: Gregor Zeitlinger Date: Tue, 23 Sep 2025 16:04:26 +0200 Subject: [PATCH 2/5] add declarative config support for AWS X-Ray --- docs/apidiffs/current_vs_latest/opentelemetry-aws-xray.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-aws-xray.txt b/docs/apidiffs/current_vs_latest/opentelemetry-aws-xray.txt index 0bfd87e3d..63e34f632 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-aws-xray.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-aws-xray.txt @@ -1,2 +1,2 @@ Comparing source compatibility of opentelemetry-aws-xray-1.52.0-SNAPSHOT.jar against opentelemetry-aws-xray-1.51.0.jar -No changes. \ No newline at end of file +No changes. From 0b5b6210d1c5f5eb6083d7afa2ebe1e8d036c609 Mon Sep 17 00:00:00 2001 From: Gregor Zeitlinger Date: Wed, 8 Oct 2025 15:55:27 +0200 Subject: [PATCH 3/5] move to internal --- .../{ => internal}/AwsXrayRemoteSamplerComponentProvider.java | 4 +++- .../AwsXrayRemoteSamplerComponentProviderTest.java | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) rename aws-xray/src/main/java/io/opentelemetry/contrib/awsxray/{ => internal}/AwsXrayRemoteSamplerComponentProvider.java (87%) rename aws-xray/src/test/java/io/opentelemetry/contrib/awsxray/{ => internal}/AwsXrayRemoteSamplerComponentProviderTest.java (95%) diff --git a/aws-xray/src/main/java/io/opentelemetry/contrib/awsxray/AwsXrayRemoteSamplerComponentProvider.java b/aws-xray/src/main/java/io/opentelemetry/contrib/awsxray/internal/AwsXrayRemoteSamplerComponentProvider.java similarity index 87% rename from aws-xray/src/main/java/io/opentelemetry/contrib/awsxray/AwsXrayRemoteSamplerComponentProvider.java rename to aws-xray/src/main/java/io/opentelemetry/contrib/awsxray/internal/AwsXrayRemoteSamplerComponentProvider.java index f1d320cf3..cfebb6454 100644 --- a/aws-xray/src/main/java/io/opentelemetry/contrib/awsxray/AwsXrayRemoteSamplerComponentProvider.java +++ b/aws-xray/src/main/java/io/opentelemetry/contrib/awsxray/internal/AwsXrayRemoteSamplerComponentProvider.java @@ -3,10 +3,12 @@ * SPDX-License-Identifier: Apache-2.0 */ -package io.opentelemetry.contrib.awsxray; +package io.opentelemetry.contrib.awsxray.internal; import com.google.auto.service.AutoService; import io.opentelemetry.api.incubator.config.DeclarativeConfigProperties; +import io.opentelemetry.contrib.awsxray.AwsXrayRemoteSampler; +import io.opentelemetry.contrib.awsxray.AwsXrayRemoteSamplerBuilder; import io.opentelemetry.sdk.autoconfigure.spi.internal.ComponentProvider; import io.opentelemetry.sdk.resources.Resource; import io.opentelemetry.sdk.trace.samplers.Sampler; diff --git a/aws-xray/src/test/java/io/opentelemetry/contrib/awsxray/AwsXrayRemoteSamplerComponentProviderTest.java b/aws-xray/src/test/java/io/opentelemetry/contrib/awsxray/internal/AwsXrayRemoteSamplerComponentProviderTest.java similarity index 95% rename from aws-xray/src/test/java/io/opentelemetry/contrib/awsxray/AwsXrayRemoteSamplerComponentProviderTest.java rename to aws-xray/src/test/java/io/opentelemetry/contrib/awsxray/internal/AwsXrayRemoteSamplerComponentProviderTest.java index bc68ab4ee..02bf22b0b 100644 --- a/aws-xray/src/test/java/io/opentelemetry/contrib/awsxray/AwsXrayRemoteSamplerComponentProviderTest.java +++ b/aws-xray/src/test/java/io/opentelemetry/contrib/awsxray/internal/AwsXrayRemoteSamplerComponentProviderTest.java @@ -3,7 +3,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -package io.opentelemetry.contrib.awsxray; +package io.opentelemetry.contrib.awsxray.internal; import static org.assertj.core.api.Assertions.assertThat; From 661794dcdd13ea681ef9fc8d5975e8fe04014575 Mon Sep 17 00:00:00 2001 From: Gregor Zeitlinger Date: Tue, 11 Nov 2025 17:55:55 +0100 Subject: [PATCH 4/5] fix --- docs/apidiffs/current_vs_latest/opentelemetry-aws-xray.txt | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-aws-xray.txt b/docs/apidiffs/current_vs_latest/opentelemetry-aws-xray.txt index 63e34f632..8202c4532 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-aws-xray.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-aws-xray.txt @@ -1,2 +1,4 @@ Comparing source compatibility of opentelemetry-aws-xray-1.52.0-SNAPSHOT.jar against opentelemetry-aws-xray-1.51.0.jar -No changes. +*** MODIFIED CLASS: PUBLIC FINAL io.opentelemetry.contrib.awsxray.AwsXrayRemoteSampler (not serializable) + === CLASS FILE FORMAT VERSION: 52.0 <- 52.0 + +++ NEW METHOD: PUBLIC(+) java.lang.String toString() From a6946bcf5b2f58d42f7415d60c20f3db68b2c221 Mon Sep 17 00:00:00 2001 From: Gregor Zeitlinger Date: Tue, 11 Nov 2025 18:20:14 +0100 Subject: [PATCH 5/5] use hypothetical resource getter on ExtendedOpenTelemetrySdk --- .../contrib/awsxray/AwsXrayRemoteSampler.java | 9 ++++---- .../awsxray/AwsXrayRemoteSamplerBuilder.java | 5 +++-- .../contrib/awsxray/XrayRulesSampler.java | 13 ++++++----- ...AwsXrayRemoteSamplerComponentProvider.java | 22 ++++++++++++++++--- 4 files changed, 34 insertions(+), 15 deletions(-) diff --git a/aws-xray/src/main/java/io/opentelemetry/contrib/awsxray/AwsXrayRemoteSampler.java b/aws-xray/src/main/java/io/opentelemetry/contrib/awsxray/AwsXrayRemoteSampler.java index 06d35e3a5..3eae9cba4 100644 --- a/aws-xray/src/main/java/io/opentelemetry/contrib/awsxray/AwsXrayRemoteSampler.java +++ b/aws-xray/src/main/java/io/opentelemetry/contrib/awsxray/AwsXrayRemoteSampler.java @@ -43,6 +43,7 @@ import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.ScheduledFuture; import java.util.concurrent.ThreadLocalRandom; +import java.util.function.Supplier; import java.util.logging.Logger; import javax.annotation.Nullable; @@ -56,7 +57,7 @@ public final class AwsXrayRemoteSampler implements Sampler, Closeable { // Default batch size to be same as OTel BSP default private static final int maxExportBatchSize = 512; - private final Resource resource; + private final Supplier resource; private final Clock clock; private final String endpoint; private final Sampler initialSampler; @@ -81,12 +82,12 @@ public final class AwsXrayRemoteSampler implements Sampler, Closeable { */ // TODO(anuraaga): Deprecate after // https://github.com/open-telemetry/opentelemetry-specification/issues/1588 - public static AwsXrayRemoteSamplerBuilder newBuilder(Resource resource) { + public static AwsXrayRemoteSamplerBuilder newBuilder(Supplier resource) { return new AwsXrayRemoteSamplerBuilder(resource); } AwsXrayRemoteSampler( - Resource resource, + Supplier resource, Clock clock, String endpoint, Sampler initialSampler, @@ -296,7 +297,7 @@ XraySamplerClient getClient() { // Visible for testing Resource getResource() { - return resource; + return resource.get(); } @Override diff --git a/aws-xray/src/main/java/io/opentelemetry/contrib/awsxray/AwsXrayRemoteSamplerBuilder.java b/aws-xray/src/main/java/io/opentelemetry/contrib/awsxray/AwsXrayRemoteSamplerBuilder.java index 25485e4b0..c948c1efb 100644 --- a/aws-xray/src/main/java/io/opentelemetry/contrib/awsxray/AwsXrayRemoteSamplerBuilder.java +++ b/aws-xray/src/main/java/io/opentelemetry/contrib/awsxray/AwsXrayRemoteSamplerBuilder.java @@ -15,6 +15,7 @@ import io.opentelemetry.sdk.trace.samplers.Sampler; import java.time.Duration; import java.util.concurrent.TimeUnit; +import java.util.function.Supplier; import javax.annotation.Nullable; /** A builder for {@link AwsXrayRemoteSampler}. */ @@ -23,14 +24,14 @@ public final class AwsXrayRemoteSamplerBuilder { private static final String DEFAULT_ENDPOINT = "http://localhost:2000"; private static final long DEFAULT_POLLING_INTERVAL_SECS = 300; - private final Resource resource; + private final Supplier resource; private Clock clock = Clock.getDefault(); private String endpoint = DEFAULT_ENDPOINT; @Nullable private Sampler initialSampler; private long pollingIntervalNanos = SECONDS.toNanos(DEFAULT_POLLING_INTERVAL_SECS); - AwsXrayRemoteSamplerBuilder(Resource resource) { + AwsXrayRemoteSamplerBuilder(Supplier resource) { this.resource = resource; } diff --git a/aws-xray/src/main/java/io/opentelemetry/contrib/awsxray/XrayRulesSampler.java b/aws-xray/src/main/java/io/opentelemetry/contrib/awsxray/XrayRulesSampler.java index f2ab7c2db..70266e68d 100644 --- a/aws-xray/src/main/java/io/opentelemetry/contrib/awsxray/XrayRulesSampler.java +++ b/aws-xray/src/main/java/io/opentelemetry/contrib/awsxray/XrayRulesSampler.java @@ -41,6 +41,7 @@ import java.util.Objects; import java.util.Set; import java.util.function.Consumer; +import java.util.function.Supplier; import java.util.logging.Logger; import javax.annotation.Nullable; @@ -60,7 +61,7 @@ final class XrayRulesSampler implements Sampler { private static final AttributeKey HTTP_METHOD = AttributeKey.stringKey("http.method"); private final String clientId; - private final Resource resource; + private final Supplier resource; private final Clock clock; private final Sampler fallbackSampler; private final SamplingRuleApplier[] ruleAppliers; @@ -75,7 +76,7 @@ final class XrayRulesSampler implements Sampler { XrayRulesSampler( String clientId, - Resource resource, + Supplier resource, Clock clock, Sampler fallbackSampler, List rules, @@ -91,7 +92,7 @@ final class XrayRulesSampler implements Sampler { .map( rule -> new SamplingRuleApplier( - clientId, rule, resource.getAttribute(SERVICE_NAME), clock)) + clientId, rule, resource.get().getAttribute(SERVICE_NAME), clock)) .toArray(SamplingRuleApplier[]::new), createRuleHashMaps(rules), rules.stream().anyMatch(r -> r.getSamplingRateBoost() != null), @@ -105,7 +106,7 @@ final class XrayRulesSampler implements Sampler { private XrayRulesSampler( String clientId, - Resource resource, + Supplier resource, Clock clock, Sampler fallbackSampler, SamplingRuleApplier[] ruleAppliers, @@ -161,7 +162,7 @@ public SamplingResult shouldSample( : null; } for (SamplingRuleApplier applier : ruleAppliers) { - if (applier.matches(attributes, resource)) { + if (applier.matches(attributes, resource.get())) { SamplingResult result = applier.shouldSample(parentContext, traceId, name, spanKind, attributes, parentLinks); @@ -263,7 +264,7 @@ void adaptSampling(ReadableSpan span, SpanData spanData, Consumer ruleToReportTo = applier; break; } - if (applier.matches(spanData.getAttributes(), resource)) { + if (applier.matches(spanData.getAttributes(), resource.get())) { matchedRule = applier; } } diff --git a/aws-xray/src/main/java/io/opentelemetry/contrib/awsxray/internal/AwsXrayRemoteSamplerComponentProvider.java b/aws-xray/src/main/java/io/opentelemetry/contrib/awsxray/internal/AwsXrayRemoteSamplerComponentProvider.java index cfebb6454..3ca2a7b0f 100644 --- a/aws-xray/src/main/java/io/opentelemetry/contrib/awsxray/internal/AwsXrayRemoteSamplerComponentProvider.java +++ b/aws-xray/src/main/java/io/opentelemetry/contrib/awsxray/internal/AwsXrayRemoteSamplerComponentProvider.java @@ -9,9 +9,13 @@ import io.opentelemetry.api.incubator.config.DeclarativeConfigProperties; import io.opentelemetry.contrib.awsxray.AwsXrayRemoteSampler; import io.opentelemetry.contrib.awsxray.AwsXrayRemoteSamplerBuilder; +import io.opentelemetry.sdk.OpenTelemetrySdk; +import io.opentelemetry.sdk.autoconfigure.spi.internal.AutoConfigureListener; import io.opentelemetry.sdk.autoconfigure.spi.internal.ComponentProvider; +import io.opentelemetry.sdk.extension.incubator.ExtendedOpenTelemetrySdk; import io.opentelemetry.sdk.resources.Resource; import io.opentelemetry.sdk.trace.samplers.Sampler; +import java.util.function.Supplier; /** * File configuration SPI implementation for {@link AwsXrayRemoteSampler}. @@ -21,7 +25,13 @@ */ @SuppressWarnings("rawtypes") @AutoService(ComponentProvider.class) -public class AwsXrayRemoteSamplerComponentProvider implements ComponentProvider { +public class AwsXrayRemoteSamplerComponentProvider + implements ComponentProvider, AutoConfigureListener { + + private Resource resource; + + private final Supplier resourceSupplier = () -> resource; + @Override public Class getType() { return Sampler.class; @@ -34,8 +44,7 @@ public String getName() { @Override public Sampler create(DeclarativeConfigProperties config) { - Resource resource = io.opentelemetry.contrib.awsxray.ResourceHolder.getResource(); - AwsXrayRemoteSamplerBuilder builder = AwsXrayRemoteSampler.newBuilder(resource); + AwsXrayRemoteSamplerBuilder builder = AwsXrayRemoteSampler.newBuilder(resourceSupplier); String endpoint = config.getString("endpoint"); if (endpoint != null) { @@ -44,4 +53,11 @@ public Sampler create(DeclarativeConfigProperties config) { return builder.build(); } + + @Override + public void afterAutoConfigure(OpenTelemetrySdk sdk) { + if (sdk instanceof ExtendedOpenTelemetrySdk) { + this.resource = ((ExtendedOpenTelemetrySdk) sdk).getResource(); + } + } }