INT-4376: Upgage to Log4J 2 (#2321)

* INT-4376: Upgage to Log4J 2

JIRA: https://jira.spring.io/browse/INT-4376

* Deprecate Log4J 1.x components in favor of newly added
a `Log4j2LevelAdjuster` JUnit `@Rule`
* Update all the logging configuration to Log4J 2

* Polishing after testing
This commit is contained in:
Artem Bilan
2018-01-11 10:59:55 -05:00
committed by Gary Russell
parent 422f651113
commit 30450c48be
97 changed files with 981 additions and 539 deletions

View File

@@ -0,0 +1,216 @@
/*
* Copyright 2018 the original author or 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 org.springframework.integration.test.rule;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import java.util.stream.Stream;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.logging.log4j.Level;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.core.LoggerContext;
import org.apache.logging.log4j.core.config.Configuration;
import org.apache.logging.log4j.core.config.LoggerConfig;
import org.junit.rules.MethodRule;
import org.junit.runners.model.FrameworkMethod;
import org.junit.runners.model.Statement;
import org.springframework.util.Assert;
import org.springframework.util.ObjectUtils;
/**
* A JUnit method {@link org.junit.Rule} that changes the Log4J 2 logger level for a set of classes
* or packages while a test method is running. Useful for performance or scalability tests
* where we don't want to generate a large log in a tight inner loop, or
* enabling debug logging for a test case.
*
* @author Artem Bilan
*
* @since 5.0.1
*
*/
public class Log4j2LevelAdjuster implements MethodRule {
private static final Log logger = LogFactory.getLog(Log4j2LevelAdjuster.class);
private final Class<?>[] classes;
private final Level level;
private final String[] categories;
private Log4j2LevelAdjuster(Level level) {
this(level, null, new String[] { "org.springframework.integration" });
}
private Log4j2LevelAdjuster(Level level, Class<?>[] classes, String[] categories) {
Assert.notNull(level, "'level' must be null");
this.level = level;
this.classes = classes != null ? classes : new Class<?>[0];
Stream<String> categoryStream = Stream.of(getClass().getPackage().getName());
if (!ObjectUtils.isEmpty(categories)) {
categoryStream = Stream.concat(Arrays.stream(categories), categoryStream);
}
this.categories = categoryStream.toArray(String[]::new);
}
@Override
public Statement apply(final Statement base, final FrameworkMethod method, Object target) {
return new Statement() {
@Override
public void evaluate() throws Throwable {
LoggerContext ctx = (LoggerContext) LogManager.getContext(false);
Configuration config = ctx.getConfiguration();
Map<Class<?>, Level> classLevels = new HashMap<>();
for (Class<?> cls : Log4j2LevelAdjuster.this.classes) {
String className = cls.getName();
LoggerConfig loggerConfig = config.getLoggerConfig(className);
LoggerConfig specificConfig = loggerConfig;
// We need a specific configuration for this logger,
// otherwise we would change the level of all other loggers
// having the original configuration as parent as well
if (!loggerConfig.getName().equals(className)) {
specificConfig = new LoggerConfig(className, Log4j2LevelAdjuster.this.level, true);
specificConfig.setParent(loggerConfig);
config.addLogger(className, specificConfig);
}
classLevels.put(cls, specificConfig.getLevel());
specificConfig.setLevel(Log4j2LevelAdjuster.this.level);
}
Map<String, Level> categoryLevels = new HashMap<>();
for (String category : Log4j2LevelAdjuster.this.categories) {
LoggerConfig loggerConfig = config.getLoggerConfig(category);
LoggerConfig specificConfig = loggerConfig;
// We need a specific configuration for this logger,
// otherwise we would change the level of all other loggers
// having the original configuration as parent as well
if (!loggerConfig.getName().equals(category)) {
specificConfig = new LoggerConfig(category, Log4j2LevelAdjuster.this.level, true);
specificConfig.setParent(loggerConfig);
config.addLogger(category, specificConfig);
}
categoryLevels.put(category, specificConfig.getLevel());
specificConfig.setLevel(Log4j2LevelAdjuster.this.level);
}
ctx.updateLoggers();
logger.debug("++++++++++++++++++++++++++++ "
+ "Overridden log level setting for: " + Arrays.toString(Log4j2LevelAdjuster.this.classes)
+ " and " + Arrays.toString(Log4j2LevelAdjuster.this.categories)
+ " for test " + method.getName());
try {
base.evaluate();
}
finally {
logger.debug("++++++++++++++++++++++++++++ "
+ "Restoring log level setting for: " + Arrays.toString(Log4j2LevelAdjuster.this.classes)
+ " and " + Arrays.toString(Log4j2LevelAdjuster.this.categories)
+ " for test " + method.getName());
for (Class<?> cls : Log4j2LevelAdjuster.this.classes) {
LoggerConfig loggerConfig = config.getLoggerConfig(cls.getName());
loggerConfig.setLevel(classLevels.get(cls));
}
for (String category : Log4j2LevelAdjuster.this.categories) {
LoggerConfig loggerConfig = config.getLoggerConfig(category);
loggerConfig.setLevel(categoryLevels.get(category));
}
ctx.updateLoggers();
}
}
};
}
/**
* Specify the classes for logging level adjusting configured before.
* A new copy Log4j2LevelAdjuster instance is produced by this method.
* The provided classes parameter overrides existing value in the {@link #classes}.
* @param classes the classes to use for logging level adjusting
* @return a Log4j2LevelAdjuster copy with the provided classes
*/
public Log4j2LevelAdjuster classes(Class<?>... classes) {
return new Log4j2LevelAdjuster(this.level, classes, this.categories);
}
/**
* Specify the categories for logging level adjusting configured before.
* A new copy Log4j2LevelAdjuster instance is produced by this method.
* The provided categories parameter overrides existing value in the {@link #categories}.
* @param categories the categories to use for logging level adjusting
* @return a Log4j2LevelAdjuster copy with the provided categories
*/
public Log4j2LevelAdjuster categories(String... categories) {
return new Log4j2LevelAdjuster(this.level, this.classes, categories);
}
/**
* The factory to produce Log4j2LevelAdjuster instances for {@link Level#TRACE} logging
* with the {@code org.springframework.integration} as default category.
* @return the Log4j2LevelAdjuster instance
*/
public static Log4j2LevelAdjuster trace() {
return level(Level.TRACE);
}
/**
* The factory to produce Log4j2LevelAdjuster instances for {@link Level#DEBUG} logging
* with the {@code org.springframework.integration} as default category.
* @return the Log4j2LevelAdjuster instance
*/
public static Log4j2LevelAdjuster debug() {
return level(Level.DEBUG);
}
/**
* The factory to produce Log4j2LevelAdjuster instances for {@link Level#INFO} logging
* with the {@code org.springframework.integration} as default category.
* @return the Log4j2LevelAdjuster instance
*/
public static Log4j2LevelAdjuster info() {
return level(Level.INFO);
}
/**
* The factory to produce Log4j2LevelAdjuster instances for arbitrary logging {@link Level}
* with the {@code org.springframework.integration} as default category.
* @return the Log4j2LevelAdjuster instance
*/
public static Log4j2LevelAdjuster level(Level level) {
return new Log4j2LevelAdjuster(level);
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2015-2016 the original author or authors.
* Copyright 2015-2018 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -41,10 +41,16 @@ import org.junit.runners.model.Statement;
* @author Dave Syer
* @author Gary Russell
*
* @deprecated since 5.0.1 in favor of {@link Log4j2LevelAdjuster}.
* Will be removed in 5.1.
*
*/
@Deprecated
@SuppressWarnings("deprecation")
public class Log4jLevelAdjuster implements MethodRule {
private static final Log logger = LogFactory.getLog(Log4jLevelAdjuster.class);
private static final Log logger =
LogFactory.getLog(org.springframework.integration.test.rule.Log4jLevelAdjuster.class);
private final Class<?>[] classes;

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2015-2016 the original author or authors.
* Copyright 2015-2018 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -40,7 +40,11 @@ import org.junit.rules.TestName;
*
* @since 4.2.2
*
* @deprecated since 5.0.1 in favor of {@link org.springframework.integration.test.rule.Log4j2LevelAdjuster}.
* Will be removed in 5.1.
*
*/
@Deprecated
public class LogAdjustingTestSupport {
/*

View File

@@ -1,7 +0,0 @@
log4j.rootCategory=WARN, stdout
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%c{1}: %m%n
log4j.category.org.springframework.integration=WARN

View File

@@ -0,0 +1,14 @@
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="WARN">
<Appenders>
<Console name="STDOUT" target="SYSTEM_OUT">
<PatternLayout pattern="%d %p [%t] [%c] - %m%n" />
</Console>
</Appenders>
<Loggers>
<Logger name="org.springframework.integration" level="warn"/>
<Root level="warn">
<AppenderRef ref="STDOUT" />
</Root>
</Loggers>
</Configuration>