diff --git a/instrumentation/log4j/log4j-mdc-1.2/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/log4j/mdc/v1_2/LoggingEventInstrumentation.java b/instrumentation/log4j/log4j-mdc-1.2/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/log4j/mdc/v1_2/LoggingEventInstrumentation.java index e8b0c425ed6f..bf5f4834c189 100644 --- a/instrumentation/log4j/log4j-mdc-1.2/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/log4j/mdc/v1_2/LoggingEventInstrumentation.java +++ b/instrumentation/log4j/log4j-mdc-1.2/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/log4j/mdc/v1_2/LoggingEventInstrumentation.java @@ -17,6 +17,7 @@ import io.opentelemetry.api.trace.SpanContext; import io.opentelemetry.context.Context; import io.opentelemetry.instrumentation.api.util.VirtualField; +import io.opentelemetry.javaagent.bootstrap.ConfiguredResourceAttributesHolder; import io.opentelemetry.javaagent.bootstrap.Java8BytecodeBridge; import io.opentelemetry.javaagent.extension.instrumentation.TypeInstrumentation; import io.opentelemetry.javaagent.extension.instrumentation.TypeTransformer; @@ -79,6 +80,10 @@ public static void onExit( default: // do nothing } + } else if (ConfiguredResourceAttributesHolder.getAttributeValue(key) != null) { + if (value == null) { + value = ConfiguredResourceAttributesHolder.getAttributeValue(key); + } } } } diff --git a/instrumentation/logback/logback-mdc-1.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/logback/mdc/v1_0/LoggingEventInstrumentation.java b/instrumentation/logback/logback-mdc-1.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/logback/mdc/v1_0/LoggingEventInstrumentation.java index c45a77984310..e1e24858a96b 100644 --- a/instrumentation/logback/logback-mdc-1.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/logback/mdc/v1_0/LoggingEventInstrumentation.java +++ b/instrumentation/logback/logback-mdc-1.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/logback/mdc/v1_0/LoggingEventInstrumentation.java @@ -23,6 +23,7 @@ import io.opentelemetry.context.Context; import io.opentelemetry.instrumentation.api.util.VirtualField; import io.opentelemetry.instrumentation.logback.mdc.v1_0.internal.UnionMap; +import io.opentelemetry.javaagent.bootstrap.ConfiguredResourceAttributesHolder; import io.opentelemetry.javaagent.bootstrap.Java8BytecodeBridge; import io.opentelemetry.javaagent.extension.instrumentation.TypeInstrumentation; import io.opentelemetry.javaagent.extension.instrumentation.TypeTransformer; @@ -79,6 +80,8 @@ public static void onExit( spanContextData.put(TRACE_ID, spanContext.getTraceId()); spanContextData.put(SPAN_ID, spanContext.getSpanId()); spanContextData.put(TRACE_FLAGS, spanContext.getTraceFlags().asHex()); + + spanContextData.putAll(ConfiguredResourceAttributesHolder.getResourceAttribute()); } if (LogbackSingletons.addBaggage()) { diff --git a/javaagent-bootstrap/src/main/java/io/opentelemetry/javaagent/bootstrap/ConfiguredResourceAttributesHolder.java b/javaagent-bootstrap/src/main/java/io/opentelemetry/javaagent/bootstrap/ConfiguredResourceAttributesHolder.java new file mode 100644 index 000000000000..a8ae4948c494 --- /dev/null +++ b/javaagent-bootstrap/src/main/java/io/opentelemetry/javaagent/bootstrap/ConfiguredResourceAttributesHolder.java @@ -0,0 +1,51 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.javaagent.bootstrap; + +import static io.opentelemetry.api.common.AttributeKey.stringKey; + +import io.opentelemetry.api.common.Attributes; +import io.opentelemetry.instrumentation.api.internal.ConfigPropertiesUtil; +import java.util.HashMap; +import java.util.Map; +import javax.annotation.Nullable; + +public final class ConfiguredResourceAttributesHolder { + + private static final Map resourceAttribute = new HashMap<>(); + + public static Map getResourceAttribute() { + return resourceAttribute; + } + + public static void initialize(Attributes resourceAttribute) { + String[] mdcResourceAttributes = getConfiguredAttributes(); + + for (String key : mdcResourceAttributes) { + String value = resourceAttribute.get(stringKey(key)); + if (value != null) { + ConfiguredResourceAttributesHolder.resourceAttribute.put( + String.format("otel.resource.%s", key), value); + } + } + } + + private static String[] getConfiguredAttributes() { + String resourceAttributes = + ConfigPropertiesUtil.getString("otel.instrumentation.mdc.resource-attributes"); + if (resourceAttributes == null) { + return new String[] {}; + } + return resourceAttributes.split(","); + } + + @Nullable + public static String getAttributeValue(String key) { + return resourceAttribute.get(String.format("otel.resource.%s", key)); + } + + private ConfiguredResourceAttributesHolder() {} +} diff --git a/javaagent-bootstrap/src/test/java/io/opentelemetry/javaagent/bootstrap/ConfiguredResourceAttributesHolderTest.java b/javaagent-bootstrap/src/test/java/io/opentelemetry/javaagent/bootstrap/ConfiguredResourceAttributesHolderTest.java new file mode 100644 index 000000000000..004f75e5b04e --- /dev/null +++ b/javaagent-bootstrap/src/test/java/io/opentelemetry/javaagent/bootstrap/ConfiguredResourceAttributesHolderTest.java @@ -0,0 +1,59 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.javaagent.bootstrap; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNull; + +import io.opentelemetry.api.common.AttributeKey; +import io.opentelemetry.api.common.Attributes; +import java.util.Collections; +import org.junit.jupiter.api.Test; +import org.junitpioneer.jupiter.ClearSystemProperty; +import org.junitpioneer.jupiter.SetSystemProperty; + +class ConfiguredResourceAttributesHolderTest { + + @Test + @SetSystemProperty( + key = "otel.instrumentation.mdc.resource-attributes", + value = "service.name,runtime") + void testGetAttributeValue() { + Attributes attributes = Attributes.builder().put("service.name", "test-service").build(); + + ConfiguredResourceAttributesHolder.initialize(attributes); + assertEquals( + "test-service", ConfiguredResourceAttributesHolder.getAttributeValue("service.name")); + } + + + @Test + @SetSystemProperty( + key = "otel.instrumentation.mdc.resource-attributes", + value = "items") + void testGetAttributeValueWhenKeyIsNotString() { + Attributes attributes = + Attributes.builder() + .put(AttributeKey.stringArrayKey("items"), Collections.singletonList("test-item")) + .build(); + + ConfiguredResourceAttributesHolder.initialize(attributes); + assertNull(ConfiguredResourceAttributesHolder.getAttributeValue("items")); + } + + + @Test + @ClearSystemProperty(key = "otel.instrumentation.mdc.resource-attributes") + void testGetAttributeValueWhenConfigIsNotSet() { + Attributes attributes = + Attributes.builder() + .put(AttributeKey.stringArrayKey("don't care"), "won't care") + .build(); + + ConfiguredResourceAttributesHolder.initialize(attributes); + assertNull(ConfiguredResourceAttributesHolder.getAttributeValue("dc-wc")); + } +} diff --git a/javaagent-tooling/src/main/java/io/opentelemetry/javaagent/tooling/AgentInstaller.java b/javaagent-tooling/src/main/java/io/opentelemetry/javaagent/tooling/AgentInstaller.java index eafe2dd14b52..b70900199a66 100644 --- a/javaagent-tooling/src/main/java/io/opentelemetry/javaagent/tooling/AgentInstaller.java +++ b/javaagent-tooling/src/main/java/io/opentelemetry/javaagent/tooling/AgentInstaller.java @@ -21,6 +21,7 @@ import io.opentelemetry.javaagent.bootstrap.AgentClassLoader; import io.opentelemetry.javaagent.bootstrap.BootstrapPackagePrefixesHolder; import io.opentelemetry.javaagent.bootstrap.ClassFileTransformerHolder; +import io.opentelemetry.javaagent.bootstrap.ConfiguredResourceAttributesHolder; import io.opentelemetry.javaagent.bootstrap.DefineClassHelper; import io.opentelemetry.javaagent.bootstrap.InstrumentedTaskClasses; import io.opentelemetry.javaagent.bootstrap.http.HttpServerResponseCustomizer; @@ -41,6 +42,7 @@ import io.opentelemetry.javaagent.tooling.muzzle.AgentTooling; import io.opentelemetry.javaagent.tooling.util.Trie; import io.opentelemetry.sdk.autoconfigure.AutoConfiguredOpenTelemetrySdk; +import io.opentelemetry.sdk.autoconfigure.SdkAutoconfigureAccess; import io.opentelemetry.sdk.autoconfigure.internal.AutoConfigureUtil; import io.opentelemetry.sdk.autoconfigure.spi.ConfigProperties; import java.lang.instrument.Instrumentation; @@ -125,6 +127,8 @@ private static void installBytebuddyAgent( copyNecessaryConfigToSystemProperties(sdkConfig); setBootstrapPackages(sdkConfig, extensionClassLoader); + ConfiguredResourceAttributesHolder.initialize( + SdkAutoconfigureAccess.getResourceAttributes(autoConfiguredSdk)); for (BeforeAgentListener agentListener : loadOrdered(BeforeAgentListener.class, extensionClassLoader)) { diff --git a/javaagent-tooling/src/main/java/io/opentelemetry/sdk/autoconfigure/SdkAutoconfigureAccess.java b/javaagent-tooling/src/main/java/io/opentelemetry/sdk/autoconfigure/SdkAutoconfigureAccess.java new file mode 100644 index 000000000000..477f5bcbdee4 --- /dev/null +++ b/javaagent-tooling/src/main/java/io/opentelemetry/sdk/autoconfigure/SdkAutoconfigureAccess.java @@ -0,0 +1,16 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.sdk.autoconfigure; + +import io.opentelemetry.api.common.Attributes; + +public final class SdkAutoconfigureAccess { + public static Attributes getResourceAttributes(AutoConfiguredOpenTelemetrySdk sdk) { + return sdk.getResource().getAttributes(); + } + + private SdkAutoconfigureAccess() {} +}