Skip to content

Commit

Permalink
[LOG4J2-3418] Fix Log4j2CloudConfigLoggingSystem registration
Browse files Browse the repository at this point in the history
This PR adds support for the `spring.factories` registration method of
the `Log4j2CloudConfigLoggingSystem` to replace the old Java system
properties injection method.

A Log4j 2.x `log4j2.disableCloudConfigLoggingSystem` property is added
to enable a choice between the `Log4j2CloudConfigLoggingSystem` and
`Log4j2LoggingSystem`.
  • Loading branch information
ppkarwasz committed Mar 4, 2022
1 parent 31697cf commit f807ecc
Show file tree
Hide file tree
Showing 4 changed files with 55 additions and 7 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,10 @@
import org.apache.logging.log4j.util.Strings;
import org.springframework.boot.logging.LogFile;
import org.springframework.boot.logging.LoggingInitializationContext;
import org.springframework.boot.logging.LoggingSystem;
import org.springframework.boot.logging.LoggingSystemFactory;
import org.springframework.boot.logging.log4j2.Log4J2LoggingSystem;
import org.springframework.core.annotation.Order;
import org.springframework.util.Assert;
import org.springframework.util.ClassUtils;
import org.springframework.util.ResourceUtils;
Expand All @@ -58,10 +61,17 @@
* Override Spring's implementation of the Log4j 2 Logging System to properly support Spring Cloud Config.
*/
public class Log4j2CloudConfigLoggingSystem extends Log4J2LoggingSystem {
private static final String HTTPS = "https";

/**
* Property that disables the usage of this {@link LoggingSystem}.
*/
public static final String LOG4J2_DISABLE_CLOUD_CONFIG_LOGGING_SYSTEM = "log4j2.disableCloudConfigLoggingSystem";

public static final String ENVIRONMENT_KEY = "SpringEnvironment";
private static final String HTTPS = "https";
private static final String OVERRIDE_PARAM = "override";
private static Logger LOGGER = StatusLogger.getLogger();
private static final int PRECEDENCE = 0;

public Log4j2CloudConfigLoggingSystem(ClassLoader loader) {
super(loader);
Expand Down Expand Up @@ -213,4 +223,18 @@ private ConfigurationSource getConfigurationSource(URL url) throws IOException,
private LoggerContext getLoggerContext() {
return (LoggerContext) LogManager.getContext(false);
}

@Order(PRECEDENCE)
public static class Factory implements LoggingSystemFactory {

@Override
public LoggingSystem getLoggingSystem(ClassLoader classLoader) {
if (PropertiesUtil.getProperties().getBooleanProperty(LOG4J2_DISABLE_CLOUD_CONFIG_LOGGING_SYSTEM)) {
return null;
}
return new Log4j2CloudConfigLoggingSystem(classLoader);
}

}

}
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,4 @@
# See the license for the specific language governing permissions and
# limitations under the license.
#
org.springframework.boot.logging.LoggingSystem=org.apache.logging.log4j.spring.boot.Log4j2CloudConfigLoggingSystem
org.springframework.boot.logging.LoggingSystemFactory=org.apache.logging.log4j.spring.boot.Log4j2CloudConfigLoggingSystem.Factory
Original file line number Diff line number Diff line change
Expand Up @@ -19,23 +19,41 @@
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.core.config.ConfigurationFactory;
import org.apache.logging.log4j.spi.LoggerContext;
import org.junit.Test;
import org.junit.jupiter.api.Test;
import org.junitpioneer.jupiter.SetSystemProperty;
import org.springframework.boot.logging.LoggingSystem;
import org.springframework.boot.logging.log4j2.Log4J2LoggingSystem;

import static org.junit.jupiter.api.Assertions.assertTrue;

import java.util.Arrays;
import java.util.List;

import static org.junit.Assert.assertTrue;

public class Log4j2CloudConfigLoggingSystemTest {

@Test
public void getStandardConfigLocations() {
String customLog4j2Location = "classpath:my_custom_log4j2.properties";
LoggerContext lc = LogManager.getContext(); // Initialize LogManager to here to prevent a failure trying to initialize it from StatusLogger.
LoggerContext lc = LogManager.getContext(); // Initialize LogManager to here to prevent a failure trying to
// initialize it from StatusLogger.
System.setProperty(ConfigurationFactory.CONFIGURATION_FILE_PROPERTY, customLog4j2Location);
Log4j2CloudConfigLoggingSystem cloudLoggingSystem = new Log4j2CloudConfigLoggingSystem(this.getClass().getClassLoader());
Log4j2CloudConfigLoggingSystem cloudLoggingSystem = new Log4j2CloudConfigLoggingSystem(
this.getClass().getClassLoader());
List<String> standardConfigLocations = Arrays.asList(cloudLoggingSystem.getStandardConfigLocations());
assertTrue(standardConfigLocations.contains(customLog4j2Location));

}

@Test
@SetSystemProperty(key = Log4j2CloudConfigLoggingSystem.LOG4J2_DISABLE_CLOUD_CONFIG_LOGGING_SYSTEM, value = "true")
public void testUseLog4j2LoggingSystem() {
LoggingSystem loggingSystem = LoggingSystem.get(getClass().getClassLoader());
assertTrue(loggingSystem.getClass().equals(Log4J2LoggingSystem.class));
}

@Test
public void testLoggingSystemEnabled() {
LoggingSystem loggingSystem = LoggingSystem.get(getClass().getClassLoader());
assertTrue(loggingSystem.getClass().equals(Log4j2CloudConfigLoggingSystem.class));
}
}
6 changes: 6 additions & 0 deletions src/site/xdoc/manual/configuration.xml.vm
Original file line number Diff line number Diff line change
Expand Up @@ -2878,6 +2878,12 @@ public class AwesomeTest {
that advertises the same language(s) in order for scripting to be enabled. If no languages are specified, which is
the default, the ScriptManager will not be installed.</td>
</tr>
<tr>
<td><a name="log4j2.disableCloudConfigLoggingSystem"/>log4j2.disableCloudConfigLoggingSystem</td>
<td></td>
<td></td>
<td>Disables the usage of the Spring Boot <tt>Log4j2CloudConfigLoggingSystem</tt>. Defaults to <tt>false</tt>.</td>
</tr>
</table>

</subsection>
Expand Down

0 comments on commit f807ecc

Please sign in to comment.