Skip to content

Commit c2be6d3

Browse files
authored
Fixing log4j configuration initialization (#2343)
1 parent e4a02a0 commit c2be6d3

File tree

4 files changed

+41
-3
lines changed

4 files changed

+41
-3
lines changed

CHANGELOG.asciidoc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ endif::[]
3333
[float]
3434
===== Bug fixes
3535
* Fix module loading errors on J9 JVM - {pull}2341[#2341]
36+
* Fixing log4j configuration error - {pull}2343[#2343]
3637
3738
[[release-notes-1.x]]
3839
=== Java Agent version 1.x

apm-agent-core/src/main/java/co/elastic/apm/agent/logging/LoggingConfiguration.java

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
import co.elastic.apm.agent.matcher.WildcardMatcher;
2424
import co.elastic.apm.agent.matcher.WildcardMatcherValueConverter;
2525
import org.apache.logging.log4j.Level;
26+
import org.apache.logging.log4j.core.config.ConfigurationFactory;
2627
import org.apache.logging.log4j.core.config.Configurator;
2728
import org.apache.logging.log4j.status.StatusLogger;
2829
import org.stagemonitor.configuration.ConfigurationOption;
@@ -300,16 +301,22 @@ public void assertValid(Boolean value) {
300301
public static void init(List<ConfigurationSource> sources, String ephemeralId) {
301302
// The initialization of log4j may produce errors if the traced application uses log4j settings (for
302303
// example - through file in the classpath or System properties) that configures specific properties for
303-
// loading classes by name. Since we shade our usage of log4j, such non-shaded classes may not (and should not)
304-
// be found on the classpath.
304+
// loading custom classes by name, which may not be found within the agent ClassLoader's classpath.
305305
// All handled Exceptions should not prevent us from using log4j further, as the system falls back to a default
306306
// which we expect anyway. We take a calculated risk of ignoring such errors only through initialization time,
307307
// assuming that errors that will make the logging system non-usable won't be handled.
308308
String initialListenersLevel = System.setProperty(INITIAL_LISTENERS_LEVEL, "OFF");
309309
String initialStatusLoggerLevel = System.setProperty(INITIAL_STATUS_LOGGER_LEVEL, "OFF");
310310
String defaultListenerLevel = System.setProperty(DEFAULT_LISTENER_LEVEL, "OFF");
311311
try {
312-
Configurator.initialize(new Log4j2ConfigurationFactory(sources, ephemeralId).getConfiguration());
312+
// org.apache.logging.log4j.core.config.ConfigurationFactory is a singleton that allows overriding its instance
313+
// through setConfigurationFactory. This API is not considered thread safe, but since we do it so early on when
314+
// there is only the main thread it should be OK. Once we override the default factory instance, any logger
315+
// created thereafter will be configured through our custom factory, regardless of its context.
316+
// Initializing only per context (the caller class loader by default, can be changed to thread or other), for
317+
// example through org.apache.logging.log4j.core.config.Configurator, means that loggers in non-initialized
318+
// contexts will either get the app-configuration for log4j, if such exists, or none.
319+
ConfigurationFactory.setConfigurationFactory(new Log4j2ConfigurationFactory(sources, ephemeralId));
313320
} catch (Throwable throwable) {
314321
System.err.println("[elastic-apm-agent] ERROR Failure during initialization of agent's log4j system: " + throwable.getMessage());
315322
} finally {

apm-agent-plugins/apm-log-shader-plugin/apm-log4j2-plugin/src/test/java/co/elastic/apm/agent/log4j2/LegacyLog4j2ShadingTest.java

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,12 +19,17 @@
1919
package co.elastic.apm.agent.log4j2;
2020

2121
import co.elastic.apm.agent.TestClassWithDependencyRunner;
22+
import co.elastic.apm.agent.logging.LoggingConfiguration;
23+
import org.apache.logging.log4j.core.config.ConfigurationFactory;
2224
import org.junit.After;
25+
import org.junit.AfterClass;
2326
import org.junit.Before;
27+
import org.junit.BeforeClass;
2428
import org.junit.Ignore;
2529
import org.junit.Test;
2630

2731
import java.io.IOException;
32+
import java.util.List;
2833

2934
/**
3035
* This class only delegates tests to the current-version log4j2 tests through JUnit 4, so that it can be ran using
@@ -35,6 +40,16 @@
3540
@Ignore
3641
public class LegacyLog4j2ShadingTest extends Log4j2ShadingTest {
3742

43+
@BeforeClass
44+
public static void resetConfigFactory() {
45+
ConfigurationFactory.resetConfigurationFactory();
46+
}
47+
48+
@AfterClass
49+
public static void reInitLogging() {
50+
LoggingConfiguration.init(List.of(), "");
51+
}
52+
3853
@Before
3954
@Override
4055
public void setup() throws Exception {

apm-agent-plugins/apm-log-shader-plugin/apm-log4j2-plugin/src/test/java/co/elastic/apm/agent/log4j2/Log4j2ShadingTest.java

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,19 +20,34 @@
2020

2121
import co.elastic.apm.agent.log.shader.LogShadingInstrumentationTest;
2222
import co.elastic.apm.agent.log.shader.LoggerFacade;
23+
import co.elastic.apm.agent.logging.LoggingConfiguration;
2324
import org.apache.logging.log4j.LogManager;
2425
import org.apache.logging.log4j.Logger;
2526
import org.apache.logging.log4j.Marker;
2627
import org.apache.logging.log4j.MarkerManager;
2728
import org.apache.logging.log4j.ThreadContext;
2829
import org.apache.logging.log4j.core.appender.RandomAccessFileAppender;
30+
import org.apache.logging.log4j.core.config.ConfigurationFactory;
31+
import org.junit.jupiter.api.AfterAll;
32+
import org.junit.jupiter.api.BeforeAll;
2933

3034
import java.net.URI;
3135
import java.net.URISyntaxException;
36+
import java.util.List;
3237
import java.util.Objects;
3338

3439
public class Log4j2ShadingTest extends LogShadingInstrumentationTest {
3540

41+
@BeforeAll
42+
static void resetConfigFactory() {
43+
ConfigurationFactory.resetConfigurationFactory();
44+
}
45+
46+
@AfterAll
47+
static void reInitLogging() {
48+
LoggingConfiguration.init(List.of(), "");
49+
}
50+
3651
private static final Marker TEST_MARKER = MarkerManager.getMarker("TEST");
3752

3853
@Override

0 commit comments

Comments
 (0)