Skip to content

Commit

Permalink
Promote EnvironmentResourceProvider to public API (#7052)
Browse files Browse the repository at this point in the history
  • Loading branch information
jack-berg authored Jan 31, 2025
1 parent 19e964a commit 045c3e6
Show file tree
Hide file tree
Showing 6 changed files with 165 additions and 61 deletions.
Original file line number Diff line number Diff line change
@@ -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.
+++ 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()
3 changes: 2 additions & 1 deletion sdk-extensions/autoconfigure/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -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")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,19 +3,15 @@
* 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;

/**
* {@link ResourceProvider} for automatically configuring {@link
* ResourceConfiguration#createEnvironmentResource(ConfigProperties)}.
*
* <p>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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@
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}.
Expand All @@ -33,12 +35,21 @@
*/
public final class ResourceConfiguration {

private static final Logger logger = Logger.getLogger(ResourceConfiguration.class.getName());

private static final AttributeKey<String> 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
Expand Down Expand Up @@ -88,10 +99,34 @@ static Resource configureResource(
BiFunction<? super Resource, ConfigProperties, ? extends Resource> resourceCustomizer) {
Resource result = Resource.getDefault();

Set<String> enabledProviders =
new HashSet<>(config.getList("otel.java.enabled.resource.providers"));
Set<String> disabledProviders =
new HashSet<>(config.getList("otel.java.disabled.resource.providers"));
Set<String> 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<String> 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())) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1 +1 @@
io.opentelemetry.sdk.autoconfigure.internal.EnvironmentResourceProvider
io.opentelemetry.sdk.autoconfigure.EnvironmentResourceProvider
Original file line number Diff line number Diff line change
Expand Up @@ -11,29 +11,25 @@
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 =
Expand All @@ -43,55 +39,126 @@ void configureResource_EmptyClassLoader() {
(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<String, String> 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<AttributesAssert> attributeAssertion) {
// build.gradle.kts sets:
// OTEL_SERVICE_NAME=test
// OTEL_RESOURCE_ATTRIBUTES=cat=meow
Map<String, String> 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<String, String> 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<Arguments> 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<String, String> 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<AttributesAssert> attributeConsumer(
Consumer<AttributesAssert> attributesAssertConsumer) {
return attributesAssertConsumer;
}
}

0 comments on commit 045c3e6

Please sign in to comment.