diff --git a/instrumentation/log4j/log4j-2.0/src/main/java/io/opentelemetry/auto/instrumentation/log4j/v2_0/Log4jSpansInstrumentation.java b/instrumentation/log4j/log4j-2.0/src/main/java/io/opentelemetry/auto/instrumentation/log4j/v2_0/Log4jSpansInstrumentation.java index 5608a3b76570..4bb7291e8a22 100644 --- a/instrumentation/log4j/log4j-2.0/src/main/java/io/opentelemetry/auto/instrumentation/log4j/v2_0/Log4jSpansInstrumentation.java +++ b/instrumentation/log4j/log4j-2.0/src/main/java/io/opentelemetry/auto/instrumentation/log4j/v2_0/Log4jSpansInstrumentation.java @@ -85,12 +85,25 @@ public Map, String> transfor public static class LogMessageAdvice { @Advice.OnMethodEnter(suppress = Throwable.class) - public static void methodEnter( + public static boolean methodEnter( @Advice.This final Logger logger, @Advice.Argument(1) final Level level, @Advice.Argument(3) final Message message, @Advice.Argument(4) final Throwable t) { - Log4jSpans.capture(logger, level, message, t); + // need to track call depth across all loggers in order to avoid double capture when one + // logging framework delegates to another + final boolean topLevel = CallDepthThreadLocalMap.incrementCallDepth("logger") == 0; + if (topLevel) { + Log4jSpans.capture(logger, level, message, t); + } + return topLevel; + } + + @Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class) + public static void methodExit(@Advice.Enter final boolean topLevel) { + if (topLevel) { + CallDepthThreadLocalMap.reset("logger"); + } } }