我目前正在从 Log4j 1.2 迁移到 Log4j 2。 我们使用 Apache Commons Logging 1.1 (JCL),并以 Log4j2 作为实现。
现在在执行单元测试时,像
这样的语句 if (log.isInfoEnabled()) {
log.info("example");
}
如果日志日志级别太高(例如本例中的 WARN),将在覆盖率报告中显示为未覆盖的行,因为 if
正文不会被执行。
在 Log4j 1 中,我公司的某人编写了一个自定义记录器,如果它检测到它是从 Maven Surefire 运行的,那么它会为所有 log.isXXXEnabled()
方法返回 true,如下所示:
import org.apache.commons.logging.Log;
import org.apache.commons.logging.impl.Log4JLogger;
public class Log4JEnhancedCoverage implements Log {
private static final long serialVersionUID = -8715529047111858959L;
private final Log logger;
private final boolean mavenRun;
public LogEnhancedCoverage(String name) {
this.logger = new Log4JLogger(_name);
this.mavenRun = TestsRunContext.isMavenSurefireRun();
}
@Override
public boolean isTraceEnabled() {
return (mavenRun) ? true : logger.isTraceEnabled();
}
@Override
public void trace(Object message) {
logger.trace(message);
}
// repeat for warn, info, etc
}
效果是每执行一个isXXXEnabled()
block ,日志语句就会通过配置文件重定向到log4j。 Log4j 本身将看到仅显示指定日志级别的消息,而执行所有级别的代码块。
旧:问题在于您可以看到 Log4j 记录器实现是直接从 JCL 的 impl 包实例化的。 (是的,他们提供了自己的适配器实现!)。
在我的新设置中,我使用的是 log4j-jcl 工件,但我不知道如何在构造函数中正确创建 Log4j 2 兼容记录器。
更新: log4j-jcl
附带其自己的日志工厂,该工厂加载 log4j 2 特定记录器实现。因此,根本不支持特定记录器的 commons-logging
配置。
最佳答案
只需使用公共(public)日志记录 API 获取记录器,而不是直接实例化它,就可以了。
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
//REMOVE THIS: import org.apache.commons.logging.impl.Log4JLogger;
public class Log4JEnhancedCoverage implements Log {
private static final long serialVersionUID = -8715529047111858959L;
private final Log logger;
private final boolean mavenRun;
public Log4JEnhancedCoverage(String name) {
//REMOVE THIS: this.logger = new Log4JLogger(name);
this.logger = LogFactory.getLog(name);
...
关于java - 通过 Commons 日志记录和 Log4j 2.0 增强代码覆盖率,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43273386/