From 045c3e65d68d426a7ec87a80702d58edea5512a2 Mon Sep 17 00:00:00 2001 From: jack-berg <34418638+jack-berg@users.noreply.github.com> Date: Fri, 31 Jan 2025 09:19:22 -0600 Subject: [PATCH] Promote EnvironmentResourceProvider to public API (#7052) --- ...ntelemetry-sdk-extension-autoconfigure.txt | 7 +- sdk-extensions/autoconfigure/build.gradle.kts | 3 +- .../EnvironmentResourceProvider.java | 6 +- .../autoconfigure/ResourceConfiguration.java | 43 ++++- ...try.sdk.autoconfigure.spi.ResourceProvider | 2 +- .../ResourceConfigurationTest.java | 165 ++++++++++++------ 6 files changed, 165 insertions(+), 61 deletions(-) rename sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/{internal => }/EnvironmentResourceProvider.java (77%) diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-sdk-extension-autoconfigure.txt b/docs/apidiffs/current_vs_latest/opentelemetry-sdk-extension-autoconfigure.txt index 4303d8e57e..2eb9113554 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-sdk-extension-autoconfigure.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-sdk-extension-autoconfigure.txt @@ -1,2 +1,7 @@ Comparing source compatibility of opentelemetry-sdk-extension-autoconfigure-1.47.0-SNAPSHOT.jar against opentelemetry-sdk-extension-autoconfigure-1.46.0.jar -No changes. \ No newline at end of file ++++ NEW CLASS: PUBLIC(+) FINAL(+) io.opentelemetry.sdk.autoconfigure.EnvironmentResourceProvider (not serializable) + +++ CLASS FILE FORMAT VERSION: 52.0 <- n.a. + +++ NEW SUPERCLASS: java.lang.Object + +++ NEW CONSTRUCTOR: PUBLIC(+) EnvironmentResourceProvider() + +++ NEW METHOD: PUBLIC(+) io.opentelemetry.sdk.resources.Resource createResource(io.opentelemetry.sdk.autoconfigure.spi.ConfigProperties) + +++ NEW METHOD: PUBLIC(+) int order() diff --git a/sdk-extensions/autoconfigure/build.gradle.kts b/sdk-extensions/autoconfigure/build.gradle.kts index e354525088..eac32f51cd 100644 --- a/sdk-extensions/autoconfigure/build.gradle.kts +++ b/sdk-extensions/autoconfigure/build.gradle.kts @@ -67,7 +67,8 @@ testing { targets { all { testTask { - environment("OTEL_RESOURCE_ATTRIBUTES", "service.name=test,cat=meow") + environment("OTEL_SERVICE_NAME", "test") + environment("OTEL_RESOURCE_ATTRIBUTES", "cat=meow") environment("OTEL_PROPAGATORS", "tracecontext,baggage,b3,b3multi,jaeger,ottrace,test") environment("OTEL_EXPORTER_OTLP_HEADERS", "cat=meow,dog=bark") environment("OTEL_EXPORTER_OTLP_TIMEOUT", "5000") diff --git a/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/internal/EnvironmentResourceProvider.java b/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/EnvironmentResourceProvider.java similarity index 77% rename from sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/internal/EnvironmentResourceProvider.java rename to sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/EnvironmentResourceProvider.java index ba61f95739..1af9b78e1c 100644 --- a/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/internal/EnvironmentResourceProvider.java +++ b/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/EnvironmentResourceProvider.java @@ -3,9 +3,8 @@ * SPDX-License-Identifier: Apache-2.0 */ -package io.opentelemetry.sdk.autoconfigure.internal; +package io.opentelemetry.sdk.autoconfigure; -import io.opentelemetry.sdk.autoconfigure.ResourceConfiguration; import io.opentelemetry.sdk.autoconfigure.spi.ConfigProperties; import io.opentelemetry.sdk.autoconfigure.spi.ResourceProvider; import io.opentelemetry.sdk.resources.Resource; @@ -13,9 +12,6 @@ import io.opentelemetry.sdk.resources.Resource; /** * {@link ResourceProvider} for automatically configuring {@link * ResourceConfiguration#createEnvironmentResource(ConfigProperties)}. - * - *

This class is internal and is hence not for public use. Its APIs are unstable and can change - * at any time. */ public final class EnvironmentResourceProvider implements ResourceProvider { @Override diff --git a/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/ResourceConfiguration.java b/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/ResourceConfiguration.java index 5e94f966a3..8e00ee19ab 100644 --- a/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/ResourceConfiguration.java +++ b/sdk-extensions/autoconfigure/src/main/java/io/opentelemetry/sdk/autoconfigure/ResourceConfiguration.java @@ -25,6 +25,8 @@ import java.util.List; import java.util.Map; import java.util.Set; import java.util.function.BiFunction; +import java.util.logging.Level; +import java.util.logging.Logger; /** * Auto-configuration for the OpenTelemetry {@link Resource}. @@ -33,12 +35,21 @@ import java.util.function.BiFunction; */ public final class ResourceConfiguration { + private static final Logger logger = Logger.getLogger(ResourceConfiguration.class.getName()); + private static final AttributeKey SERVICE_NAME = AttributeKey.stringKey("service.name"); // Visible for testing static final String ATTRIBUTE_PROPERTY = "otel.resource.attributes"; static final String SERVICE_NAME_PROPERTY = "otel.service.name"; static final String DISABLED_ATTRIBUTE_KEYS = "otel.resource.disabled.keys"; + static final String ENABLED_RESOURCE_PROVIDERS = "otel.java.enabled.resource.providers"; + static final String DISABLED_RESOURCE_PROVIDERS = "otel.java.disabled.resource.providers"; + + private static final String OLD_ENVIRONMENT_DETECTOR_FQCN = + "io.opentelemetry.sdk.autoconfigure.internal.EnvironmentResourceProvider"; + private static final String NEW_ENVIRONMENT_DETECT_FQCN = + EnvironmentResourceProvider.class.getName(); /** * Create a {@link Resource} from the environment. The resource contains attributes parsed from @@ -88,10 +99,34 @@ public final class ResourceConfiguration { BiFunction resourceCustomizer) { Resource result = Resource.getDefault(); - Set enabledProviders = - new HashSet<>(config.getList("otel.java.enabled.resource.providers")); - Set disabledProviders = - new HashSet<>(config.getList("otel.java.disabled.resource.providers")); + Set enabledProviders = new HashSet<>(config.getList(ENABLED_RESOURCE_PROVIDERS)); + if (enabledProviders.remove(OLD_ENVIRONMENT_DETECTOR_FQCN)) { + logger.log( + Level.WARNING, + "Found reference to " + + OLD_ENVIRONMENT_DETECTOR_FQCN + + " in " + + ENABLED_RESOURCE_PROVIDERS + + ". Please update to " + + NEW_ENVIRONMENT_DETECT_FQCN + + ". Support for the old provider name will be removed after 1.49.0."); + enabledProviders.add(NEW_ENVIRONMENT_DETECT_FQCN); + } + + Set disabledProviders = new HashSet<>(config.getList(DISABLED_RESOURCE_PROVIDERS)); + if (disabledProviders.remove(OLD_ENVIRONMENT_DETECTOR_FQCN)) { + logger.log( + Level.WARNING, + "Found reference to " + + OLD_ENVIRONMENT_DETECTOR_FQCN + + " in " + + DISABLED_RESOURCE_PROVIDERS + + ". Please update to " + + NEW_ENVIRONMENT_DETECT_FQCN + + ". Support for the old provider name will be removed after 1.49.0."); + disabledProviders.add(NEW_ENVIRONMENT_DETECT_FQCN); + } + for (ResourceProvider resourceProvider : spiHelper.loadOrdered(ResourceProvider.class)) { if (!enabledProviders.isEmpty() && !enabledProviders.contains(resourceProvider.getClass().getName())) { diff --git a/sdk-extensions/autoconfigure/src/main/resources/META-INF/services/io.opentelemetry.sdk.autoconfigure.spi.ResourceProvider b/sdk-extensions/autoconfigure/src/main/resources/META-INF/services/io.opentelemetry.sdk.autoconfigure.spi.ResourceProvider index af0f9919ad..f9bd3554d7 100644 --- a/sdk-extensions/autoconfigure/src/main/resources/META-INF/services/io.opentelemetry.sdk.autoconfigure.spi.ResourceProvider +++ b/sdk-extensions/autoconfigure/src/main/resources/META-INF/services/io.opentelemetry.sdk.autoconfigure.spi.ResourceProvider @@ -1 +1 @@ -io.opentelemetry.sdk.autoconfigure.internal.EnvironmentResourceProvider +io.opentelemetry.sdk.autoconfigure.EnvironmentResourceProvider diff --git a/sdk-extensions/autoconfigure/src/testFullConfig/java/io/opentelemetry/sdk/autoconfigure/ResourceConfigurationTest.java b/sdk-extensions/autoconfigure/src/testFullConfig/java/io/opentelemetry/sdk/autoconfigure/ResourceConfigurationTest.java index 722d80b870..785fd23cba 100644 --- a/sdk-extensions/autoconfigure/src/testFullConfig/java/io/opentelemetry/sdk/autoconfigure/ResourceConfigurationTest.java +++ b/sdk-extensions/autoconfigure/src/testFullConfig/java/io/opentelemetry/sdk/autoconfigure/ResourceConfigurationTest.java @@ -11,29 +11,25 @@ import io.opentelemetry.api.common.AttributeKey; import io.opentelemetry.api.common.Attributes; import io.opentelemetry.sdk.autoconfigure.internal.SpiHelper; import io.opentelemetry.sdk.autoconfigure.spi.internal.DefaultConfigProperties; +import io.opentelemetry.sdk.testing.assertj.AttributesAssert; import java.net.URL; import java.net.URLClassLoader; import java.util.Collections; import java.util.HashMap; import java.util.Map; +import java.util.function.Consumer; +import java.util.stream.Stream; +import javax.annotation.Nullable; import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; class ResourceConfigurationTest { private final SpiHelper spiHelper = SpiHelper.create(ResourceConfigurationTest.class.getClassLoader()); - @Test - void configureResource() { - Attributes attributes = - ResourceConfiguration.configureResource( - DefaultConfigProperties.create(Collections.emptyMap()), spiHelper, (r, c) -> r) - .getAttributes(); - - assertThat(attributes.get(AttributeKey.stringKey("animal"))).isNotNull(); - assertThat(attributes.get(AttributeKey.stringKey("color"))).isNotNull(); - } - @Test void configureResource_EmptyClassLoader() { Attributes attributes = @@ -43,55 +39,126 @@ class ResourceConfigurationTest { (r, c) -> r) .getAttributes(); + assertThat(attributes.get(AttributeKey.stringKey("service.name"))) + .isEqualTo("unknown_service:java"); + assertThat(attributes.get(AttributeKey.stringKey("cat"))).isNull(); assertThat(attributes.get(AttributeKey.stringKey("animal"))).isNull(); assertThat(attributes.get(AttributeKey.stringKey("color"))).isNull(); } - @Test - void configureResource_OnlyEnabled() { - Map customConfigs = new HashMap<>(1); - customConfigs.put( - "otel.java.enabled.resource.providers", - "io.opentelemetry.sdk.autoconfigure.provider.TestAnimalResourceProvider"); + @ParameterizedTest + @MethodSource("configureResourceArgs") + void configureResource( + @Nullable String enabledProviders, + @Nullable String disabledProviders, + Consumer attributeAssertion) { + // build.gradle.kts sets: + // OTEL_SERVICE_NAME=test + // OTEL_RESOURCE_ATTRIBUTES=cat=meow + Map config = new HashMap<>(); + if (enabledProviders != null) { + config.put("otel.java.enabled.resource.providers", enabledProviders); + } + if (disabledProviders != null) { + config.put("otel.java.disabled.resource.providers", disabledProviders); + } Attributes attributes = ResourceConfiguration.configureResource( - DefaultConfigProperties.create(customConfigs), spiHelper, (r, c) -> r) + DefaultConfigProperties.create(config), spiHelper, (r, c) -> r) .getAttributes(); - assertThat(attributes.get(AttributeKey.stringKey("animal"))).isEqualTo("cat"); - assertThat(attributes.get(AttributeKey.stringKey("color"))).isNull(); + attributeAssertion.accept(assertThat(attributes)); } - @Test - void configureResource_EnabledAndDisabled() { - Map customConfigs = new HashMap<>(2); - customConfigs.put( - "otel.java.enabled.resource.providers", - "io.opentelemetry.sdk.autoconfigure.provider.TestAnimalResourceProvider"); - customConfigs.put( - "otel.java.disabled.resource.providers", - "io.opentelemetry.sdk.extension.resources.TestColorResourceProvider"); - Attributes attributes = - ResourceConfiguration.configureResource( - DefaultConfigProperties.create(customConfigs), spiHelper, (r, c) -> r) - .getAttributes(); - - assertThat(attributes.get(AttributeKey.stringKey("animal"))).isEqualTo("cat"); - assertThat(attributes.get(AttributeKey.stringKey("color"))).isNull(); + private static Stream configureResourceArgs() { + return Stream.of( + // default + Arguments.of( + null, + null, + attributeConsumer( + attr -> attr.containsEntry("service.name", "test").containsEntry("cat", "meow"))), + // only enabled + Arguments.of( + "io.opentelemetry.sdk.autoconfigure.provider.TestAnimalResourceProvider", + null, + attributeConsumer( + attr -> + attr.containsEntry("service.name", "unknown_service:java") + .doesNotContainKey("cat") + .containsEntry("animal", "cat") + .doesNotContainKey("color"))), + // only disabled + Arguments.of( + null, + "io.opentelemetry.sdk.autoconfigure.provider.TestColorResourceProvider", + attributeConsumer( + attr -> + attr.containsEntry("service.name", "test") + .containsEntry("cat", "meow") + .containsEntry("animal", "cat") + .doesNotContainKey("color"))), + // enabled and disabled + Arguments.of( + "io.opentelemetry.sdk.autoconfigure.provider.TestAnimalResourceProvider", + "io.opentelemetry.sdk.autoconfigure.provider.TestColorResourceProvider", + attributeConsumer( + attr -> + attr.containsEntry("service.name", "unknown_service:java") + .doesNotContainKey("cat") + .containsEntry("animal", "cat") + .doesNotContainKey("color"))), + Arguments.of( + "io.opentelemetry.sdk.autoconfigure.provider.TestAnimalResourceProvider", + "io.opentelemetry.sdk.autoconfigure.provider.TestColorResourceProvider,io.opentelemetry.sdk.autoconfigure.provider.TestAnimalResourceProvider", + attributeConsumer( + attr -> + attr.containsEntry("service.name", "unknown_service:java") + .doesNotContainKey("cat") + .doesNotContainKey("animal") + .doesNotContainKey("color"))), + // environment resource provider + Arguments.of( + "io.opentelemetry.sdk.autoconfigure.EnvironmentResourceProvider", + null, + attributeConsumer( + attr -> + attr.containsEntry("service.name", "test") + .containsEntry("cat", "meow") + .doesNotContainKey("animal") + .doesNotContainKey("color"))), + Arguments.of( + null, + "io.opentelemetry.sdk.autoconfigure.EnvironmentResourceProvider", + attributeConsumer( + attr -> + attr.containsEntry("service.name", "unknown_service:java") + .doesNotContainKey("cat") + .containsEntry("animal", "cat") + .containsEntry("color", "blue"))), + // old environment resource provider FQCN + Arguments.of( + "io.opentelemetry.sdk.autoconfigure.internal.EnvironmentResourceProvider", + null, + attributeConsumer( + attr -> + attr.containsEntry("service.name", "test") + .containsEntry("cat", "meow") + .doesNotContainKey("animal") + .doesNotContainKey("color"))), + Arguments.of( + null, + "io.opentelemetry.sdk.autoconfigure.internal.EnvironmentResourceProvider", + attributeConsumer( + attr -> + attr.containsEntry("service.name", "unknown_service:java") + .doesNotContainKey("cat") + .containsEntry("animal", "cat") + .containsEntry("color", "blue")))); } - @Test - void configureResource_OnlyDisabled() { - Map customConfigs = new HashMap<>(1); - customConfigs.put( - "otel.java.disabled.resource.providers", - "io.opentelemetry.sdk.autoconfigure.provider.TestColorResourceProvider"); - Attributes attributes = - ResourceConfiguration.configureResource( - DefaultConfigProperties.create(customConfigs), spiHelper, (r, c) -> r) - .getAttributes(); - - assertThat(attributes.get(AttributeKey.stringKey("animal"))).isEqualTo("cat"); - assertThat(attributes.get(AttributeKey.stringKey("color"))).isNull(); + private static Consumer attributeConsumer( + Consumer attributesAssertConsumer) { + return attributesAssertConsumer; } }