From 22477efb7af8d862ddee61825c43b28766b8f2b8 Mon Sep 17 00:00:00 2001 From: Luca Abbati Date: Thu, 13 Jun 2019 19:18:44 +0200 Subject: [PATCH 01/16] Add basic support for log4j ThreadContext for log injection. --- .../log4j-thread-context.gradle | 28 +++++ .../mdc/ThreadContextInstrumentation.java | 111 ++++++++++++++++++ .../test/groovy/Log4jThreadContextTest.groovy | 97 +++++++++++++++ settings.gradle | 1 + 4 files changed, 237 insertions(+) create mode 100644 dd-java-agent/instrumentation/log4j-thread-context/log4j-thread-context.gradle create mode 100644 dd-java-agent/instrumentation/log4j-thread-context/src/main/java/datadog/trace/instrumentation/slf4j/mdc/ThreadContextInstrumentation.java create mode 100644 dd-java-agent/instrumentation/log4j-thread-context/src/test/groovy/Log4jThreadContextTest.groovy diff --git a/dd-java-agent/instrumentation/log4j-thread-context/log4j-thread-context.gradle b/dd-java-agent/instrumentation/log4j-thread-context/log4j-thread-context.gradle new file mode 100644 index 00000000000..6dbf22fc26c --- /dev/null +++ b/dd-java-agent/instrumentation/log4j-thread-context/log4j-thread-context.gradle @@ -0,0 +1,28 @@ +apply from: "${rootDir}/gradle/java.gradle" + +ext { + log4jVersion = '2.11.2' +} + +//muzzle { +// pass { +// group = 'org.slf4j' +// module = 'slf4j-api' +// versions = '(,)' +// } +//} + +dependencies { + compile project(':dd-trace-api') + compile project(':dd-java-agent:agent-tooling') + + testCompile group: 'org.apache.logging.log4j', name: 'log4j-core', version: log4jVersion + testCompile group: 'org.apache.logging.log4j', name: 'log4j-api', version: log4jVersion + + compile deps.bytebuddy + compile deps.opentracing + annotationProcessor deps.autoservice + implementation deps.autoservice + + testCompile project(':dd-java-agent:testing') +} diff --git a/dd-java-agent/instrumentation/log4j-thread-context/src/main/java/datadog/trace/instrumentation/slf4j/mdc/ThreadContextInstrumentation.java b/dd-java-agent/instrumentation/log4j-thread-context/src/main/java/datadog/trace/instrumentation/slf4j/mdc/ThreadContextInstrumentation.java new file mode 100644 index 00000000000..b33e1078d02 --- /dev/null +++ b/dd-java-agent/instrumentation/log4j-thread-context/src/main/java/datadog/trace/instrumentation/slf4j/mdc/ThreadContextInstrumentation.java @@ -0,0 +1,111 @@ +package datadog.trace.instrumentation.slf4j.mdc; + +import static java.util.Collections.singletonMap; +import static net.bytebuddy.matcher.ElementMatchers.isTypeInitializer; +import static net.bytebuddy.matcher.ElementMatchers.named; + +import com.google.auto.service.AutoService; +import datadog.trace.agent.tooling.Instrumenter; +import datadog.trace.api.Config; +import datadog.trace.api.CorrelationIdentifier; +import datadog.trace.api.GlobalTracer; +import datadog.trace.context.ScopeListener; +import java.lang.reflect.Method; +import java.security.ProtectionDomain; +import java.util.Map; +import lombok.extern.slf4j.Slf4j; +import net.bytebuddy.asm.Advice; +import net.bytebuddy.description.method.MethodDescription; +import net.bytebuddy.description.type.TypeDescription; +import net.bytebuddy.matcher.ElementMatcher; +import net.bytebuddy.utility.JavaModule; + +@AutoService(Instrumenter.class) +public class ThreadContextInstrumentation extends Instrumenter.Default { + public static final String MDC_INSTRUMENTATION_NAME = "log4j-thread-context"; + + private static final String mdcClassName = "org.apache.logging.log4j.ThreadContext"; + + public ThreadContextInstrumentation() { + super(MDC_INSTRUMENTATION_NAME); + } + + @Override + protected boolean defaultEnabled() { + return Config.getBooleanSettingFromEnvironment( + Config.LOGS_INJECTION_ENABLED, Config.DEFAULT_LOGS_INJECTION_ENABLED); + } + + @Override + public ElementMatcher typeMatcher() { + return named(mdcClassName); + } + + @Override + public void postMatch( + final TypeDescription typeDescription, + final ClassLoader classLoader, + final JavaModule module, + final Class classBeingRedefined, + final ProtectionDomain protectionDomain) { + if (classBeingRedefined != null) { + ThreadContextAdvice.mdcClassInitialized(classBeingRedefined); + } + } + + @Override + public Map, String> transformers() { + return singletonMap(isTypeInitializer(), ThreadContextAdvice.class.getName()); + } + + @Override + public String[] helperClassNames() { + return new String[] {ThreadContextAdvice.class.getName() + "$ThreadContextScopeListener"}; + } + + public static class ThreadContextAdvice { + @Advice.OnMethodExit(suppress = Throwable.class) + public static void mdcClassInitialized(@Advice.Origin final Class threadClass) { + try { + final Method putMethod = threadClass.getMethod("put", String.class, String.class); + final Method removeMethod = threadClass.getMethod("remove", String.class); + GlobalTracer.get().addScopeListener(new ThreadContextScopeListener(putMethod, removeMethod)); + } catch (final NoSuchMethodException e) { + org.slf4j.LoggerFactory.getLogger(threadClass).debug("Failed to add log4j ThreadContext span listener", e); + } + } + + @Slf4j + public static class ThreadContextScopeListener implements ScopeListener { + private final Method putMethod; + private final Method removeMethod; + + public ThreadContextScopeListener(final Method putMethod, final Method removeMethod) { + this.putMethod = putMethod; + this.removeMethod = removeMethod; + } + + @Override + public void afterScopeActivated() { + try { + putMethod.invoke( + null, CorrelationIdentifier.getTraceIdKey(), CorrelationIdentifier.getTraceId()); + putMethod.invoke( + null, CorrelationIdentifier.getSpanIdKey(), CorrelationIdentifier.getSpanId()); + } catch (final Exception e) { + log.debug("Exception setting thread context context", e); + } + } + + @Override + public void afterScopeClosed() { + try { + removeMethod.invoke(null, CorrelationIdentifier.getTraceIdKey()); + removeMethod.invoke(null, CorrelationIdentifier.getSpanIdKey()); + } catch (final Exception e) { + log.debug("Exception removing thread context context", e); + } + } + } + } +} diff --git a/dd-java-agent/instrumentation/log4j-thread-context/src/test/groovy/Log4jThreadContextTest.groovy b/dd-java-agent/instrumentation/log4j-thread-context/src/test/groovy/Log4jThreadContextTest.groovy new file mode 100644 index 00000000000..1590e002de5 --- /dev/null +++ b/dd-java-agent/instrumentation/log4j-thread-context/src/test/groovy/Log4jThreadContextTest.groovy @@ -0,0 +1,97 @@ +import datadog.trace.agent.test.AgentTestRunner +import datadog.trace.agent.test.utils.ConfigUtils +import datadog.trace.api.CorrelationIdentifier +import io.opentracing.Scope +import io.opentracing.util.GlobalTracer +import org.apache.logging.log4j.ThreadContext + +import java.util.concurrent.atomic.AtomicReference + +class Log4jThreadContextTest extends AgentTestRunner { + + static { + System.setProperty("dd.logs.injection", "true") + } + + def "ThreadContext shows trace and span ids for active scope"() { + when: + ThreadContext.put("foo", "bar") + Scope rootScope = GlobalTracer.get().buildSpan("root").startActive(true) + + then: + ThreadContext.get(CorrelationIdentifier.getTraceIdKey()) == CorrelationIdentifier.getTraceId() + ThreadContext.get(CorrelationIdentifier.getSpanIdKey()) == CorrelationIdentifier.getSpanId() + ThreadContext.get("foo") == "bar" + + when: + Scope childScope = GlobalTracer.get().buildSpan("child").startActive(true) + + then: + ThreadContext.get(CorrelationIdentifier.getTraceIdKey()) == CorrelationIdentifier.getTraceId() + ThreadContext.get(CorrelationIdentifier.getSpanIdKey()) == CorrelationIdentifier.getSpanId() + ThreadContext.get("foo") == "bar" + + when: + childScope.close() + + then: + ThreadContext.get(CorrelationIdentifier.getTraceIdKey()) == CorrelationIdentifier.getTraceId() + ThreadContext.get(CorrelationIdentifier.getSpanIdKey()) == CorrelationIdentifier.getSpanId() + ThreadContext.get("foo") == "bar" + + when: + rootScope.close() + + then: + ThreadContext.get(CorrelationIdentifier.getTraceIdKey()) == null + ThreadContext.get(CorrelationIdentifier.getSpanIdKey()) == null + ThreadContext.get("foo") == "bar" + } + + def "ThreadContext context scoped by thread"() { + setup: + ConfigUtils.updateConfig { + System.setProperty("dd.logs.injection", "true") + } + AtomicReference thread1TraceId = new AtomicReference<>() + AtomicReference thread2TraceId = new AtomicReference<>() + + final Thread thread1 = new Thread() { + @Override + void run() { + // no trace in scope + thread1TraceId.set(ThreadContext.get(CorrelationIdentifier.getTraceIdKey())) + } + } + + final Thread thread2 = new Thread() { + @Override + void run() { + // other trace in scope + final Scope thread2Scope = GlobalTracer.get().buildSpan("root2").startActive(true) + try { + thread2TraceId.set(ThreadContext.get(CorrelationIdentifier.getTraceIdKey())) + } finally { + thread2Scope.close() + } + } + } + final Scope mainScope = GlobalTracer.get().buildSpan("root").startActive(true) + thread1.start() + thread2.start() + final String mainThreadTraceId = ThreadContext.get(CorrelationIdentifier.getTraceIdKey()) + final String expectedMainThreadTraceId = CorrelationIdentifier.getTraceId() + + thread1.join() + thread2.join() + + expect: + mainThreadTraceId == expectedMainThreadTraceId + thread1TraceId.get() == null + thread2TraceId.get() != null + thread2TraceId.get() != mainThreadTraceId + + cleanup: + mainScope?.close() + } +} diff --git a/settings.gradle b/settings.gradle index 0cd07e4c116..568e34cd198 100644 --- a/settings.gradle +++ b/settings.gradle @@ -66,6 +66,7 @@ include ':dd-java-agent:instrumentation:jsp-2.3' include ':dd-java-agent:instrumentation:kafka-clients-0.11' include ':dd-java-agent:instrumentation:kafka-streams-0.11' include ':dd-java-agent:instrumentation:lettuce-5' +include ':dd-java-agent:instrumentation:log4j-thread-context' include ':dd-java-agent:instrumentation:mongo' include ':dd-java-agent:instrumentation:mongo:driver-3.1' include ':dd-java-agent:instrumentation:mongo:driver-async-3.3' From d9eb480f3ca38fd0e482e5e4336db0903ea1d30f Mon Sep 17 00:00:00 2001 From: Luca Abbati Date: Thu, 13 Jun 2019 19:33:58 +0200 Subject: [PATCH 02/16] Rename log4j2 module to reflect library name --- .../log4j2.gradle} | 20 ++++++++++++------- .../mdc/ThreadContextInstrumentation.java | 0 .../test/groovy/Log4jThreadContextTest.groovy | 0 settings.gradle | 2 +- 4 files changed, 14 insertions(+), 8 deletions(-) rename dd-java-agent/instrumentation/{log4j-thread-context/log4j-thread-context.gradle => log4j2/log4j2.gradle} (72%) rename dd-java-agent/instrumentation/{log4j-thread-context => log4j2}/src/main/java/datadog/trace/instrumentation/slf4j/mdc/ThreadContextInstrumentation.java (100%) rename dd-java-agent/instrumentation/{log4j-thread-context => log4j2}/src/test/groovy/Log4jThreadContextTest.groovy (100%) diff --git a/dd-java-agent/instrumentation/log4j-thread-context/log4j-thread-context.gradle b/dd-java-agent/instrumentation/log4j2/log4j2.gradle similarity index 72% rename from dd-java-agent/instrumentation/log4j-thread-context/log4j-thread-context.gradle rename to dd-java-agent/instrumentation/log4j2/log4j2.gradle index 6dbf22fc26c..981f623b633 100644 --- a/dd-java-agent/instrumentation/log4j-thread-context/log4j-thread-context.gradle +++ b/dd-java-agent/instrumentation/log4j2/log4j2.gradle @@ -4,13 +4,19 @@ ext { log4jVersion = '2.11.2' } -//muzzle { -// pass { -// group = 'org.slf4j' -// module = 'slf4j-api' -// versions = '(,)' -// } -//} +muzzle { + pass { + group = 'org.apache.logging.log4j' + module = 'log4j-core' + versions = '(,)' + } + + pass { + group = 'org.apache.logging.log4j' + module = 'log4j-api' + versions = '(,)' + } +} dependencies { compile project(':dd-trace-api') diff --git a/dd-java-agent/instrumentation/log4j-thread-context/src/main/java/datadog/trace/instrumentation/slf4j/mdc/ThreadContextInstrumentation.java b/dd-java-agent/instrumentation/log4j2/src/main/java/datadog/trace/instrumentation/slf4j/mdc/ThreadContextInstrumentation.java similarity index 100% rename from dd-java-agent/instrumentation/log4j-thread-context/src/main/java/datadog/trace/instrumentation/slf4j/mdc/ThreadContextInstrumentation.java rename to dd-java-agent/instrumentation/log4j2/src/main/java/datadog/trace/instrumentation/slf4j/mdc/ThreadContextInstrumentation.java diff --git a/dd-java-agent/instrumentation/log4j-thread-context/src/test/groovy/Log4jThreadContextTest.groovy b/dd-java-agent/instrumentation/log4j2/src/test/groovy/Log4jThreadContextTest.groovy similarity index 100% rename from dd-java-agent/instrumentation/log4j-thread-context/src/test/groovy/Log4jThreadContextTest.groovy rename to dd-java-agent/instrumentation/log4j2/src/test/groovy/Log4jThreadContextTest.groovy diff --git a/settings.gradle b/settings.gradle index 568e34cd198..4bceeaa7aaf 100644 --- a/settings.gradle +++ b/settings.gradle @@ -66,7 +66,7 @@ include ':dd-java-agent:instrumentation:jsp-2.3' include ':dd-java-agent:instrumentation:kafka-clients-0.11' include ':dd-java-agent:instrumentation:kafka-streams-0.11' include ':dd-java-agent:instrumentation:lettuce-5' -include ':dd-java-agent:instrumentation:log4j-thread-context' +include ':dd-java-agent:instrumentation:log4j2' include ':dd-java-agent:instrumentation:mongo' include ':dd-java-agent:instrumentation:mongo:driver-3.1' include ':dd-java-agent:instrumentation:mongo:driver-async-3.3' From 8d562f91fdee48cc91ed299f471f8d088faf3bca Mon Sep 17 00:00:00 2001 From: Luca Abbati Date: Thu, 13 Jun 2019 19:42:24 +0200 Subject: [PATCH 03/16] Rename log4j package removing the left-over from sl4j original class --- .../mdc => log4j}/ThreadContextInstrumentation.java | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) rename dd-java-agent/instrumentation/log4j2/src/main/java/datadog/trace/instrumentation/{slf4j/mdc => log4j}/ThreadContextInstrumentation.java (92%) diff --git a/dd-java-agent/instrumentation/log4j2/src/main/java/datadog/trace/instrumentation/slf4j/mdc/ThreadContextInstrumentation.java b/dd-java-agent/instrumentation/log4j2/src/main/java/datadog/trace/instrumentation/log4j/ThreadContextInstrumentation.java similarity index 92% rename from dd-java-agent/instrumentation/log4j2/src/main/java/datadog/trace/instrumentation/slf4j/mdc/ThreadContextInstrumentation.java rename to dd-java-agent/instrumentation/log4j2/src/main/java/datadog/trace/instrumentation/log4j/ThreadContextInstrumentation.java index b33e1078d02..644a1a44cf3 100644 --- a/dd-java-agent/instrumentation/log4j2/src/main/java/datadog/trace/instrumentation/slf4j/mdc/ThreadContextInstrumentation.java +++ b/dd-java-agent/instrumentation/log4j2/src/main/java/datadog/trace/instrumentation/log4j/ThreadContextInstrumentation.java @@ -1,4 +1,4 @@ -package datadog.trace.instrumentation.slf4j.mdc; +package datadog.trace.instrumentation.log4j; import static java.util.Collections.singletonMap; import static net.bytebuddy.matcher.ElementMatchers.isTypeInitializer; @@ -69,9 +69,11 @@ public static void mdcClassInitialized(@Advice.Origin final Class threadClass) { try { final Method putMethod = threadClass.getMethod("put", String.class, String.class); final Method removeMethod = threadClass.getMethod("remove", String.class); - GlobalTracer.get().addScopeListener(new ThreadContextScopeListener(putMethod, removeMethod)); + GlobalTracer.get() + .addScopeListener(new ThreadContextScopeListener(putMethod, removeMethod)); } catch (final NoSuchMethodException e) { - org.slf4j.LoggerFactory.getLogger(threadClass).debug("Failed to add log4j ThreadContext span listener", e); + org.slf4j.LoggerFactory.getLogger(threadClass) + .debug("Failed to add log4j ThreadContext span listener", e); } } From dcf0f5703041ec2c0797ebf60b1717211609f15f Mon Sep 17 00:00:00 2001 From: Luca Abbati Date: Thu, 20 Jun 2019 16:08:49 -0400 Subject: [PATCH 04/16] Add support for log4j 1.x --- .../trace/agent/tooling/AgentInstaller.java | 1 + .../instrumentation/log4j1/log4j1.gradle | 34 ++++++ .../log4j1/Log4j1MDCInstrumentation.java | 102 ++++++++++++++++++ .../log4j1/something/SomeClass.java | 18 ++++ .../src/test/groovy/Log4j1MDCTest.groovy | 97 +++++++++++++++++ .../instrumentation/log4j2/log4j2.gradle | 7 ++ .../ThreadContextInstrumentation.java | 2 +- settings.gradle | 1 + 8 files changed, 261 insertions(+), 1 deletion(-) create mode 100644 dd-java-agent/instrumentation/log4j1/log4j1.gradle create mode 100644 dd-java-agent/instrumentation/log4j1/src/main/java/datadog/trace/instrumentation/log4j1/Log4j1MDCInstrumentation.java create mode 100644 dd-java-agent/instrumentation/log4j1/src/main/java/datadoggggg/trace/instrumentation/log4j1/something/SomeClass.java create mode 100644 dd-java-agent/instrumentation/log4j1/src/test/groovy/Log4j1MDCTest.groovy rename dd-java-agent/instrumentation/log4j2/src/main/java/datadog/trace/instrumentation/{log4j => log4j2}/ThreadContextInstrumentation.java (98%) diff --git a/dd-java-agent/agent-tooling/src/main/java/datadog/trace/agent/tooling/AgentInstaller.java b/dd-java-agent/agent-tooling/src/main/java/datadog/trace/agent/tooling/AgentInstaller.java index ba39b39e5fb..2e08c127cdf 100644 --- a/dd-java-agent/agent-tooling/src/main/java/datadog/trace/agent/tooling/AgentInstaller.java +++ b/dd-java-agent/agent-tooling/src/main/java/datadog/trace/agent/tooling/AgentInstaller.java @@ -128,6 +128,7 @@ public static ResettableClassFileTransformer installBytebuddyAgent( .or(nameStartsWith("com.jinspired.")) .or(nameStartsWith("org.jinspired.")) .or(nameStartsWith("org.apache.log4j.")) + .and(not(named("org.apache.log4j.MDC"))) .or(nameStartsWith("org.slf4j.").and(not(named("org.slf4j.MDC")))) .or(nameContains("$JaxbAccessor")) .or(nameContains("CGLIB$$")) diff --git a/dd-java-agent/instrumentation/log4j1/log4j1.gradle b/dd-java-agent/instrumentation/log4j1/log4j1.gradle new file mode 100644 index 00000000000..42ec36690cf --- /dev/null +++ b/dd-java-agent/instrumentation/log4j1/log4j1.gradle @@ -0,0 +1,34 @@ +apply from: "${rootDir}/gradle/java.gradle" + +ext { + log4jVersion = '1.2.17' +} + +muzzle { + pass { + group = 'log4j' + module = 'log4j' + versions = '(,)' + } +} + +configurations { + // In order to test the real log4j library we need to remove the log4j transitive dependency + // dependency brought in by :dd-java-agent:testing over 'log4j-over-slf4j' which would shadow + // the log4j module under test. + testCompile.exclude group: 'org.slf4j', module: 'log4j-over-slf4j' +} + +dependencies { + compile project(':dd-trace-api') + compile project(':dd-java-agent:agent-tooling') + + testCompile group: 'log4j', name: 'log4j', version: log4jVersion + + compile deps.bytebuddy + compile deps.opentracing + annotationProcessor deps.autoservice + implementation deps.autoservice + + testCompile project(':dd-java-agent:testing') +} diff --git a/dd-java-agent/instrumentation/log4j1/src/main/java/datadog/trace/instrumentation/log4j1/Log4j1MDCInstrumentation.java b/dd-java-agent/instrumentation/log4j1/src/main/java/datadog/trace/instrumentation/log4j1/Log4j1MDCInstrumentation.java new file mode 100644 index 00000000000..b867a20750f --- /dev/null +++ b/dd-java-agent/instrumentation/log4j1/src/main/java/datadog/trace/instrumentation/log4j1/Log4j1MDCInstrumentation.java @@ -0,0 +1,102 @@ +package datadog.trace.instrumentation.log4j1; + +import static java.util.Collections.singletonMap; +import static net.bytebuddy.matcher.ElementMatchers.isConstructor; +import static net.bytebuddy.matcher.ElementMatchers.named; + +import com.google.auto.service.AutoService; +import datadog.trace.agent.tooling.Instrumenter; +import datadog.trace.api.Config; +import datadog.trace.api.CorrelationIdentifier; +import datadog.trace.api.GlobalTracer; +import datadog.trace.context.ScopeListener; +import java.lang.reflect.Method; +import java.util.Map; +import lombok.extern.slf4j.Slf4j; +import net.bytebuddy.asm.Advice; +import net.bytebuddy.description.method.MethodDescription; +import net.bytebuddy.description.type.TypeDescription; +import net.bytebuddy.matcher.ElementMatcher; + +@AutoService(Instrumenter.class) +public class Log4j1MDCInstrumentation extends Instrumenter.Default { + public static final String MDC_INSTRUMENTATION_NAME = "log4j-mdc"; + + private static final String mdcClassName = "org.apache.log4j.MDC"; + + public Log4j1MDCInstrumentation() { + super(MDC_INSTRUMENTATION_NAME); + } + + @Override + protected boolean defaultEnabled() { + return Config.getBooleanSettingFromEnvironment( + Config.LOGS_INJECTION_ENABLED, Config.DEFAULT_LOGS_INJECTION_ENABLED); + } + + @Override + public ElementMatcher typeMatcher() { + return named(mdcClassName); + } + + @Override + public Map, String> transformers() { + return singletonMap(isConstructor(), MDCContextAdvice.class.getName()); + } + + @Override + public String[] helperClassNames() { + return new String[] {MDCContextAdvice.class.getName() + "$MDCScopeListener"}; + } + + public static class MDCContextAdvice { + @Advice.OnMethodExit(suppress = Throwable.class) + public static void mdcClassInitialized(@Advice.This Object instance) { + try { + if (instance == null) { + return; + } + + Class mdcClass = instance.getClass(); + final Method putMethod = mdcClass.getMethod("put", String.class, Object.class); + final Method removeMethod = mdcClass.getMethod("remove", String.class); + GlobalTracer.get().addScopeListener(new MDCScopeListener(putMethod, removeMethod)); + } catch (final NoSuchMethodException e) { + } + } + + @Slf4j + public static class MDCScopeListener implements ScopeListener { + private final Method putMethod; + private final Method removeMethod; + + public MDCScopeListener(final Method putMethod, final Method removeMethod) { + System.out.println("Initializing scope listener"); + this.putMethod = putMethod; + this.removeMethod = removeMethod; + } + + @Override + public void afterScopeActivated() { + try { + putMethod.invoke( + null, CorrelationIdentifier.getTraceIdKey(), CorrelationIdentifier.getTraceId()); + putMethod.invoke( + null, CorrelationIdentifier.getSpanIdKey(), CorrelationIdentifier.getSpanId()); + } catch (final Exception e) { + log.debug("Exception setting thread context context", e); + } + } + + @Override + public void afterScopeClosed() { + try { + removeMethod.invoke(null, CorrelationIdentifier.getTraceIdKey()); + removeMethod.invoke(null, CorrelationIdentifier.getSpanIdKey()); + } catch (final Exception e) { + log.debug("Exception removing thread context context", e); + } + } + } + } +} diff --git a/dd-java-agent/instrumentation/log4j1/src/main/java/datadoggggg/trace/instrumentation/log4j1/something/SomeClass.java b/dd-java-agent/instrumentation/log4j1/src/main/java/datadoggggg/trace/instrumentation/log4j1/something/SomeClass.java new file mode 100644 index 00000000000..b72c5f4a14a --- /dev/null +++ b/dd-java-agent/instrumentation/log4j1/src/main/java/datadoggggg/trace/instrumentation/log4j1/something/SomeClass.java @@ -0,0 +1,18 @@ +package datadoggggg.trace.instrumentation.log4j1.something; + +public class SomeClass { + + private static SomeClass instance = new SomeClass(); + + public SomeClass() { + System.out.println("SomeClass Constructor.......!!!!!!!"); + } + + public static void put() { + instance.doSomething(); + } + + public void doSomething() { + System.out.println("SomeClass Doing something............"); + } +} diff --git a/dd-java-agent/instrumentation/log4j1/src/test/groovy/Log4j1MDCTest.groovy b/dd-java-agent/instrumentation/log4j1/src/test/groovy/Log4j1MDCTest.groovy new file mode 100644 index 00000000000..b54617e10d3 --- /dev/null +++ b/dd-java-agent/instrumentation/log4j1/src/test/groovy/Log4j1MDCTest.groovy @@ -0,0 +1,97 @@ +import datadog.trace.agent.test.AgentTestRunner +import datadog.trace.agent.test.utils.ConfigUtils +import datadog.trace.api.CorrelationIdentifier +import io.opentracing.Scope +import io.opentracing.util.GlobalTracer +import org.apache.log4j.MDC +import java.util.concurrent.atomic.AtomicReference + +class Log4j1MDCTest extends AgentTestRunner { + + static { + System.setProperty("dd.logs.injection", "true") + } + + def "MDC shows trace and span ids for active scope"() { + + when: + MDC.put("foo", "bar") + Scope rootScope = GlobalTracer.get().buildSpan("root").startActive(true) + + then: + MDC.get(CorrelationIdentifier.getTraceIdKey()) == CorrelationIdentifier.getTraceId() + MDC.get(CorrelationIdentifier.getSpanIdKey()) == CorrelationIdentifier.getSpanId() + MDC.get("foo") == "bar" + + when: + Scope childScope = GlobalTracer.get().buildSpan("child").startActive(true) + + then: + MDC.get(CorrelationIdentifier.getTraceIdKey()) == CorrelationIdentifier.getTraceId() + MDC.get(CorrelationIdentifier.getSpanIdKey()) == CorrelationIdentifier.getSpanId() + MDC.get("foo") == "bar" + + when: + childScope.close() + + then: + MDC.get(CorrelationIdentifier.getTraceIdKey()) == CorrelationIdentifier.getTraceId() + MDC.get(CorrelationIdentifier.getSpanIdKey()) == CorrelationIdentifier.getSpanId() + MDC.get("foo") == "bar" + + when: + rootScope.close() + + then: + MDC.get(CorrelationIdentifier.getTraceIdKey()) == null + MDC.get(CorrelationIdentifier.getSpanIdKey()) == null + MDC.get("foo") == "bar" + } + + def "MDC context scoped by thread"() { + setup: + ConfigUtils.updateConfig { + System.setProperty("dd.logs.injection", "true") + } + AtomicReference thread1TraceId = new AtomicReference<>() + AtomicReference thread2TraceId = new AtomicReference<>() + + final Thread thread1 = new Thread() { + @Override + void run() { + // no trace in scope + thread1TraceId.set(MDC.get(CorrelationIdentifier.getTraceIdKey())) + } + } + + final Thread thread2 = new Thread() { + @Override + void run() { + // other trace in scope + final Scope thread2Scope = GlobalTracer.get().buildSpan("root2").startActive(true) + try { + thread2TraceId.set(MDC.get(CorrelationIdentifier.getTraceIdKey())) + } finally { + thread2Scope.close() + } + } + } + final Scope mainScope = GlobalTracer.get().buildSpan("root").startActive(true) + thread1.start() + thread2.start() + final String mainThreadTraceId = MDC.get(CorrelationIdentifier.getTraceIdKey()) + final String expectedMainThreadTraceId = CorrelationIdentifier.getTraceId() + + thread1.join() + thread2.join() + + expect: + mainThreadTraceId == expectedMainThreadTraceId + thread1TraceId.get() == null + thread2TraceId.get() != null + thread2TraceId.get() != mainThreadTraceId + + cleanup: + mainScope?.close() + } +} diff --git a/dd-java-agent/instrumentation/log4j2/log4j2.gradle b/dd-java-agent/instrumentation/log4j2/log4j2.gradle index 981f623b633..b9fb992551f 100644 --- a/dd-java-agent/instrumentation/log4j2/log4j2.gradle +++ b/dd-java-agent/instrumentation/log4j2/log4j2.gradle @@ -4,6 +4,13 @@ ext { log4jVersion = '2.11.2' } +configurations { + // In order to test the real log4j library we need to remove the log4j transitive dependency + // dependency brought in by :dd-java-agent:testing over 'log4j-over-slf4j' which would shadow + // the log4j module under test. + testCompile.exclude group: 'org.slf4j', module: 'log4j-over-slf4j' +} + muzzle { pass { group = 'org.apache.logging.log4j' diff --git a/dd-java-agent/instrumentation/log4j2/src/main/java/datadog/trace/instrumentation/log4j/ThreadContextInstrumentation.java b/dd-java-agent/instrumentation/log4j2/src/main/java/datadog/trace/instrumentation/log4j2/ThreadContextInstrumentation.java similarity index 98% rename from dd-java-agent/instrumentation/log4j2/src/main/java/datadog/trace/instrumentation/log4j/ThreadContextInstrumentation.java rename to dd-java-agent/instrumentation/log4j2/src/main/java/datadog/trace/instrumentation/log4j2/ThreadContextInstrumentation.java index 644a1a44cf3..85ec29546ed 100644 --- a/dd-java-agent/instrumentation/log4j2/src/main/java/datadog/trace/instrumentation/log4j/ThreadContextInstrumentation.java +++ b/dd-java-agent/instrumentation/log4j2/src/main/java/datadog/trace/instrumentation/log4j2/ThreadContextInstrumentation.java @@ -1,4 +1,4 @@ -package datadog.trace.instrumentation.log4j; +package datadog.trace.instrumentation.log4j2; import static java.util.Collections.singletonMap; import static net.bytebuddy.matcher.ElementMatchers.isTypeInitializer; diff --git a/settings.gradle b/settings.gradle index 4bceeaa7aaf..23b68dd31f0 100644 --- a/settings.gradle +++ b/settings.gradle @@ -66,6 +66,7 @@ include ':dd-java-agent:instrumentation:jsp-2.3' include ':dd-java-agent:instrumentation:kafka-clients-0.11' include ':dd-java-agent:instrumentation:kafka-streams-0.11' include ':dd-java-agent:instrumentation:lettuce-5' +include ':dd-java-agent:instrumentation:log4j1' include ':dd-java-agent:instrumentation:log4j2' include ':dd-java-agent:instrumentation:mongo' include ':dd-java-agent:instrumentation:mongo:driver-3.1' From 34d589e53690649047a53d725d7b09669d3790c3 Mon Sep 17 00:00:00 2001 From: Luca Abbati Date: Thu, 20 Jun 2019 17:07:28 -0400 Subject: [PATCH 05/16] Create a reusable log context listener to be used for slf4j, log4j1 and log4j2 --- .../tooling/log/LogContextScopeListener.java | 47 +++++++++++++++++++ .../log4j1/Log4j1MDCInstrumentation.java | 42 ++--------------- .../log4j2/ThreadContextInstrumentation.java | 42 ++--------------- .../mdc/MDCInjectionInstrumentation.java | 41 ++-------------- 4 files changed, 56 insertions(+), 116 deletions(-) create mode 100644 dd-java-agent/agent-tooling/src/main/java/datadog/trace/agent/tooling/log/LogContextScopeListener.java diff --git a/dd-java-agent/agent-tooling/src/main/java/datadog/trace/agent/tooling/log/LogContextScopeListener.java b/dd-java-agent/agent-tooling/src/main/java/datadog/trace/agent/tooling/log/LogContextScopeListener.java new file mode 100644 index 00000000000..3a4128a50a5 --- /dev/null +++ b/dd-java-agent/agent-tooling/src/main/java/datadog/trace/agent/tooling/log/LogContextScopeListener.java @@ -0,0 +1,47 @@ +package datadog.trace.agent.tooling.log; + +import datadog.trace.api.CorrelationIdentifier; +import datadog.trace.context.ScopeListener; +import java.lang.reflect.Method; +import lombok.extern.slf4j.Slf4j; + +/** + * A scope listener that receives the MDC/ThreadContext put and receive methods and update the trace + * and span reference anytime a new scope is activated. + */ +@Slf4j +public class LogContextScopeListener implements ScopeListener { + + /** A reference to the log context method that sets a new attribute in the log context */ + private final Method putMethod; + + /** A reference to the log context method that removes an attribute from the log context */ + private final Method removeMethod; + + public LogContextScopeListener(final Method putMethod, final Method removeMethod) { + this.putMethod = putMethod; + this.removeMethod = removeMethod; + } + + @Override + public void afterScopeActivated() { + try { + putMethod.invoke( + null, CorrelationIdentifier.getTraceIdKey(), CorrelationIdentifier.getTraceId()); + putMethod.invoke( + null, CorrelationIdentifier.getSpanIdKey(), CorrelationIdentifier.getSpanId()); + } catch (final Exception e) { + log.debug("Exception setting log context context", e); + } + } + + @Override + public void afterScopeClosed() { + try { + removeMethod.invoke(null, CorrelationIdentifier.getTraceIdKey()); + removeMethod.invoke(null, CorrelationIdentifier.getSpanIdKey()); + } catch (final Exception e) { + log.debug("Exception removing log context context", e); + } + } +} diff --git a/dd-java-agent/instrumentation/log4j1/src/main/java/datadog/trace/instrumentation/log4j1/Log4j1MDCInstrumentation.java b/dd-java-agent/instrumentation/log4j1/src/main/java/datadog/trace/instrumentation/log4j1/Log4j1MDCInstrumentation.java index b867a20750f..05a563f42af 100644 --- a/dd-java-agent/instrumentation/log4j1/src/main/java/datadog/trace/instrumentation/log4j1/Log4j1MDCInstrumentation.java +++ b/dd-java-agent/instrumentation/log4j1/src/main/java/datadog/trace/instrumentation/log4j1/Log4j1MDCInstrumentation.java @@ -6,13 +6,11 @@ import com.google.auto.service.AutoService; import datadog.trace.agent.tooling.Instrumenter; +import datadog.trace.agent.tooling.log.LogContextScopeListener; import datadog.trace.api.Config; -import datadog.trace.api.CorrelationIdentifier; import datadog.trace.api.GlobalTracer; -import datadog.trace.context.ScopeListener; import java.lang.reflect.Method; import java.util.Map; -import lombok.extern.slf4j.Slf4j; import net.bytebuddy.asm.Advice; import net.bytebuddy.description.method.MethodDescription; import net.bytebuddy.description.type.TypeDescription; @@ -46,7 +44,7 @@ public Map, String> transfor @Override public String[] helperClassNames() { - return new String[] {MDCContextAdvice.class.getName() + "$MDCScopeListener"}; + return new String[] {LogContextScopeListener.class.getName()}; } public static class MDCContextAdvice { @@ -60,43 +58,9 @@ public static void mdcClassInitialized(@Advice.This Object instance) { Class mdcClass = instance.getClass(); final Method putMethod = mdcClass.getMethod("put", String.class, Object.class); final Method removeMethod = mdcClass.getMethod("remove", String.class); - GlobalTracer.get().addScopeListener(new MDCScopeListener(putMethod, removeMethod)); + GlobalTracer.get().addScopeListener(new LogContextScopeListener(putMethod, removeMethod)); } catch (final NoSuchMethodException e) { } } - - @Slf4j - public static class MDCScopeListener implements ScopeListener { - private final Method putMethod; - private final Method removeMethod; - - public MDCScopeListener(final Method putMethod, final Method removeMethod) { - System.out.println("Initializing scope listener"); - this.putMethod = putMethod; - this.removeMethod = removeMethod; - } - - @Override - public void afterScopeActivated() { - try { - putMethod.invoke( - null, CorrelationIdentifier.getTraceIdKey(), CorrelationIdentifier.getTraceId()); - putMethod.invoke( - null, CorrelationIdentifier.getSpanIdKey(), CorrelationIdentifier.getSpanId()); - } catch (final Exception e) { - log.debug("Exception setting thread context context", e); - } - } - - @Override - public void afterScopeClosed() { - try { - removeMethod.invoke(null, CorrelationIdentifier.getTraceIdKey()); - removeMethod.invoke(null, CorrelationIdentifier.getSpanIdKey()); - } catch (final Exception e) { - log.debug("Exception removing thread context context", e); - } - } - } } } diff --git a/dd-java-agent/instrumentation/log4j2/src/main/java/datadog/trace/instrumentation/log4j2/ThreadContextInstrumentation.java b/dd-java-agent/instrumentation/log4j2/src/main/java/datadog/trace/instrumentation/log4j2/ThreadContextInstrumentation.java index 85ec29546ed..03d16f21ffc 100644 --- a/dd-java-agent/instrumentation/log4j2/src/main/java/datadog/trace/instrumentation/log4j2/ThreadContextInstrumentation.java +++ b/dd-java-agent/instrumentation/log4j2/src/main/java/datadog/trace/instrumentation/log4j2/ThreadContextInstrumentation.java @@ -6,14 +6,12 @@ import com.google.auto.service.AutoService; import datadog.trace.agent.tooling.Instrumenter; +import datadog.trace.agent.tooling.log.LogContextScopeListener; import datadog.trace.api.Config; -import datadog.trace.api.CorrelationIdentifier; import datadog.trace.api.GlobalTracer; -import datadog.trace.context.ScopeListener; import java.lang.reflect.Method; import java.security.ProtectionDomain; import java.util.Map; -import lombok.extern.slf4j.Slf4j; import net.bytebuddy.asm.Advice; import net.bytebuddy.description.method.MethodDescription; import net.bytebuddy.description.type.TypeDescription; @@ -60,7 +58,7 @@ public Map, String> transfor @Override public String[] helperClassNames() { - return new String[] {ThreadContextAdvice.class.getName() + "$ThreadContextScopeListener"}; + return new String[] {LogContextScopeListener.class.getName()}; } public static class ThreadContextAdvice { @@ -69,45 +67,11 @@ public static void mdcClassInitialized(@Advice.Origin final Class threadClass) { try { final Method putMethod = threadClass.getMethod("put", String.class, String.class); final Method removeMethod = threadClass.getMethod("remove", String.class); - GlobalTracer.get() - .addScopeListener(new ThreadContextScopeListener(putMethod, removeMethod)); + GlobalTracer.get().addScopeListener(new LogContextScopeListener(putMethod, removeMethod)); } catch (final NoSuchMethodException e) { org.slf4j.LoggerFactory.getLogger(threadClass) .debug("Failed to add log4j ThreadContext span listener", e); } } - - @Slf4j - public static class ThreadContextScopeListener implements ScopeListener { - private final Method putMethod; - private final Method removeMethod; - - public ThreadContextScopeListener(final Method putMethod, final Method removeMethod) { - this.putMethod = putMethod; - this.removeMethod = removeMethod; - } - - @Override - public void afterScopeActivated() { - try { - putMethod.invoke( - null, CorrelationIdentifier.getTraceIdKey(), CorrelationIdentifier.getTraceId()); - putMethod.invoke( - null, CorrelationIdentifier.getSpanIdKey(), CorrelationIdentifier.getSpanId()); - } catch (final Exception e) { - log.debug("Exception setting thread context context", e); - } - } - - @Override - public void afterScopeClosed() { - try { - removeMethod.invoke(null, CorrelationIdentifier.getTraceIdKey()); - removeMethod.invoke(null, CorrelationIdentifier.getSpanIdKey()); - } catch (final Exception e) { - log.debug("Exception removing thread context context", e); - } - } - } } } diff --git a/dd-java-agent/instrumentation/slf4j-mdc/src/main/java/datadog/trace/instrumentation/slf4j/mdc/MDCInjectionInstrumentation.java b/dd-java-agent/instrumentation/slf4j-mdc/src/main/java/datadog/trace/instrumentation/slf4j/mdc/MDCInjectionInstrumentation.java index 992923d30c2..d9a203d971d 100644 --- a/dd-java-agent/instrumentation/slf4j-mdc/src/main/java/datadog/trace/instrumentation/slf4j/mdc/MDCInjectionInstrumentation.java +++ b/dd-java-agent/instrumentation/slf4j-mdc/src/main/java/datadog/trace/instrumentation/slf4j/mdc/MDCInjectionInstrumentation.java @@ -6,14 +6,12 @@ import com.google.auto.service.AutoService; import datadog.trace.agent.tooling.Instrumenter; +import datadog.trace.agent.tooling.log.LogContextScopeListener; import datadog.trace.api.Config; -import datadog.trace.api.CorrelationIdentifier; import datadog.trace.api.GlobalTracer; -import datadog.trace.context.ScopeListener; import java.lang.reflect.Method; import java.security.ProtectionDomain; import java.util.Map; -import lombok.extern.slf4j.Slf4j; import net.bytebuddy.asm.Advice; import net.bytebuddy.description.method.MethodDescription; import net.bytebuddy.description.type.TypeDescription; @@ -61,7 +59,7 @@ public Map, String> transfor @Override public String[] helperClassNames() { - return new String[] {MDCAdvice.class.getName() + "$MDCScopeListener"}; + return new String[] {LogContextScopeListener.class.getName()}; } public static class MDCAdvice { @@ -70,43 +68,10 @@ public static void mdcClassInitialized(@Advice.Origin final Class mdcClass) { try { final Method putMethod = mdcClass.getMethod("put", String.class, String.class); final Method removeMethod = mdcClass.getMethod("remove", String.class); - GlobalTracer.get().addScopeListener(new MDCScopeListener(putMethod, removeMethod)); + GlobalTracer.get().addScopeListener(new LogContextScopeListener(putMethod, removeMethod)); } catch (final NoSuchMethodException e) { org.slf4j.LoggerFactory.getLogger(mdcClass).debug("Failed to add MDC span listener", e); } } - - @Slf4j - public static class MDCScopeListener implements ScopeListener { - private final Method putMethod; - private final Method removeMethod; - - public MDCScopeListener(final Method putMethod, final Method removeMethod) { - this.putMethod = putMethod; - this.removeMethod = removeMethod; - } - - @Override - public void afterScopeActivated() { - try { - putMethod.invoke( - null, CorrelationIdentifier.getTraceIdKey(), CorrelationIdentifier.getTraceId()); - putMethod.invoke( - null, CorrelationIdentifier.getSpanIdKey(), CorrelationIdentifier.getSpanId()); - } catch (final Exception e) { - log.debug("Exception setting mdc context", e); - } - } - - @Override - public void afterScopeClosed() { - try { - removeMethod.invoke(null, CorrelationIdentifier.getTraceIdKey()); - removeMethod.invoke(null, CorrelationIdentifier.getSpanIdKey()); - } catch (final Exception e) { - log.debug("Exception removing mdc context", e); - } - } - } } } From ecdf6664ef06e2d9c0258b4671e43f95e2ab0f63 Mon Sep 17 00:00:00 2001 From: Luca Abbati Date: Thu, 20 Jun 2019 17:36:10 -0400 Subject: [PATCH 06/16] Refactor log4jX instrumentations --- .../tooling/log/LogContextScopeListener.java | 2 +- .../instrumentation/log4j1/log4j1.gradle | 2 +- .../log4j1/Log4j1MDCInstrumentation.java | 7 ++----- .../log4j1/something/SomeClass.java | 18 ------------------ .../src/test/groovy/Log4j1MDCTest.groovy | 2 ++ .../instrumentation/log4j2/log4j2.gradle | 2 +- .../log4j2/ThreadContextInstrumentation.java | 7 ++----- .../test/groovy/Log4jThreadContextTest.groovy | 2 ++ 8 files changed, 11 insertions(+), 31 deletions(-) delete mode 100644 dd-java-agent/instrumentation/log4j1/src/main/java/datadoggggg/trace/instrumentation/log4j1/something/SomeClass.java diff --git a/dd-java-agent/agent-tooling/src/main/java/datadog/trace/agent/tooling/log/LogContextScopeListener.java b/dd-java-agent/agent-tooling/src/main/java/datadog/trace/agent/tooling/log/LogContextScopeListener.java index 3a4128a50a5..7e3ddff23b7 100644 --- a/dd-java-agent/agent-tooling/src/main/java/datadog/trace/agent/tooling/log/LogContextScopeListener.java +++ b/dd-java-agent/agent-tooling/src/main/java/datadog/trace/agent/tooling/log/LogContextScopeListener.java @@ -7,7 +7,7 @@ /** * A scope listener that receives the MDC/ThreadContext put and receive methods and update the trace - * and span reference anytime a new scope is activated. + * and span reference anytime a new scope is activated or closed. */ @Slf4j public class LogContextScopeListener implements ScopeListener { diff --git a/dd-java-agent/instrumentation/log4j1/log4j1.gradle b/dd-java-agent/instrumentation/log4j1/log4j1.gradle index 42ec36690cf..33ff242c80a 100644 --- a/dd-java-agent/instrumentation/log4j1/log4j1.gradle +++ b/dd-java-agent/instrumentation/log4j1/log4j1.gradle @@ -15,7 +15,7 @@ muzzle { configurations { // In order to test the real log4j library we need to remove the log4j transitive dependency // dependency brought in by :dd-java-agent:testing over 'log4j-over-slf4j' which would shadow - // the log4j module under test. + // the log4j module under test using a proxy to slf4j instead. testCompile.exclude group: 'org.slf4j', module: 'log4j-over-slf4j' } diff --git a/dd-java-agent/instrumentation/log4j1/src/main/java/datadog/trace/instrumentation/log4j1/Log4j1MDCInstrumentation.java b/dd-java-agent/instrumentation/log4j1/src/main/java/datadog/trace/instrumentation/log4j1/Log4j1MDCInstrumentation.java index 05a563f42af..16c71a1b8bc 100644 --- a/dd-java-agent/instrumentation/log4j1/src/main/java/datadog/trace/instrumentation/log4j1/Log4j1MDCInstrumentation.java +++ b/dd-java-agent/instrumentation/log4j1/src/main/java/datadog/trace/instrumentation/log4j1/Log4j1MDCInstrumentation.java @@ -20,21 +20,18 @@ public class Log4j1MDCInstrumentation extends Instrumenter.Default { public static final String MDC_INSTRUMENTATION_NAME = "log4j-mdc"; - private static final String mdcClassName = "org.apache.log4j.MDC"; - public Log4j1MDCInstrumentation() { super(MDC_INSTRUMENTATION_NAME); } @Override protected boolean defaultEnabled() { - return Config.getBooleanSettingFromEnvironment( - Config.LOGS_INJECTION_ENABLED, Config.DEFAULT_LOGS_INJECTION_ENABLED); + return Config.get().isLogsInjectionEnabled(); } @Override public ElementMatcher typeMatcher() { - return named(mdcClassName); + return named("org.apache.log4j.MDC"); } @Override diff --git a/dd-java-agent/instrumentation/log4j1/src/main/java/datadoggggg/trace/instrumentation/log4j1/something/SomeClass.java b/dd-java-agent/instrumentation/log4j1/src/main/java/datadoggggg/trace/instrumentation/log4j1/something/SomeClass.java deleted file mode 100644 index b72c5f4a14a..00000000000 --- a/dd-java-agent/instrumentation/log4j1/src/main/java/datadoggggg/trace/instrumentation/log4j1/something/SomeClass.java +++ /dev/null @@ -1,18 +0,0 @@ -package datadoggggg.trace.instrumentation.log4j1.something; - -public class SomeClass { - - private static SomeClass instance = new SomeClass(); - - public SomeClass() { - System.out.println("SomeClass Constructor.......!!!!!!!"); - } - - public static void put() { - instance.doSomething(); - } - - public void doSomething() { - System.out.println("SomeClass Doing something............"); - } -} diff --git a/dd-java-agent/instrumentation/log4j1/src/test/groovy/Log4j1MDCTest.groovy b/dd-java-agent/instrumentation/log4j1/src/test/groovy/Log4j1MDCTest.groovy index b54617e10d3..2f0c8e48874 100644 --- a/dd-java-agent/instrumentation/log4j1/src/test/groovy/Log4j1MDCTest.groovy +++ b/dd-java-agent/instrumentation/log4j1/src/test/groovy/Log4j1MDCTest.groovy @@ -9,7 +9,9 @@ import java.util.concurrent.atomic.AtomicReference class Log4j1MDCTest extends AgentTestRunner { static { + ConfigUtils.updateConfig { System.setProperty("dd.logs.injection", "true") + } } def "MDC shows trace and span ids for active scope"() { diff --git a/dd-java-agent/instrumentation/log4j2/log4j2.gradle b/dd-java-agent/instrumentation/log4j2/log4j2.gradle index b9fb992551f..c92bad8cf6e 100644 --- a/dd-java-agent/instrumentation/log4j2/log4j2.gradle +++ b/dd-java-agent/instrumentation/log4j2/log4j2.gradle @@ -7,7 +7,7 @@ ext { configurations { // In order to test the real log4j library we need to remove the log4j transitive dependency // dependency brought in by :dd-java-agent:testing over 'log4j-over-slf4j' which would shadow - // the log4j module under test. + // the log4j module under test using a proxy to slf4j instead. testCompile.exclude group: 'org.slf4j', module: 'log4j-over-slf4j' } diff --git a/dd-java-agent/instrumentation/log4j2/src/main/java/datadog/trace/instrumentation/log4j2/ThreadContextInstrumentation.java b/dd-java-agent/instrumentation/log4j2/src/main/java/datadog/trace/instrumentation/log4j2/ThreadContextInstrumentation.java index 03d16f21ffc..9aebc903f45 100644 --- a/dd-java-agent/instrumentation/log4j2/src/main/java/datadog/trace/instrumentation/log4j2/ThreadContextInstrumentation.java +++ b/dd-java-agent/instrumentation/log4j2/src/main/java/datadog/trace/instrumentation/log4j2/ThreadContextInstrumentation.java @@ -22,21 +22,18 @@ public class ThreadContextInstrumentation extends Instrumenter.Default { public static final String MDC_INSTRUMENTATION_NAME = "log4j-thread-context"; - private static final String mdcClassName = "org.apache.logging.log4j.ThreadContext"; - public ThreadContextInstrumentation() { super(MDC_INSTRUMENTATION_NAME); } @Override protected boolean defaultEnabled() { - return Config.getBooleanSettingFromEnvironment( - Config.LOGS_INJECTION_ENABLED, Config.DEFAULT_LOGS_INJECTION_ENABLED); + return Config.get().isLogsInjectionEnabled(); } @Override public ElementMatcher typeMatcher() { - return named(mdcClassName); + return named("org.apache.logging.log4j.ThreadContext"); } @Override diff --git a/dd-java-agent/instrumentation/log4j2/src/test/groovy/Log4jThreadContextTest.groovy b/dd-java-agent/instrumentation/log4j2/src/test/groovy/Log4jThreadContextTest.groovy index 1590e002de5..19b4daa5472 100644 --- a/dd-java-agent/instrumentation/log4j2/src/test/groovy/Log4jThreadContextTest.groovy +++ b/dd-java-agent/instrumentation/log4j2/src/test/groovy/Log4jThreadContextTest.groovy @@ -10,7 +10,9 @@ import java.util.concurrent.atomic.AtomicReference class Log4jThreadContextTest extends AgentTestRunner { static { + ConfigUtils.updateConfig { System.setProperty("dd.logs.injection", "true") + } } def "ThreadContext shows trace and span ids for active scope"() { From c2bd5eefa081f0a79c988a78d60605ef318b24ce Mon Sep 17 00:00:00 2001 From: Luca Abbati Date: Thu, 20 Jun 2019 17:55:43 -0400 Subject: [PATCH 07/16] Remove method that was copied and pasted from slf4j instrumentation but seems not to be relevant here --- .../log4j2/ThreadContextInstrumentation.java | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/dd-java-agent/instrumentation/log4j2/src/main/java/datadog/trace/instrumentation/log4j2/ThreadContextInstrumentation.java b/dd-java-agent/instrumentation/log4j2/src/main/java/datadog/trace/instrumentation/log4j2/ThreadContextInstrumentation.java index 9aebc903f45..0d33141df44 100644 --- a/dd-java-agent/instrumentation/log4j2/src/main/java/datadog/trace/instrumentation/log4j2/ThreadContextInstrumentation.java +++ b/dd-java-agent/instrumentation/log4j2/src/main/java/datadog/trace/instrumentation/log4j2/ThreadContextInstrumentation.java @@ -36,18 +36,6 @@ public ElementMatcher typeMatcher() { return named("org.apache.logging.log4j.ThreadContext"); } - @Override - public void postMatch( - final TypeDescription typeDescription, - final ClassLoader classLoader, - final JavaModule module, - final Class classBeingRedefined, - final ProtectionDomain protectionDomain) { - if (classBeingRedefined != null) { - ThreadContextAdvice.mdcClassInitialized(classBeingRedefined); - } - } - @Override public Map, String> transformers() { return singletonMap(isTypeInitializer(), ThreadContextAdvice.class.getName()); From 4d1d5d1012501678cedc6eaa4b1f48f3c76fc8ec Mon Sep 17 00:00:00 2001 From: Luca Abbati Date: Thu, 20 Jun 2019 18:14:46 -0400 Subject: [PATCH 08/16] Introduce the mandatory test suite that a supported logging library MUST satisfy for log injection --- .../src/test/groovy/Log4j1MDCTest.groovy | 100 ++-------------- .../log4j2/ThreadContextInstrumentation.java | 2 - .../test/groovy/Log4jThreadContextTest.groovy | 100 ++-------------- .../src/test/groovy/Slf4jMDCTest.groovy | 96 ++------------- .../LogContextContextInjectionTest.groovy | 113 ++++++++++++++++++ 5 files changed, 137 insertions(+), 274 deletions(-) create mode 100644 dd-java-agent/testing/src/main/groovy/datadog/trace/agent/test/log/injection/LogContextContextInjectionTest.groovy diff --git a/dd-java-agent/instrumentation/log4j1/src/test/groovy/Log4j1MDCTest.groovy b/dd-java-agent/instrumentation/log4j1/src/test/groovy/Log4j1MDCTest.groovy index 2f0c8e48874..0ae31b166f4 100644 --- a/dd-java-agent/instrumentation/log4j1/src/test/groovy/Log4j1MDCTest.groovy +++ b/dd-java-agent/instrumentation/log4j1/src/test/groovy/Log4j1MDCTest.groovy @@ -1,99 +1,15 @@ -import datadog.trace.agent.test.AgentTestRunner -import datadog.trace.agent.test.utils.ConfigUtils -import datadog.trace.api.CorrelationIdentifier -import io.opentracing.Scope -import io.opentracing.util.GlobalTracer +import datadog.trace.agent.test.log.injection.LogContextContextInjectionTest import org.apache.log4j.MDC -import java.util.concurrent.atomic.AtomicReference -class Log4j1MDCTest extends AgentTestRunner { +class Log4j1MDCTest extends LogContextContextInjectionTest { - static { - ConfigUtils.updateConfig { - System.setProperty("dd.logs.injection", "true") - } + @Override + def put(String key, Object value) { + return MDC.put(key, value) } - def "MDC shows trace and span ids for active scope"() { - - when: - MDC.put("foo", "bar") - Scope rootScope = GlobalTracer.get().buildSpan("root").startActive(true) - - then: - MDC.get(CorrelationIdentifier.getTraceIdKey()) == CorrelationIdentifier.getTraceId() - MDC.get(CorrelationIdentifier.getSpanIdKey()) == CorrelationIdentifier.getSpanId() - MDC.get("foo") == "bar" - - when: - Scope childScope = GlobalTracer.get().buildSpan("child").startActive(true) - - then: - MDC.get(CorrelationIdentifier.getTraceIdKey()) == CorrelationIdentifier.getTraceId() - MDC.get(CorrelationIdentifier.getSpanIdKey()) == CorrelationIdentifier.getSpanId() - MDC.get("foo") == "bar" - - when: - childScope.close() - - then: - MDC.get(CorrelationIdentifier.getTraceIdKey()) == CorrelationIdentifier.getTraceId() - MDC.get(CorrelationIdentifier.getSpanIdKey()) == CorrelationIdentifier.getSpanId() - MDC.get("foo") == "bar" - - when: - rootScope.close() - - then: - MDC.get(CorrelationIdentifier.getTraceIdKey()) == null - MDC.get(CorrelationIdentifier.getSpanIdKey()) == null - MDC.get("foo") == "bar" - } - - def "MDC context scoped by thread"() { - setup: - ConfigUtils.updateConfig { - System.setProperty("dd.logs.injection", "true") - } - AtomicReference thread1TraceId = new AtomicReference<>() - AtomicReference thread2TraceId = new AtomicReference<>() - - final Thread thread1 = new Thread() { - @Override - void run() { - // no trace in scope - thread1TraceId.set(MDC.get(CorrelationIdentifier.getTraceIdKey())) - } - } - - final Thread thread2 = new Thread() { - @Override - void run() { - // other trace in scope - final Scope thread2Scope = GlobalTracer.get().buildSpan("root2").startActive(true) - try { - thread2TraceId.set(MDC.get(CorrelationIdentifier.getTraceIdKey())) - } finally { - thread2Scope.close() - } - } - } - final Scope mainScope = GlobalTracer.get().buildSpan("root").startActive(true) - thread1.start() - thread2.start() - final String mainThreadTraceId = MDC.get(CorrelationIdentifier.getTraceIdKey()) - final String expectedMainThreadTraceId = CorrelationIdentifier.getTraceId() - - thread1.join() - thread2.join() - - expect: - mainThreadTraceId == expectedMainThreadTraceId - thread1TraceId.get() == null - thread2TraceId.get() != null - thread2TraceId.get() != mainThreadTraceId - - cleanup: - mainScope?.close() + @Override + def get(String key) { + return MDC.get(key) } } diff --git a/dd-java-agent/instrumentation/log4j2/src/main/java/datadog/trace/instrumentation/log4j2/ThreadContextInstrumentation.java b/dd-java-agent/instrumentation/log4j2/src/main/java/datadog/trace/instrumentation/log4j2/ThreadContextInstrumentation.java index 0d33141df44..8713182292b 100644 --- a/dd-java-agent/instrumentation/log4j2/src/main/java/datadog/trace/instrumentation/log4j2/ThreadContextInstrumentation.java +++ b/dd-java-agent/instrumentation/log4j2/src/main/java/datadog/trace/instrumentation/log4j2/ThreadContextInstrumentation.java @@ -10,13 +10,11 @@ import datadog.trace.api.Config; import datadog.trace.api.GlobalTracer; import java.lang.reflect.Method; -import java.security.ProtectionDomain; import java.util.Map; import net.bytebuddy.asm.Advice; import net.bytebuddy.description.method.MethodDescription; import net.bytebuddy.description.type.TypeDescription; import net.bytebuddy.matcher.ElementMatcher; -import net.bytebuddy.utility.JavaModule; @AutoService(Instrumenter.class) public class ThreadContextInstrumentation extends Instrumenter.Default { diff --git a/dd-java-agent/instrumentation/log4j2/src/test/groovy/Log4jThreadContextTest.groovy b/dd-java-agent/instrumentation/log4j2/src/test/groovy/Log4jThreadContextTest.groovy index 19b4daa5472..6ee8cfb1b61 100644 --- a/dd-java-agent/instrumentation/log4j2/src/test/groovy/Log4jThreadContextTest.groovy +++ b/dd-java-agent/instrumentation/log4j2/src/test/groovy/Log4jThreadContextTest.groovy @@ -1,99 +1,15 @@ -import datadog.trace.agent.test.AgentTestRunner -import datadog.trace.agent.test.utils.ConfigUtils -import datadog.trace.api.CorrelationIdentifier -import io.opentracing.Scope -import io.opentracing.util.GlobalTracer +import datadog.trace.agent.test.log.injection.LogContextContextInjectionTest import org.apache.logging.log4j.ThreadContext -import java.util.concurrent.atomic.AtomicReference +class Log4jThreadContextTest extends LogContextContextInjectionTest { -class Log4jThreadContextTest extends AgentTestRunner { - - static { - ConfigUtils.updateConfig { - System.setProperty("dd.logs.injection", "true") - } + @Override + def put(String key, Object value) { + return ThreadContext.put(key, value as String) } - def "ThreadContext shows trace and span ids for active scope"() { - when: - ThreadContext.put("foo", "bar") - Scope rootScope = GlobalTracer.get().buildSpan("root").startActive(true) - - then: - ThreadContext.get(CorrelationIdentifier.getTraceIdKey()) == CorrelationIdentifier.getTraceId() - ThreadContext.get(CorrelationIdentifier.getSpanIdKey()) == CorrelationIdentifier.getSpanId() - ThreadContext.get("foo") == "bar" - - when: - Scope childScope = GlobalTracer.get().buildSpan("child").startActive(true) - - then: - ThreadContext.get(CorrelationIdentifier.getTraceIdKey()) == CorrelationIdentifier.getTraceId() - ThreadContext.get(CorrelationIdentifier.getSpanIdKey()) == CorrelationIdentifier.getSpanId() - ThreadContext.get("foo") == "bar" - - when: - childScope.close() - - then: - ThreadContext.get(CorrelationIdentifier.getTraceIdKey()) == CorrelationIdentifier.getTraceId() - ThreadContext.get(CorrelationIdentifier.getSpanIdKey()) == CorrelationIdentifier.getSpanId() - ThreadContext.get("foo") == "bar" - - when: - rootScope.close() - - then: - ThreadContext.get(CorrelationIdentifier.getTraceIdKey()) == null - ThreadContext.get(CorrelationIdentifier.getSpanIdKey()) == null - ThreadContext.get("foo") == "bar" - } - - def "ThreadContext context scoped by thread"() { - setup: - ConfigUtils.updateConfig { - System.setProperty("dd.logs.injection", "true") - } - AtomicReference thread1TraceId = new AtomicReference<>() - AtomicReference thread2TraceId = new AtomicReference<>() - - final Thread thread1 = new Thread() { - @Override - void run() { - // no trace in scope - thread1TraceId.set(ThreadContext.get(CorrelationIdentifier.getTraceIdKey())) - } - } - - final Thread thread2 = new Thread() { - @Override - void run() { - // other trace in scope - final Scope thread2Scope = GlobalTracer.get().buildSpan("root2").startActive(true) - try { - thread2TraceId.set(ThreadContext.get(CorrelationIdentifier.getTraceIdKey())) - } finally { - thread2Scope.close() - } - } - } - final Scope mainScope = GlobalTracer.get().buildSpan("root").startActive(true) - thread1.start() - thread2.start() - final String mainThreadTraceId = ThreadContext.get(CorrelationIdentifier.getTraceIdKey()) - final String expectedMainThreadTraceId = CorrelationIdentifier.getTraceId() - - thread1.join() - thread2.join() - - expect: - mainThreadTraceId == expectedMainThreadTraceId - thread1TraceId.get() == null - thread2TraceId.get() != null - thread2TraceId.get() != mainThreadTraceId - - cleanup: - mainScope?.close() + @Override + def get(String key) { + return ThreadContext.get(key) } } diff --git a/dd-java-agent/instrumentation/slf4j-mdc/src/test/groovy/Slf4jMDCTest.groovy b/dd-java-agent/instrumentation/slf4j-mdc/src/test/groovy/Slf4jMDCTest.groovy index 727c68d9c1a..f0c9f83327b 100644 --- a/dd-java-agent/instrumentation/slf4j-mdc/src/test/groovy/Slf4jMDCTest.groovy +++ b/dd-java-agent/instrumentation/slf4j-mdc/src/test/groovy/Slf4jMDCTest.groovy @@ -1,95 +1,15 @@ -import datadog.trace.agent.test.AgentTestRunner -import datadog.trace.agent.test.utils.ConfigUtils -import datadog.trace.api.CorrelationIdentifier -import io.opentracing.Scope -import io.opentracing.util.GlobalTracer +import datadog.trace.agent.test.log.injection.LogContextContextInjectionTest import org.slf4j.MDC -import java.util.concurrent.atomic.AtomicReference +class Slf4jMDCTest extends LogContextContextInjectionTest { -class Slf4jMDCTest extends AgentTestRunner { - static { - ConfigUtils.updateConfig { - System.setProperty("dd.logs.injection", "true") - } + @Override + def put(String key, Object value) { + return MDC.put(key, value as String) } - def "mdc shows trace and span ids for active scope"() { - when: - MDC.put("foo", "bar") - Scope rootScope = GlobalTracer.get().buildSpan("root").startActive(true) - - then: - MDC.get(CorrelationIdentifier.getTraceIdKey()) == CorrelationIdentifier.getTraceId() - MDC.get(CorrelationIdentifier.getSpanIdKey()) == CorrelationIdentifier.getSpanId() - MDC.get("foo") == "bar" - - when: - Scope childScope = GlobalTracer.get().buildSpan("child").startActive(true) - - then: - MDC.get(CorrelationIdentifier.getTraceIdKey()) == CorrelationIdentifier.getTraceId() - MDC.get(CorrelationIdentifier.getSpanIdKey()) == CorrelationIdentifier.getSpanId() - MDC.get("foo") == "bar" - - when: - childScope.close() - - then: - MDC.get(CorrelationIdentifier.getTraceIdKey()) == CorrelationIdentifier.getTraceId() - MDC.get(CorrelationIdentifier.getSpanIdKey()) == CorrelationIdentifier.getSpanId() - MDC.get("foo") == "bar" - - when: - rootScope.close() - - then: - MDC.get(CorrelationIdentifier.getTraceIdKey()) == null - MDC.get(CorrelationIdentifier.getSpanIdKey()) == null - MDC.get("foo") == "bar" - } - - def "mdc context scoped by thread"() { - setup: - AtomicReference thread1TraceId = new AtomicReference<>() - AtomicReference thread2TraceId = new AtomicReference<>() - - final Thread thread1 = new Thread() { - @Override - void run() { - // no trace in scope - thread1TraceId.set(MDC.get(CorrelationIdentifier.getTraceIdKey())) - } - } - - final Thread thread2 = new Thread() { - @Override - void run() { - // other trace in scope - final Scope thread2Scope = GlobalTracer.get().buildSpan("root2").startActive(true) - try { - thread2TraceId.set(MDC.get(CorrelationIdentifier.getTraceIdKey())) - } finally { - thread2Scope.close() - } - } - } - final Scope mainScope = GlobalTracer.get().buildSpan("root").startActive(true) - thread1.start() - thread2.start() - final String mainThreadTraceId = MDC.get(CorrelationIdentifier.getTraceIdKey()) - final String expectedMainThreadTraceId = CorrelationIdentifier.getTraceId() - - thread1.join() - thread2.join() - - expect: - mainThreadTraceId == expectedMainThreadTraceId - thread1TraceId.get() == null - thread2TraceId.get() != null - thread2TraceId.get() != mainThreadTraceId - - cleanup: - mainScope?.close() + @Override + def get(String key) { + return MDC.get(key) } } diff --git a/dd-java-agent/testing/src/main/groovy/datadog/trace/agent/test/log/injection/LogContextContextInjectionTest.groovy b/dd-java-agent/testing/src/main/groovy/datadog/trace/agent/test/log/injection/LogContextContextInjectionTest.groovy new file mode 100644 index 00000000000..91eb618c60e --- /dev/null +++ b/dd-java-agent/testing/src/main/groovy/datadog/trace/agent/test/log/injection/LogContextContextInjectionTest.groovy @@ -0,0 +1,113 @@ +package datadog.trace.agent.test.log.injection; + +import datadog.trace.agent.test.AgentTestRunner +import datadog.trace.agent.test.utils.ConfigUtils +import datadog.trace.api.CorrelationIdentifier +import io.opentracing.Scope +import io.opentracing.util.GlobalTracer + +import java.util.concurrent.atomic.AtomicReference + +/** + * This class represents the standard test cases that new logging library integration MUST satisfy in order to support log injection. + */ +abstract class LogContextContextInjectionTest extends AgentTestRunner { + + /** + * Set in the framework-specific context the given value at the given key + */ + abstract put(String key, Object value) + + /** + * Get from the framework-specific context the given value at the given key + */ + abstract get(String key) + + static { + ConfigUtils.updateConfig { + System.setProperty("dd.logs.injection", "true") + } + } + + def "Log context shows trace and span ids for active scope"() { + when: + put("foo", "bar") + Scope rootScope = GlobalTracer.get().buildSpan("root").startActive(true) + + then: + get(CorrelationIdentifier.getTraceIdKey()) == CorrelationIdentifier.getTraceId() + get(CorrelationIdentifier.getSpanIdKey()) == CorrelationIdentifier.getSpanId() + get("foo") == "bar" + + when: + Scope childScope = GlobalTracer.get().buildSpan("child").startActive(true) + + then: + get(CorrelationIdentifier.getTraceIdKey()) == CorrelationIdentifier.getTraceId() + get(CorrelationIdentifier.getSpanIdKey()) == CorrelationIdentifier.getSpanId() + get("foo") == "bar" + + when: + childScope.close() + + then: + get(CorrelationIdentifier.getTraceIdKey()) == CorrelationIdentifier.getTraceId() + get(CorrelationIdentifier.getSpanIdKey()) == CorrelationIdentifier.getSpanId() + get("foo") == "bar" + + when: + rootScope.close() + + then: + get(CorrelationIdentifier.getTraceIdKey()) == null + get(CorrelationIdentifier.getSpanIdKey()) == null + get("foo") == "bar" + } + + def "Log context is scoped by thread"() { + setup: + ConfigUtils.updateConfig { + System.setProperty("dd.logs.injection", "true") + } + AtomicReference thread1TraceId = new AtomicReference<>() + AtomicReference thread2TraceId = new AtomicReference<>() + + final Thread thread1 = new Thread() { + @Override + void run() { + // no trace in scope + thread1TraceId.set(get(CorrelationIdentifier.getTraceIdKey())) + } + } + + final Thread thread2 = new Thread() { + @Override + void run() { + // other trace in scope + final Scope thread2Scope = GlobalTracer.get().buildSpan("root2").startActive(true) + try { + thread2TraceId.set(get(CorrelationIdentifier.getTraceIdKey())) + } finally { + thread2Scope.close() + } + } + } + final Scope mainScope = GlobalTracer.get().buildSpan("root").startActive(true) + thread1.start() + thread2.start() + final String mainThreadTraceId = get(CorrelationIdentifier.getTraceIdKey()) + final String expectedMainThreadTraceId = CorrelationIdentifier.getTraceId() + + thread1.join() + thread2.join() + + expect: + mainThreadTraceId == expectedMainThreadTraceId + thread1TraceId.get() == null + thread2TraceId.get() != null + thread2TraceId.get() != mainThreadTraceId + + cleanup: + mainScope?.close() + } +} From b7393df4733baba14e4ed7a3ea32d8e62d419f75 Mon Sep 17 00:00:00 2001 From: Luca Abbati Date: Thu, 20 Jun 2019 18:23:40 -0400 Subject: [PATCH 09/16] Remove jms functionality brought in by log4j1.X dependency --- dd-java-agent/instrumentation/log4j1/log4j1.gradle | 3 +++ 1 file changed, 3 insertions(+) diff --git a/dd-java-agent/instrumentation/log4j1/log4j1.gradle b/dd-java-agent/instrumentation/log4j1/log4j1.gradle index 33ff242c80a..5111cffb759 100644 --- a/dd-java-agent/instrumentation/log4j1/log4j1.gradle +++ b/dd-java-agent/instrumentation/log4j1/log4j1.gradle @@ -17,6 +17,9 @@ configurations { // dependency brought in by :dd-java-agent:testing over 'log4j-over-slf4j' which would shadow // the log4j module under test using a proxy to slf4j instead. testCompile.exclude group: 'org.slf4j', module: 'log4j-over-slf4j' + + // See: https://stackoverflow.com/a/9047963/2749853 + testCompile.exclude group: 'javax.jms', module: 'jms' } dependencies { From cba8ba122125905ded7ff1be2aa10259306ac0ee Mon Sep 17 00:00:00 2001 From: Luca Abbati Date: Thu, 20 Jun 2019 18:38:00 -0400 Subject: [PATCH 10/16] Refactor classes of log injection services to improve readability --- dd-java-agent/instrumentation/log4j1/log4j1.gradle | 4 ++-- .../log4j1/Log4j1MDCInstrumentation.java | 14 +++++++++----- .../log4j1/src/test/groovy/Log4j1MDCTest.groovy | 4 ++-- dd-java-agent/instrumentation/log4j2/log4j2.gradle | 4 ++-- .../src/test/groovy/Log4jThreadContextTest.groovy | 4 ++-- .../slf4j-mdc/src/test/groovy/Slf4jMDCTest.groovy | 4 ++-- ...nTest.groovy => LogContextInjectionTest.groovy} | 7 ++++--- 7 files changed, 23 insertions(+), 18 deletions(-) rename dd-java-agent/testing/src/main/groovy/datadog/trace/agent/test/log/injection/{LogContextContextInjectionTest.groovy => LogContextInjectionTest.groovy} (93%) diff --git a/dd-java-agent/instrumentation/log4j1/log4j1.gradle b/dd-java-agent/instrumentation/log4j1/log4j1.gradle index 5111cffb759..a69b9a67607 100644 --- a/dd-java-agent/instrumentation/log4j1/log4j1.gradle +++ b/dd-java-agent/instrumentation/log4j1/log4j1.gradle @@ -13,8 +13,8 @@ muzzle { } configurations { - // In order to test the real log4j library we need to remove the log4j transitive dependency - // dependency brought in by :dd-java-agent:testing over 'log4j-over-slf4j' which would shadow + // In order to test the real log4j library we need to remove the log4j transitive + // dependency 'log4j-over-slf4j' brought in by :dd-java-agent:testing which would shadow // the log4j module under test using a proxy to slf4j instead. testCompile.exclude group: 'org.slf4j', module: 'log4j-over-slf4j' diff --git a/dd-java-agent/instrumentation/log4j1/src/main/java/datadog/trace/instrumentation/log4j1/Log4j1MDCInstrumentation.java b/dd-java-agent/instrumentation/log4j1/src/main/java/datadog/trace/instrumentation/log4j1/Log4j1MDCInstrumentation.java index 16c71a1b8bc..30800f335b8 100644 --- a/dd-java-agent/instrumentation/log4j1/src/main/java/datadog/trace/instrumentation/log4j1/Log4j1MDCInstrumentation.java +++ b/dd-java-agent/instrumentation/log4j1/src/main/java/datadog/trace/instrumentation/log4j1/Log4j1MDCInstrumentation.java @@ -9,8 +9,10 @@ import datadog.trace.agent.tooling.log.LogContextScopeListener; import datadog.trace.api.Config; import datadog.trace.api.GlobalTracer; + import java.lang.reflect.Method; import java.util.Map; + import net.bytebuddy.asm.Advice; import net.bytebuddy.description.method.MethodDescription; import net.bytebuddy.description.type.TypeDescription; @@ -41,22 +43,24 @@ public Map, String> transfor @Override public String[] helperClassNames() { - return new String[] {LogContextScopeListener.class.getName()}; + return new String[]{LogContextScopeListener.class.getName()}; } public static class MDCContextAdvice { @Advice.OnMethodExit(suppress = Throwable.class) public static void mdcClassInitialized(@Advice.This Object instance) { - try { - if (instance == null) { - return; - } + if (instance == null) { + return; + } + try { Class mdcClass = instance.getClass(); final Method putMethod = mdcClass.getMethod("put", String.class, Object.class); final Method removeMethod = mdcClass.getMethod("remove", String.class); GlobalTracer.get().addScopeListener(new LogContextScopeListener(putMethod, removeMethod)); } catch (final NoSuchMethodException e) { + org.slf4j.LoggerFactory.getLogger(instance.getClass()) + .debug("Failed to add log4j ThreadContext span listener", e); } } } diff --git a/dd-java-agent/instrumentation/log4j1/src/test/groovy/Log4j1MDCTest.groovy b/dd-java-agent/instrumentation/log4j1/src/test/groovy/Log4j1MDCTest.groovy index 0ae31b166f4..da8de315da7 100644 --- a/dd-java-agent/instrumentation/log4j1/src/test/groovy/Log4j1MDCTest.groovy +++ b/dd-java-agent/instrumentation/log4j1/src/test/groovy/Log4j1MDCTest.groovy @@ -1,7 +1,7 @@ -import datadog.trace.agent.test.log.injection.LogContextContextInjectionTest +import datadog.trace.agent.test.log.injection.LogContextInjectionTest import org.apache.log4j.MDC -class Log4j1MDCTest extends LogContextContextInjectionTest { +class Log4j1MDCTest extends LogContextInjectionTest { @Override def put(String key, Object value) { diff --git a/dd-java-agent/instrumentation/log4j2/log4j2.gradle b/dd-java-agent/instrumentation/log4j2/log4j2.gradle index c92bad8cf6e..64cdf0ecc47 100644 --- a/dd-java-agent/instrumentation/log4j2/log4j2.gradle +++ b/dd-java-agent/instrumentation/log4j2/log4j2.gradle @@ -5,8 +5,8 @@ ext { } configurations { - // In order to test the real log4j library we need to remove the log4j transitive dependency - // dependency brought in by :dd-java-agent:testing over 'log4j-over-slf4j' which would shadow + // In order to test the real log4j library we need to remove the log4j transitive + // dependency 'log4j-over-slf4j' brought in by :dd-java-agent:testing which would shadow // the log4j module under test using a proxy to slf4j instead. testCompile.exclude group: 'org.slf4j', module: 'log4j-over-slf4j' } diff --git a/dd-java-agent/instrumentation/log4j2/src/test/groovy/Log4jThreadContextTest.groovy b/dd-java-agent/instrumentation/log4j2/src/test/groovy/Log4jThreadContextTest.groovy index 6ee8cfb1b61..c881bbadf20 100644 --- a/dd-java-agent/instrumentation/log4j2/src/test/groovy/Log4jThreadContextTest.groovy +++ b/dd-java-agent/instrumentation/log4j2/src/test/groovy/Log4jThreadContextTest.groovy @@ -1,7 +1,7 @@ -import datadog.trace.agent.test.log.injection.LogContextContextInjectionTest +import datadog.trace.agent.test.log.injection.LogContextInjectionTest import org.apache.logging.log4j.ThreadContext -class Log4jThreadContextTest extends LogContextContextInjectionTest { +class Log4jThreadContextTest extends LogContextInjectionTest { @Override def put(String key, Object value) { diff --git a/dd-java-agent/instrumentation/slf4j-mdc/src/test/groovy/Slf4jMDCTest.groovy b/dd-java-agent/instrumentation/slf4j-mdc/src/test/groovy/Slf4jMDCTest.groovy index f0c9f83327b..57a850e071c 100644 --- a/dd-java-agent/instrumentation/slf4j-mdc/src/test/groovy/Slf4jMDCTest.groovy +++ b/dd-java-agent/instrumentation/slf4j-mdc/src/test/groovy/Slf4jMDCTest.groovy @@ -1,7 +1,7 @@ -import datadog.trace.agent.test.log.injection.LogContextContextInjectionTest +import datadog.trace.agent.test.log.injection.LogContextInjectionTest import org.slf4j.MDC -class Slf4jMDCTest extends LogContextContextInjectionTest { +class Slf4jMDCTest extends LogContextInjectionTest { @Override def put(String key, Object value) { diff --git a/dd-java-agent/testing/src/main/groovy/datadog/trace/agent/test/log/injection/LogContextContextInjectionTest.groovy b/dd-java-agent/testing/src/main/groovy/datadog/trace/agent/test/log/injection/LogContextInjectionTest.groovy similarity index 93% rename from dd-java-agent/testing/src/main/groovy/datadog/trace/agent/test/log/injection/LogContextContextInjectionTest.groovy rename to dd-java-agent/testing/src/main/groovy/datadog/trace/agent/test/log/injection/LogContextInjectionTest.groovy index 91eb618c60e..b709ba271a5 100644 --- a/dd-java-agent/testing/src/main/groovy/datadog/trace/agent/test/log/injection/LogContextContextInjectionTest.groovy +++ b/dd-java-agent/testing/src/main/groovy/datadog/trace/agent/test/log/injection/LogContextInjectionTest.groovy @@ -9,9 +9,10 @@ import io.opentracing.util.GlobalTracer import java.util.concurrent.atomic.AtomicReference /** - * This class represents the standard test cases that new logging library integration MUST satisfy in order to support log injection. + * This class represents the standard test cases that new logging library integrations MUST + * satisfy in order to support log injection. */ -abstract class LogContextContextInjectionTest extends AgentTestRunner { +abstract class LogContextInjectionTest extends AgentTestRunner { /** * Set in the framework-specific context the given value at the given key @@ -19,7 +20,7 @@ abstract class LogContextContextInjectionTest extends AgentTestRunner { abstract put(String key, Object value) /** - * Get from the framework-specific context the given value at the given key + * Get from the framework-specific context the value at the given key */ abstract get(String key) From 27b4db8861bee2eec16b8e40d38ddab8ffa908f3 Mon Sep 17 00:00:00 2001 From: Luca Abbati Date: Thu, 20 Jun 2019 21:29:46 -0400 Subject: [PATCH 11/16] Remove legacy transitive dependencies no longer bundled with the JVM from muzzle tests --- buildSrc/src/main/groovy/MuzzlePlugin.groovy | 10 ++++++++-- .../log4j1/Log4j1MDCInstrumentation.java | 6 ++---- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/buildSrc/src/main/groovy/MuzzlePlugin.groovy b/buildSrc/src/main/groovy/MuzzlePlugin.groovy index e62679f21e3..ce31a4bd6a5 100644 --- a/buildSrc/src/main/groovy/MuzzlePlugin.groovy +++ b/buildSrc/src/main/groovy/MuzzlePlugin.groovy @@ -263,9 +263,15 @@ class MuzzlePlugin implements Plugin { private static Task addMuzzleTask(MuzzleDirective muzzleDirective, Artifact versionArtifact, Project instrumentationProject, Task runAfter, Project bootstrapProject, Project toolingProject) { def taskName = "muzzle-Assert${muzzleDirective.assertPass ? "Pass" : "Fail"}-$versionArtifact.groupId-$versionArtifact.artifactId-$versionArtifact.version${muzzleDirective.name ? "-${muzzleDirective.getNameSlug()}" : ""}" def config = instrumentationProject.configurations.create(taskName) - config.dependencies.add(instrumentationProject.dependencies.create("$versionArtifact.groupId:$versionArtifact.artifactId:$versionArtifact.version") { + def dep = instrumentationProject.dependencies.create("$versionArtifact.groupId:$versionArtifact.artifactId:$versionArtifact.version") { transitive = true - }) + } + // The following optional transitive dependencies are brought in by some legacy module such as log4j 1.x but are no + // longer bundled with the JVM and have to be excluded for the muzzle tests to be able to run. + dep.exclude group: 'com.sun.jdmk', module: 'jmxtools' + dep.exclude group: 'com.sun.jmx', module: 'jmxri' + + config.dependencies.add(dep) for (String additionalDependency : muzzleDirective.additionalDependencies) { config.dependencies.add(instrumentationProject.dependencies.create(additionalDependency) { transitive = true diff --git a/dd-java-agent/instrumentation/log4j1/src/main/java/datadog/trace/instrumentation/log4j1/Log4j1MDCInstrumentation.java b/dd-java-agent/instrumentation/log4j1/src/main/java/datadog/trace/instrumentation/log4j1/Log4j1MDCInstrumentation.java index 30800f335b8..6aa4d60acb3 100644 --- a/dd-java-agent/instrumentation/log4j1/src/main/java/datadog/trace/instrumentation/log4j1/Log4j1MDCInstrumentation.java +++ b/dd-java-agent/instrumentation/log4j1/src/main/java/datadog/trace/instrumentation/log4j1/Log4j1MDCInstrumentation.java @@ -9,10 +9,8 @@ import datadog.trace.agent.tooling.log.LogContextScopeListener; import datadog.trace.api.Config; import datadog.trace.api.GlobalTracer; - import java.lang.reflect.Method; import java.util.Map; - import net.bytebuddy.asm.Advice; import net.bytebuddy.description.method.MethodDescription; import net.bytebuddy.description.type.TypeDescription; @@ -43,7 +41,7 @@ public Map, String> transfor @Override public String[] helperClassNames() { - return new String[]{LogContextScopeListener.class.getName()}; + return new String[] {LogContextScopeListener.class.getName()}; } public static class MDCContextAdvice { @@ -60,7 +58,7 @@ public static void mdcClassInitialized(@Advice.This Object instance) { GlobalTracer.get().addScopeListener(new LogContextScopeListener(putMethod, removeMethod)); } catch (final NoSuchMethodException e) { org.slf4j.LoggerFactory.getLogger(instance.getClass()) - .debug("Failed to add log4j ThreadContext span listener", e); + .debug("Failed to add log4j ThreadContext span listener", e); } } } From 0916a00a5e7ad29fbb01d773d949b5cb9eadf4f0 Mon Sep 17 00:00:00 2001 From: Luca Abbati Date: Thu, 20 Jun 2019 21:42:50 -0400 Subject: [PATCH 12/16] Fixed unnecessary semi-colon in groovy class --- .../agent/test/log/injection/LogContextInjectionTest.groovy | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dd-java-agent/testing/src/main/groovy/datadog/trace/agent/test/log/injection/LogContextInjectionTest.groovy b/dd-java-agent/testing/src/main/groovy/datadog/trace/agent/test/log/injection/LogContextInjectionTest.groovy index b709ba271a5..e171701d1d3 100644 --- a/dd-java-agent/testing/src/main/groovy/datadog/trace/agent/test/log/injection/LogContextInjectionTest.groovy +++ b/dd-java-agent/testing/src/main/groovy/datadog/trace/agent/test/log/injection/LogContextInjectionTest.groovy @@ -1,4 +1,4 @@ -package datadog.trace.agent.test.log.injection; +package datadog.trace.agent.test.log.injection import datadog.trace.agent.test.AgentTestRunner import datadog.trace.agent.test.utils.ConfigUtils From d0f17e4b9d202cb0016273188fada38c36f8f896 Mon Sep 17 00:00:00 2001 From: Luca Abbati Date: Fri, 21 Jun 2019 08:54:13 -0400 Subject: [PATCH 13/16] Rename log context injection test base --- .../log4j1/src/test/groovy/Log4j1MDCTest.groovy | 4 ++-- .../log4j2/src/test/groovy/Log4jThreadContextTest.groovy | 4 ++-- .../slf4j-mdc/src/test/groovy/Slf4jMDCTest.groovy | 4 ++-- ...njectionTest.groovy => LogContextInjectionTestBase.groovy} | 2 +- 4 files changed, 7 insertions(+), 7 deletions(-) rename dd-java-agent/testing/src/main/groovy/datadog/trace/agent/test/log/injection/{LogContextInjectionTest.groovy => LogContextInjectionTestBase.groovy} (97%) diff --git a/dd-java-agent/instrumentation/log4j1/src/test/groovy/Log4j1MDCTest.groovy b/dd-java-agent/instrumentation/log4j1/src/test/groovy/Log4j1MDCTest.groovy index da8de315da7..24a9c3264ee 100644 --- a/dd-java-agent/instrumentation/log4j1/src/test/groovy/Log4j1MDCTest.groovy +++ b/dd-java-agent/instrumentation/log4j1/src/test/groovy/Log4j1MDCTest.groovy @@ -1,7 +1,7 @@ -import datadog.trace.agent.test.log.injection.LogContextInjectionTest +import datadog.trace.agent.test.log.injection.LogContextInjectionTestBase import org.apache.log4j.MDC -class Log4j1MDCTest extends LogContextInjectionTest { +class Log4j1MDCTest extends LogContextInjectionTestBase { @Override def put(String key, Object value) { diff --git a/dd-java-agent/instrumentation/log4j2/src/test/groovy/Log4jThreadContextTest.groovy b/dd-java-agent/instrumentation/log4j2/src/test/groovy/Log4jThreadContextTest.groovy index c881bbadf20..9dacdb7a0a1 100644 --- a/dd-java-agent/instrumentation/log4j2/src/test/groovy/Log4jThreadContextTest.groovy +++ b/dd-java-agent/instrumentation/log4j2/src/test/groovy/Log4jThreadContextTest.groovy @@ -1,7 +1,7 @@ -import datadog.trace.agent.test.log.injection.LogContextInjectionTest +import datadog.trace.agent.test.log.injection.LogContextInjectionTestBase import org.apache.logging.log4j.ThreadContext -class Log4jThreadContextTest extends LogContextInjectionTest { +class Log4jThreadContextTest extends LogContextInjectionTestBase { @Override def put(String key, Object value) { diff --git a/dd-java-agent/instrumentation/slf4j-mdc/src/test/groovy/Slf4jMDCTest.groovy b/dd-java-agent/instrumentation/slf4j-mdc/src/test/groovy/Slf4jMDCTest.groovy index 57a850e071c..c83b658ad4e 100644 --- a/dd-java-agent/instrumentation/slf4j-mdc/src/test/groovy/Slf4jMDCTest.groovy +++ b/dd-java-agent/instrumentation/slf4j-mdc/src/test/groovy/Slf4jMDCTest.groovy @@ -1,7 +1,7 @@ -import datadog.trace.agent.test.log.injection.LogContextInjectionTest +import datadog.trace.agent.test.log.injection.LogContextInjectionTestBase import org.slf4j.MDC -class Slf4jMDCTest extends LogContextInjectionTest { +class Slf4jMDCTest extends LogContextInjectionTestBase { @Override def put(String key, Object value) { diff --git a/dd-java-agent/testing/src/main/groovy/datadog/trace/agent/test/log/injection/LogContextInjectionTest.groovy b/dd-java-agent/testing/src/main/groovy/datadog/trace/agent/test/log/injection/LogContextInjectionTestBase.groovy similarity index 97% rename from dd-java-agent/testing/src/main/groovy/datadog/trace/agent/test/log/injection/LogContextInjectionTest.groovy rename to dd-java-agent/testing/src/main/groovy/datadog/trace/agent/test/log/injection/LogContextInjectionTestBase.groovy index e171701d1d3..1eee80b584e 100644 --- a/dd-java-agent/testing/src/main/groovy/datadog/trace/agent/test/log/injection/LogContextInjectionTest.groovy +++ b/dd-java-agent/testing/src/main/groovy/datadog/trace/agent/test/log/injection/LogContextInjectionTestBase.groovy @@ -12,7 +12,7 @@ import java.util.concurrent.atomic.AtomicReference * This class represents the standard test cases that new logging library integrations MUST * satisfy in order to support log injection. */ -abstract class LogContextInjectionTest extends AgentTestRunner { +abstract class LogContextInjectionTestBase extends AgentTestRunner { /** * Set in the framework-specific context the given value at the given key From ac7abcdfa84710430eb455f0d57c989ad5108a6e Mon Sep 17 00:00:00 2001 From: Luca Abbati Date: Fri, 21 Jun 2019 15:52:20 -0400 Subject: [PATCH 14/16] Fix expression to include tracing of log4j1 MDC in agent installer --- .../main/java/datadog/trace/agent/tooling/AgentInstaller.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/dd-java-agent/agent-tooling/src/main/java/datadog/trace/agent/tooling/AgentInstaller.java b/dd-java-agent/agent-tooling/src/main/java/datadog/trace/agent/tooling/AgentInstaller.java index 2e08c127cdf..b51197d4ada 100644 --- a/dd-java-agent/agent-tooling/src/main/java/datadog/trace/agent/tooling/AgentInstaller.java +++ b/dd-java-agent/agent-tooling/src/main/java/datadog/trace/agent/tooling/AgentInstaller.java @@ -127,8 +127,7 @@ public static ResettableClassFileTransformer installBytebuddyAgent( .or(nameStartsWith("com.singularity.")) .or(nameStartsWith("com.jinspired.")) .or(nameStartsWith("org.jinspired.")) - .or(nameStartsWith("org.apache.log4j.")) - .and(not(named("org.apache.log4j.MDC"))) + .or(nameStartsWith("org.apache.log4j.").and(not(named("org.apache.log4j.MDC")))) .or(nameStartsWith("org.slf4j.").and(not(named("org.slf4j.MDC")))) .or(nameContains("$JaxbAccessor")) .or(nameContains("CGLIB$$")) From f279a612f737ea5616690317197ccac4bf688585 Mon Sep 17 00:00:00 2001 From: Luca Abbati Date: Fri, 21 Jun 2019 15:53:13 -0400 Subject: [PATCH 15/16] Minor fixes to typos and code styles --- dd-java-agent/instrumentation/log4j2/log4j2.gradle | 5 ++--- dd-java-agent/testing/testing.gradle | 1 + gradle/jacoco.gradle | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/dd-java-agent/instrumentation/log4j2/log4j2.gradle b/dd-java-agent/instrumentation/log4j2/log4j2.gradle index 64cdf0ecc47..7130100cfc6 100644 --- a/dd-java-agent/instrumentation/log4j2/log4j2.gradle +++ b/dd-java-agent/instrumentation/log4j2/log4j2.gradle @@ -29,13 +29,12 @@ dependencies { compile project(':dd-trace-api') compile project(':dd-java-agent:agent-tooling') - testCompile group: 'org.apache.logging.log4j', name: 'log4j-core', version: log4jVersion - testCompile group: 'org.apache.logging.log4j', name: 'log4j-api', version: log4jVersion - compile deps.bytebuddy compile deps.opentracing annotationProcessor deps.autoservice implementation deps.autoservice testCompile project(':dd-java-agent:testing') + testCompile group: 'org.apache.logging.log4j', name: 'log4j-core', version: log4jVersion + testCompile group: 'org.apache.logging.log4j', name: 'log4j-api', version: log4jVersion } diff --git a/dd-java-agent/testing/testing.gradle b/dd-java-agent/testing/testing.gradle index 4a951232a60..5fe8b9f022c 100644 --- a/dd-java-agent/testing/testing.gradle +++ b/dd-java-agent/testing/testing.gradle @@ -5,6 +5,7 @@ minimumInstructionCoverage = 0.5 excludedClassesCoverage += [ 'datadog.trace.agent.test.asserts.*Assert', 'datadog.trace.agent.test.base.*', + 'datadog.trace.agent.test.log.*', 'datadog.trace.agent.test.AgentTestRunner.ErrorCountingListener', 'datadog.trace.agent.test.utils.*', // Avoid applying jacoco instrumentation to classes instrumented by tested agent diff --git a/gradle/jacoco.gradle b/gradle/jacoco.gradle index e946702d49f..b77294005ae 100644 --- a/gradle/jacoco.gradle +++ b/gradle/jacoco.gradle @@ -32,7 +32,7 @@ project.ext.minimumInstructionCoverage = 0.9 afterEvaluate { test { jacoco { - // Make sure that excluded classes do not get jacoc instrumentation applied since it may confuse apm agent in some cases + // Make sure that excluded classes do not get jacoco instrumentation applied since it may confuse apm agent in some cases excludes = project.excludedClassesCoverage } } From 8ee6d26d15d721c0af650cb69ad75582df9d0190 Mon Sep 17 00:00:00 2001 From: Luca Abbati Date: Fri, 21 Jun 2019 15:56:27 -0400 Subject: [PATCH 16/16] Rename log4j 1 and 2 instrumentation to log4j1 and log4j2 respectively --- .../trace/instrumentation/log4j1/Log4j1MDCInstrumentation.java | 2 +- .../instrumentation/log4j2/ThreadContextInstrumentation.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/dd-java-agent/instrumentation/log4j1/src/main/java/datadog/trace/instrumentation/log4j1/Log4j1MDCInstrumentation.java b/dd-java-agent/instrumentation/log4j1/src/main/java/datadog/trace/instrumentation/log4j1/Log4j1MDCInstrumentation.java index 6aa4d60acb3..2e970b08d9b 100644 --- a/dd-java-agent/instrumentation/log4j1/src/main/java/datadog/trace/instrumentation/log4j1/Log4j1MDCInstrumentation.java +++ b/dd-java-agent/instrumentation/log4j1/src/main/java/datadog/trace/instrumentation/log4j1/Log4j1MDCInstrumentation.java @@ -18,7 +18,7 @@ @AutoService(Instrumenter.class) public class Log4j1MDCInstrumentation extends Instrumenter.Default { - public static final String MDC_INSTRUMENTATION_NAME = "log4j-mdc"; + public static final String MDC_INSTRUMENTATION_NAME = "log4j1"; public Log4j1MDCInstrumentation() { super(MDC_INSTRUMENTATION_NAME); diff --git a/dd-java-agent/instrumentation/log4j2/src/main/java/datadog/trace/instrumentation/log4j2/ThreadContextInstrumentation.java b/dd-java-agent/instrumentation/log4j2/src/main/java/datadog/trace/instrumentation/log4j2/ThreadContextInstrumentation.java index 8713182292b..954526a9d06 100644 --- a/dd-java-agent/instrumentation/log4j2/src/main/java/datadog/trace/instrumentation/log4j2/ThreadContextInstrumentation.java +++ b/dd-java-agent/instrumentation/log4j2/src/main/java/datadog/trace/instrumentation/log4j2/ThreadContextInstrumentation.java @@ -18,7 +18,7 @@ @AutoService(Instrumenter.class) public class ThreadContextInstrumentation extends Instrumenter.Default { - public static final String MDC_INSTRUMENTATION_NAME = "log4j-thread-context"; + public static final String MDC_INSTRUMENTATION_NAME = "log4j"; public ThreadContextInstrumentation() { super(MDC_INSTRUMENTATION_NAME);