diff --git a/instrumentation/log4j/log4j-2.13.2/testing/log4j-2.13.2-testing.gradle b/instrumentation/log4j/log4j-2-testing/log4j-2-testing.gradle similarity index 88% rename from instrumentation/log4j/log4j-2.13.2/testing/log4j-2.13.2-testing.gradle rename to instrumentation/log4j/log4j-2-testing/log4j-2-testing.gradle index 415b8b11b1c0..cb1c03ca2dd8 100644 --- a/instrumentation/log4j/log4j-2.13.2/testing/log4j-2.13.2-testing.gradle +++ b/instrumentation/log4j/log4j-2-testing/log4j-2-testing.gradle @@ -3,7 +3,7 @@ apply from: "$rootDir/gradle/java.gradle" dependencies { api project(':testing-common') - api group: 'org.apache.logging.log4j', name: 'log4j-core', version: '2.13.2' + api group: 'org.apache.logging.log4j', name: 'log4j-core', version: '2.7' implementation deps.guava @@ -11,5 +11,5 @@ dependencies { implementation deps.opentelemetryApi implementation deps.spock - annotationProcessor group: 'org.apache.logging.log4j', name: 'log4j-core', version: '2.13.2' + annotationProcessor group: 'org.apache.logging.log4j', name: 'log4j-core', version: '2.7' } diff --git a/instrumentation/log4j/log4j-2.13.2/testing/src/main/groovy/Log4j2Test.groovy b/instrumentation/log4j/log4j-2-testing/src/main/groovy/Log4j2Test.groovy similarity index 100% rename from instrumentation/log4j/log4j-2.13.2/testing/src/main/groovy/Log4j2Test.groovy rename to instrumentation/log4j/log4j-2-testing/src/main/groovy/Log4j2Test.groovy diff --git a/instrumentation/log4j/log4j-2.13.2/testing/src/main/java/io/opentelemetry/instrumentation/log4j/v2_13_2/ListAppender.java b/instrumentation/log4j/log4j-2-testing/src/main/java/io/opentelemetry/instrumentation/log4j/v2_13_2/ListAppender.java similarity index 90% rename from instrumentation/log4j/log4j-2.13.2/testing/src/main/java/io/opentelemetry/instrumentation/log4j/v2_13_2/ListAppender.java rename to instrumentation/log4j/log4j-2-testing/src/main/java/io/opentelemetry/instrumentation/log4j/v2_13_2/ListAppender.java index 514e1404f219..a5b8b65e60e9 100644 --- a/instrumentation/log4j/log4j-2.13.2/testing/src/main/java/io/opentelemetry/instrumentation/log4j/v2_13_2/ListAppender.java +++ b/instrumentation/log4j/log4j-2-testing/src/main/java/io/opentelemetry/instrumentation/log4j/v2_13_2/ListAppender.java @@ -20,17 +20,15 @@ import java.util.Collections; import java.util.List; import org.apache.logging.log4j.core.Appender; -import org.apache.logging.log4j.core.Core; import org.apache.logging.log4j.core.LogEvent; import org.apache.logging.log4j.core.appender.AbstractAppender; -import org.apache.logging.log4j.core.config.Property; import org.apache.logging.log4j.core.config.plugins.Plugin; import org.apache.logging.log4j.core.config.plugins.PluginAttribute; import org.apache.logging.log4j.core.config.plugins.PluginFactory; @Plugin( name = "ListAppender", - category = Core.CATEGORY_NAME, + category = "Core", elementType = Appender.ELEMENT_TYPE, printObject = true) public class ListAppender extends AbstractAppender { @@ -44,7 +42,7 @@ public static ListAppender get() { private final List events = Collections.synchronizedList(new ArrayList()); public ListAppender() { - super("ListAppender", null, null, true, Property.EMPTY_ARRAY); + super("ListAppender", null, null, true); } public List getEvents() { diff --git a/instrumentation/log4j/log4j-2.13.2/testing/src/main/resources/log4j2-test.xml b/instrumentation/log4j/log4j-2-testing/src/main/resources/log4j2-test.xml similarity index 100% rename from instrumentation/log4j/log4j-2.13.2/testing/src/main/resources/log4j2-test.xml rename to instrumentation/log4j/log4j-2-testing/src/main/resources/log4j2-test.xml diff --git a/instrumentation/log4j/log4j-2.13.2/auto/log4j-2.13.2-auto.gradle b/instrumentation/log4j/log4j-2.13.2/auto/log4j-2.13.2-auto.gradle index d63e3d94c063..3354b39b0941 100644 --- a/instrumentation/log4j/log4j-2.13.2/auto/log4j-2.13.2-auto.gradle +++ b/instrumentation/log4j/log4j-2.13.2/auto/log4j-2.13.2-auto.gradle @@ -14,5 +14,5 @@ dependencies { implementation project(':instrumentation:log4j:log4j-2.13.2:library') - testImplementation project(':instrumentation:log4j:log4j-2.13.2:testing') + testImplementation project(':instrumentation:log4j:log4j-2-testing') } diff --git a/instrumentation/log4j/log4j-2.13.2/auto/src/main/java/io/opentelemetry/instrumentation/auto/log4j/v2_13_2/Log4j2Instrumentation.java b/instrumentation/log4j/log4j-2.13.2/auto/src/main/java/io/opentelemetry/instrumentation/auto/log4j/v2_13_2/Log4j2Instrumentation.java index 75fa183a4510..611d13ef463c 100644 --- a/instrumentation/log4j/log4j-2.13.2/auto/src/main/java/io/opentelemetry/instrumentation/auto/log4j/v2_13_2/Log4j2Instrumentation.java +++ b/instrumentation/log4j/log4j-2.13.2/auto/src/main/java/io/opentelemetry/instrumentation/auto/log4j/v2_13_2/Log4j2Instrumentation.java @@ -40,7 +40,7 @@ @AutoService(Instrumenter.class) public final class Log4j2Instrumentation extends Instrumenter.Default { public Log4j2Instrumentation() { - super("log4j2", "log4j"); + super("log4j2", "log4j", "log4j2.13.2"); } @Override diff --git a/instrumentation/log4j/log4j-2.13.2/library/log4j-2.13.2-library.gradle b/instrumentation/log4j/log4j-2.13.2/library/log4j-2.13.2-library.gradle index 12e2338d18e3..2945fa9dd8c8 100644 --- a/instrumentation/log4j/log4j-2.13.2/library/log4j-2.13.2-library.gradle +++ b/instrumentation/log4j/log4j-2.13.2/library/log4j-2.13.2-library.gradle @@ -10,5 +10,5 @@ dependencies { annotationProcessor deps.autoservice compileOnly deps.autoservice - testImplementation project(':instrumentation:log4j:log4j-2.13.2:testing') + testImplementation project(':instrumentation:log4j:log4j-2-testing') } diff --git a/instrumentation/log4j/log4j-2.7/log4j-2.7.gradle b/instrumentation/log4j/log4j-2.7/log4j-2.7.gradle new file mode 100644 index 000000000000..d341732febf8 --- /dev/null +++ b/instrumentation/log4j/log4j-2.7/log4j-2.7.gradle @@ -0,0 +1,15 @@ +apply from: "$rootDir/gradle/instrumentation.gradle" + +muzzle { + pass { + group = "org.apache.logging.log4j" + module = "log4j-core" + versions = "[2.7,2.13.2)" + } +} + +dependencies { + library group: 'org.apache.logging.log4j', name: 'log4j-core', version: '2.7' + + testImplementation project(':instrumentation:log4j:log4j-2-testing') +} diff --git a/instrumentation/log4j/log4j-2.7/src/main/java/io/opentelemetry/instrumentation/auto/log4j/v2_7/Log4j27Instrumentation.java b/instrumentation/log4j/log4j-2.7/src/main/java/io/opentelemetry/instrumentation/auto/log4j/v2_7/Log4j27Instrumentation.java new file mode 100644 index 000000000000..8c4b435d3b68 --- /dev/null +++ b/instrumentation/log4j/log4j-2.7/src/main/java/io/opentelemetry/instrumentation/auto/log4j/v2_7/Log4j27Instrumentation.java @@ -0,0 +1,86 @@ +/* + * Copyright The OpenTelemetry Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.opentelemetry.instrumentation.auto.log4j.v2_7; + +import static io.opentelemetry.javaagent.tooling.ClassLoaderMatcher.hasClassesNamed; +import static io.opentelemetry.javaagent.tooling.bytebuddy.matcher.AgentElementMatchers.implementsInterface; +import static net.bytebuddy.matcher.ElementMatchers.isMethod; +import static net.bytebuddy.matcher.ElementMatchers.named; +import static net.bytebuddy.matcher.ElementMatchers.not; +import static net.bytebuddy.matcher.ElementMatchers.returns; + +import com.google.auto.service.AutoService; +import io.opentelemetry.javaagent.tooling.Instrumenter; +import io.opentelemetry.trace.SpanContext; +import io.opentelemetry.trace.TracingContextUtils; +import java.util.Collections; +import java.util.Map; +import net.bytebuddy.asm.Advice; +import net.bytebuddy.description.method.MethodDescription; +import net.bytebuddy.description.type.TypeDescription; +import net.bytebuddy.implementation.bytecode.assign.Assigner.Typing; +import net.bytebuddy.matcher.ElementMatcher; +import org.apache.logging.log4j.util.SortedArrayStringMap; +import org.apache.logging.log4j.util.StringMap; + +@AutoService(Instrumenter.class) +public class Log4j27Instrumentation extends Instrumenter.Default { + public Log4j27Instrumentation() { + super("log4j2", "log4j", "log4j2.7"); + } + + @Override + public ElementMatcher classLoaderMatcher() { + return not(hasClassesNamed("org.apache.logging.log4j.core.util.ContextDataProvider")); + } + + @Override + public ElementMatcher typeMatcher() { + return implementsInterface(named("org.apache.logging.log4j.core.ContextDataInjector")); + } + + @Override + public Map, String> transformers() { + return Collections.singletonMap( + isMethod() + .and(named("injectContextData")) + .and(returns(named("org.apache.logging.log4j.util.StringMap"))), + Log4j27Instrumentation.class.getName() + "$InjectContextDataAdvice"); + } + + public static class InjectContextDataAdvice { + @Advice.OnMethodExit(suppress = Throwable.class) + public static void onExit( + @Advice.Return(typing = Typing.DYNAMIC, readOnly = false) StringMap contextData) { + SpanContext currentContext = TracingContextUtils.getCurrentSpan().getContext(); + if (!currentContext.isValid()) { + return; + } + + if (contextData.containsKey("traceId")) { + // Assume already instrumented event if traceId is present. + return; + } + + StringMap newContextData = new SortedArrayStringMap(contextData); + newContextData.putValue("traceId", currentContext.getTraceId().toLowerBase16()); + newContextData.putValue("spanId", currentContext.getSpanId().toLowerBase16()); + newContextData.putValue("traceFlags", currentContext.getTraceFlags().toLowerBase16()); + contextData = newContextData; + } + } +} diff --git a/instrumentation/log4j/log4j-2.7/src/test/groovy/Log4j27Test.groovy b/instrumentation/log4j/log4j-2.7/src/test/groovy/Log4j27Test.groovy new file mode 100644 index 000000000000..4761dd9bc276 --- /dev/null +++ b/instrumentation/log4j/log4j-2.7/src/test/groovy/Log4j27Test.groovy @@ -0,0 +1,18 @@ +/* + * Copyright The OpenTelemetry Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +class Log4j27Test extends Log4j2Test { +} diff --git a/settings.gradle b/settings.gradle index cd1dfc629d55..813f1b9f2663 100644 --- a/settings.gradle +++ b/settings.gradle @@ -126,9 +126,10 @@ include ':instrumentation:kubernetes-client-7.0' include ':instrumentation:lettuce:lettuce-4.0' include ':instrumentation:lettuce:lettuce-5.0' include ':instrumentation:lettuce:lettuce-5.1' +include ':instrumentation:log4j:log4j-2.7' include ':instrumentation:log4j:log4j-2.13.2:auto' include ':instrumentation:log4j:log4j-2.13.2:library' -include ':instrumentation:log4j:log4j-2.13.2:testing' +include ':instrumentation:log4j:log4j-2-testing' include ':instrumentation:logback:logback-1.0.0:auto' include ':instrumentation:logback:logback-1.0.0:library' include ':instrumentation:logback:logback-1.0.0:testing'