Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow configuring MDC key names for trace_id, span_id, trace_flags #11329

Merged
merged 22 commits into from
Jun 10, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,11 @@ public static String getString(String propertyName) {
return System.getenv(toEnvVarName(propertyName));
}

public static String getString(String propertyName, String defaultValue) {
String strValue = getString(propertyName);
return strValue == null ? defaultValue : strValue;
}

public static List<String> getList(String propertyName, List<String> defaultValue) {
String value = getString(propertyName);
if (value == null) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,6 @@

package io.opentelemetry.javaagent.instrumentation.jbosslogmanager.mdc.v1_1;

import static io.opentelemetry.instrumentation.api.incubator.log.LoggingContextConstants.SPAN_ID;
import static io.opentelemetry.instrumentation.api.incubator.log.LoggingContextConstants.TRACE_FLAGS;
import static io.opentelemetry.instrumentation.api.incubator.log.LoggingContextConstants.TRACE_ID;
import static net.bytebuddy.matcher.ElementMatchers.isMethod;
import static net.bytebuddy.matcher.ElementMatchers.isPublic;
import static net.bytebuddy.matcher.ElementMatchers.named;
Expand All @@ -18,6 +15,7 @@
import io.opentelemetry.context.Context;
import io.opentelemetry.instrumentation.api.util.VirtualField;
import io.opentelemetry.javaagent.bootstrap.Java8BytecodeBridge;
import io.opentelemetry.javaagent.bootstrap.internal.CommonConfig;
import io.opentelemetry.javaagent.extension.instrumentation.TypeInstrumentation;
import io.opentelemetry.javaagent.extension.instrumentation.TypeTransformer;
import java.util.Map;
Expand Down Expand Up @@ -57,7 +55,9 @@ public static void onExit(
@Advice.This ExtLogRecord record,
@Advice.Argument(0) String key,
@Advice.Return(readOnly = false) String value) {
if (TRACE_ID.equals(key) || SPAN_ID.equals(key) || TRACE_FLAGS.equals(key)) {
if (CommonConfig.get().getTraceIdKey().equals(key)
|| CommonConfig.get().getSpanIdKey().equals(key)
|| CommonConfig.get().getTraceFlagsKey().equals(key)) {
if (value != null) {
// Assume already instrumented event if traceId/spanId/sampled is present.
return;
Expand All @@ -72,18 +72,14 @@ public static void onExit(
return;
}

switch (key) {
case TRACE_ID:
value = spanContext.getTraceId();
break;
case SPAN_ID:
value = spanContext.getSpanId();
break;
case TRACE_FLAGS:
value = spanContext.getTraceFlags().asHex();
break;
default:
// do nothing
if (CommonConfig.get().getTraceIdKey().equals(key)) {
value = spanContext.getTraceId();
}
if (CommonConfig.get().getSpanIdKey().equals(key)) {
value = spanContext.getSpanId();
}
if (CommonConfig.get().getTraceFlagsKey().equals(key)) {
value = spanContext.getTraceFlags().asHex();
}
}
}
Expand All @@ -97,9 +93,9 @@ public static void onExit(
@Advice.This ExtLogRecord record,
@Advice.Return(readOnly = false) Map<String, String> value) {

if (value.containsKey(TRACE_ID)
&& value.containsKey(SPAN_ID)
&& value.containsKey(TRACE_FLAGS)) {
if (value.containsKey(CommonConfig.get().getTraceIdKey())
&& value.containsKey(CommonConfig.get().getSpanIdKey())
&& value.containsKey(CommonConfig.get().getTraceFlagsKey())) {
return;
}

Expand All @@ -113,16 +109,16 @@ public static void onExit(
return;
}

if (!value.containsKey(TRACE_ID)) {
value.put(TRACE_ID, spanContext.getTraceId());
if (!value.containsKey(CommonConfig.get().getTraceIdKey())) {
value.put(CommonConfig.get().getTraceIdKey(), spanContext.getTraceId());
}

if (!value.containsKey(SPAN_ID)) {
value.put(SPAN_ID, spanContext.getSpanId());
if (!value.containsKey(CommonConfig.get().getSpanIdKey())) {
value.put(CommonConfig.get().getSpanIdKey(), spanContext.getSpanId());
}

if (!value.containsKey(TRACE_FLAGS)) {
value.put(TRACE_FLAGS, spanContext.getTraceFlags().asHex());
if (!value.containsKey(CommonConfig.get().getTraceFlagsKey())) {
value.put(CommonConfig.get().getTraceFlagsKey(), spanContext.getTraceFlags().asHex());
}
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
# Settings for the Log4j MDC instrumentation

| System property | Type | Default | Description |
|-------------------------------------------------------|---------|---------|--------------------------------------------------------------------|
| `otel.instrumentation.common.mdc.resource-attributes` | String | | Comma separated list of resource attributes to expose through MDC. |
| System property | Type | Default | Description |
|-------------------------------------------------------|---------|---------------|--------------------------------------------------------------------|
| `otel.instrumentation.log4j-context-data.add-baggage` | Boolean | `false` | Enable exposing baggage attributes through MDC. |
| `otel.instrumentation.common.mdc.resource-attributes` | String | | Comma separated list of resource attributes to expose through MDC. |
| `otel.instrumentation.common.logging.trace-id` | String | `trace_id` | Customize MDC key name for the trace id. |
| `otel.instrumentation.common.logging.span-id` | String | `span_id` | Customize MDC key name for the span id. |
| `otel.instrumentation.common.logging.trace-flags` | String | `trace_flags` | Customize MDC key name for the trace flags. |
Original file line number Diff line number Diff line change
Expand Up @@ -47,19 +47,32 @@ testing {
}

val testAddBaggage by registering(JvmTestSuite::class) {
sources {
java {
setSrcDirs(listOf("src/testAddBaggage/java"))
dependencies {
implementation(project(":instrumentation:log4j:log4j-context-data:log4j-context-data-common:testing"))
}

targets {
all {
testTask.configure {
jvmArgs("-Dotel.instrumentation.log4j-context-data.add-baggage=true")
jvmArgs("-Dlog4j2.is.webapp=false")
jvmArgs("-Dlog4j2.enable.threadlocals=true")
}
}
}
}

val testLoggingKeys by registering(JvmTestSuite::class) {
dependencies {
implementation(project(":instrumentation:log4j:log4j-context-data:log4j-context-data-common:testing"))
}

targets {
all {
testTask.configure {
jvmArgs("-Dotel.instrumentation.log4j-context-data.add-baggage=true")
jvmArgs("-Dotel.instrumentation.common.logging.trace-id=trace_id_test")
jvmArgs("-Dotel.instrumentation.common.logging.span-id=span_id_test")
jvmArgs("-Dotel.instrumentation.common.logging.trace-flags=trace_flags_test")
jvmArgs("-Dlog4j2.is.webapp=false")
jvmArgs("-Dlog4j2.enable.threadlocals=true")
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/

package io.opentelemetry.javaagent.instrumentation.log4j.contextdata.v2_17;

import io.opentelemetry.instrumentation.log4j.contextdata.Log4j2LoggingKeysTest;
import io.opentelemetry.instrumentation.testing.junit.AgentInstrumentationExtension;
import io.opentelemetry.instrumentation.testing.junit.InstrumentationExtension;
import org.junit.jupiter.api.extension.RegisterExtension;

class AutoLog4jLoggingKeysTest extends Log4j2LoggingKeysTest {
@RegisterExtension
static final InstrumentationExtension testing = AgentInstrumentationExtension.create();

@Override
public InstrumentationExtension getInstrumentationExtension() {
return testing;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -42,9 +42,17 @@ will be added to the context when a log statement is made when a span is active:
- `span_id`
- `trace_flags`

These keys can be customized using the following system properties or environment variables:

| System property | Environment variable |
|-------------------------------------------------------|---------------------------------------------------|
| `otel.instrumentation.common.logging.trace-id` | `OTEL_INSTRUMENTATION_COMMON_LOGGING_TRACE_ID` |
| `otel.instrumentation.common.logging.span-id` | `OTEL_INSTRUMENTATION_COMMON_LOGGING_SPAN_ID` |
| `otel.instrumentation.common.logging.trace-flags` | `OTEL_INSTRUMENTATION_COMMON_LOGGING_TRACE_FLAGS` |

If the `otel.instrumentation.log4j-context-data.add-baggage` system property (or the
`OTEL_INSTRUMENTATION_LOG4J_CONTEXT_DATA_ADD_BAGGAGE` environment variable) is set to `true`,
key/value pairs in [baggage](https://opentelemetry.io/docs/concepts/signals/baggage/) will be added to the context too.
key/value pairs in [baggage](https://opentelemetry.io/docs/concepts/signals/baggage/) will also be added to the context data.

- `baggage.<entry_name>`

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ tasks {
test {
filter {
excludeTestsMatching("LibraryLog4j2BaggageTest")
excludeTestsMatching("LibraryLog4j2LoggingKeysTest")
}
}

Expand All @@ -25,7 +26,17 @@ tasks {
jvmArgs("-Dotel.instrumentation.log4j-context-data.add-baggage=true")
}

val testLoggingKeys by registering(Test::class) {
filter {
includeTestsMatching("LibraryLog4j2LoggingKeysTest")
}
jvmArgs("-Dotel.instrumentation.common.logging.trace-id=trace_id_test")
jvmArgs("-Dotel.instrumentation.common.logging.span-id=span_id_test")
jvmArgs("-Dotel.instrumentation.common.logging.trace-flags=trace_flags_test")
}

named("check") {
dependsOn(testAddBaggage)
dependsOn(testLoggingKeys)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,12 @@

package io.opentelemetry.instrumentation.log4j.contextdata.v2_17;

import static io.opentelemetry.instrumentation.api.incubator.log.LoggingContextConstants.SPAN_ID;
import static io.opentelemetry.instrumentation.api.incubator.log.LoggingContextConstants.TRACE_FLAGS;
import static io.opentelemetry.instrumentation.api.incubator.log.LoggingContextConstants.TRACE_ID;

import io.opentelemetry.api.baggage.Baggage;
import io.opentelemetry.api.baggage.BaggageEntry;
import io.opentelemetry.api.trace.Span;
import io.opentelemetry.api.trace.SpanContext;
import io.opentelemetry.context.Context;
import io.opentelemetry.instrumentation.api.incubator.log.LoggingContextConstants;
import io.opentelemetry.instrumentation.api.internal.ConfigPropertiesUtil;
import io.opentelemetry.javaagent.bootstrap.internal.ConfiguredResourceAttributesHolder;
import java.util.Collections;
Expand All @@ -26,13 +23,19 @@
* #supplyContextData()} is called when a log entry is created.
*/
public class OpenTelemetryContextDataProvider implements ContextDataProvider {

private static final boolean BAGGAGE_ENABLED =
ConfigPropertiesUtil.getBoolean("otel.instrumentation.log4j-context-data.add-baggage", false);

private static final String TRACE_ID_KEY =
ConfigPropertiesUtil.getString(
"otel.instrumentation.common.logging.trace-id", LoggingContextConstants.TRACE_ID);
private static final String SPAN_ID_KEY =
ConfigPropertiesUtil.getString(
"otel.instrumentation.common.logging.span-id", LoggingContextConstants.SPAN_ID);
private static final String TRACE_FLAGS_KEY =
ConfigPropertiesUtil.getString(
"otel.instrumentation.common.logging.trace-flags", LoggingContextConstants.TRACE_FLAGS);
private static final boolean configuredResourceAttributeAccessible =
isConfiguredResourceAttributeAccessible();

private static final Map<String, String> staticContextData = getStaticContextData();

private static Map<String, String> getStaticContextData() {
Expand Down Expand Up @@ -77,9 +80,9 @@ public Map<String, String> supplyContextData() {
contextData.putAll(staticContextData);

SpanContext spanContext = currentSpan.getSpanContext();
contextData.put(TRACE_ID, spanContext.getTraceId());
contextData.put(SPAN_ID, spanContext.getSpanId());
contextData.put(TRACE_FLAGS, spanContext.getTraceFlags().asHex());
contextData.put(TRACE_ID_KEY, spanContext.getTraceId());
contextData.put(SPAN_ID_KEY, spanContext.getSpanId());
contextData.put(TRACE_FLAGS_KEY, spanContext.getTraceFlags().asHex());

if (BAGGAGE_ENABLED) {
Baggage baggage = Baggage.fromContext(context);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/

package io.opentelemetry.instrumentation.log4j.contextdata.v2_17;

import io.opentelemetry.instrumentation.log4j.contextdata.Log4j2LoggingKeysTest;
import io.opentelemetry.instrumentation.testing.junit.InstrumentationExtension;
import io.opentelemetry.instrumentation.testing.junit.LibraryInstrumentationExtension;
import org.junit.jupiter.api.extension.RegisterExtension;

class LibraryLog4j2LoggingKeysTest extends Log4j2LoggingKeysTest {
@RegisterExtension
static final InstrumentationExtension testing = LibraryInstrumentationExtension.create();

@Override
public InstrumentationExtension getInstrumentationExtension() {
return testing;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ tasks {
test {
filter {
excludeTestsMatching("Log4j27BaggageTest")
excludeTestsMatching("Log4j27LoggingKeysTest")
}
jvmArgs("-Dotel.instrumentation.common.mdc.resource-attributes=service.name,telemetry.sdk.language")
}
Expand All @@ -36,7 +37,17 @@ tasks {
jvmArgs("-Dotel.instrumentation.log4j-context-data.add-baggage=true")
}

val testLoggingKeys by registering(Test::class) {
filter {
includeTestsMatching("Log4j27LoggingKeysTest")
}
jvmArgs("-Dotel.instrumentation.common.logging.trace-id=trace_id_test")
jvmArgs("-Dotel.instrumentation.common.logging.span-id=span_id_test")
jvmArgs("-Dotel.instrumentation.common.logging.trace-flags=trace_flags_test")
}

named("check") {
dependsOn(testAddBaggage)
dependsOn(testLoggingKeys)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,12 @@

package io.opentelemetry.javaagent.instrumentation.log4j.contextdata.v2_7;

import static io.opentelemetry.instrumentation.api.incubator.log.LoggingContextConstants.SPAN_ID;
import static io.opentelemetry.instrumentation.api.incubator.log.LoggingContextConstants.TRACE_FLAGS;
import static io.opentelemetry.instrumentation.api.incubator.log.LoggingContextConstants.TRACE_ID;

import io.opentelemetry.api.baggage.Baggage;
import io.opentelemetry.api.baggage.BaggageEntry;
import io.opentelemetry.api.trace.Span;
import io.opentelemetry.api.trace.SpanContext;
import io.opentelemetry.context.Context;
import io.opentelemetry.javaagent.bootstrap.internal.CommonConfig;
import io.opentelemetry.javaagent.bootstrap.internal.ConfiguredResourceAttributesHolder;
import io.opentelemetry.javaagent.bootstrap.internal.InstrumentationConfig;
import java.util.List;
Expand All @@ -28,6 +25,9 @@ public final class SpanDecoratingContextDataInjector implements ContextDataInjec
private static final boolean BAGGAGE_ENABLED =
InstrumentationConfig.get()
.getBoolean("otel.instrumentation.log4j-context-data.add-baggage", false);
private static final String TRACE_ID_KEY = CommonConfig.get().getTraceIdKey();
private static final String SPAN_ID_KEY = CommonConfig.get().getSpanIdKey();
private static final String TRACE_FLAGS_KEY = CommonConfig.get().getTraceFlagsKey();

private static final StringMap staticContextData = getStaticContextData();

Expand All @@ -41,7 +41,7 @@ public SpanDecoratingContextDataInjector(ContextDataInjector delegate) {
public StringMap injectContextData(List<Property> list, StringMap stringMap) {
StringMap contextData = delegate.injectContextData(list, stringMap);

if (contextData.containsKey(TRACE_ID)) {
if (contextData.containsKey(TRACE_ID_KEY)) {
// Assume already instrumented event if traceId is present.
return staticContextData.isEmpty() ? contextData : newContextData(contextData);
}
Expand All @@ -54,9 +54,9 @@ public StringMap injectContextData(List<Property> list, StringMap stringMap) {
}

StringMap newContextData = newContextData(contextData);
newContextData.putValue(TRACE_ID, currentContext.getTraceId());
newContextData.putValue(SPAN_ID, currentContext.getSpanId());
newContextData.putValue(TRACE_FLAGS, currentContext.getTraceFlags().asHex());
newContextData.putValue(TRACE_ID_KEY, currentContext.getTraceId());
newContextData.putValue(SPAN_ID_KEY, currentContext.getSpanId());
newContextData.putValue(TRACE_FLAGS_KEY, currentContext.getTraceFlags().asHex());

if (BAGGAGE_ENABLED) {
Baggage baggage = Baggage.fromContext(context);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/

package io.opentelemetry.javaagent.instrumentation.log4j.contextdata.v2_7;

import io.opentelemetry.instrumentation.log4j.contextdata.Log4j2LoggingKeysTest;
import io.opentelemetry.instrumentation.testing.junit.AgentInstrumentationExtension;
import io.opentelemetry.instrumentation.testing.junit.InstrumentationExtension;
import org.junit.jupiter.api.extension.RegisterExtension;

class Log4j27LoggingKeysTest extends Log4j2LoggingKeysTest {
@RegisterExtension
static final InstrumentationExtension testing = AgentInstrumentationExtension.create();

@Override
public InstrumentationExtension getInstrumentationExtension() {
return testing;
}
}
Loading
Loading