即使我已将奖金奖励给下面的用户 试图帮助,原来的问题仍然没有答案。没有实际的 存在可行的解决方案以确保配置logback.groovy 日志记录在junit测试中得到尊重。测试加载了 logback配置它确实报告了正确的级别,但仍然是 实际测试记录(仅通过slf4j)处于任何或特定状态 水平
我知道其他人也遇到过同样的问题 由于控制台,大型项目的测试需要更长的时间,这很烦人 记录太冗长了。我不能继续投掷赏金 这个问题。我希望有人提出一个很好的解决方案 允许在不同级别正确配置测试日志记录 通过系统属性。然后,可以是不同的配置 为项目创建,以便测试能够配置为不同的日志记录阈值级别。
我的日志记录是通过logback.groovy文件
进行logback配置的现在,当我的Maven POM项目聚合所有其他项目时,它会传递所有System属性以设置正确的日志记录级别。
但是,当junit测试运行时,由于某种原因,即使测试类静态@beforeClass确保正确配置了logback,记录器也不会获得正确的级别。
测试中的记录器不是问题所在 - 嗯 - 是的,是的 - 真正的问题是运行的代码段中的记录器(我所有程序记录器到处都是)设置为错误的日志记录级别。在配置程序测试时,他们没有掌握日志记录的内容。
但是,当logback使用logback.goovy文件初始化时,项目报告正确。但是,实际日志记录级别设置为TRACE或ALL
从下面的输出中可以看出,logback已配置为INFO。但TRACE(最后一行)的第一个项目记录声明显示没有被提取。
帮助。
-------------------------------------------------------
T E S T S
-------------------------------------------------------
Running groovy.text.StreamingTemplateEngineTest
Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 1.245 sec
Running net.abcd.templating.InlinerTest
01:22:15,265 |-INFO in ch.qos.logback.classic.gaffer.ConfigurationDelegate@1e8c3cb - Added status listener of type [ch.qos.logback.core.status.OnConsoleStatusListener]
01:22:15,290 |-INFO in ch.qos.logback.classic.gaffer.ConfigurationDelegate@1e8c3cb - Setting ReconfigureOnChangeFilter scanning period to 5 minutes
01:22:15,290 |-INFO in ReconfigureOnChangeFilter{invocationCounter=0} - Will scan for changes in [[C:\Users\ABDC\Dropbox\workspace\abcd\AbcdTemplating\conf\logback.groovy]] every 300 seconds.
01:22:15,290 |-INFO in ch.qos.logback.classic.gaffer.ConfigurationDelegate@1e8c3cb - Adding ReconfigureOnChangeFilter as a turbo filter
01:22:15,312 |-INFO in ch.qos.logback.classic.gaffer.ConfigurationDelegate@1e8c3cb - About to instantiate appender of type [ch.qos.logback.core.ConsoleAppender]
01:22:15,316 |-INFO in ch.qos.logback.classic.gaffer.ConfigurationDelegate@1e8c3cb - Naming appender as [STDOUT]
***********************************************************
LOGGING MODE PROPERTY 'net.abcd.logging.level' SET TO: [info]
IT CAN BE SET TO: OFF, ERROR, WARN, INFO, DEBUG, TRACE, ALL, INFO
***********************************************************
getLogLevel() returned 'INFO'
01:22:15,496 |-INFO in ch.qos.logback.classic.gaffer.ConfigurationDelegate@1e8c3cb - Setting level of logger [ROOT] to INFO
01:22:15,532 |-INFO in ch.qos.logback.classic.gaffer.ConfigurationDelegate@1e8c3cb - Attaching appender named [STDOUT] to Logger[ROOT]
01:22:15.846 [main] TRACE net.abcd.templating.Inliner - Document:
我的logback.groovy文件是:
displayStatusOnConsole()
scan('5 minutes') // Scan for changes every 5 minutes.
setupAppenders()
setupLoggers()
def displayStatusOnConsole() {
statusListener OnConsoleStatusListener
}
def setupAppenders() {
appender('STDOUT', ConsoleAppender) {
encoder(PatternLayoutEncoder) {
pattern = "%d{HH:mm:ss.SSS} [%thread] %-5level %-16logger{50} - %msg%n"
}
}
}
def setupLoggers() {
def loglevel = getLogLevel()
println("getLogLevel() returned '${loglevel}'")
root(loglevel, ['STDOUT'])
}
def getLogLevel() {
def mode = System.getProperty('net.abcd.logging.level', '')
println("***********************************************************")
println("")
println("LOGGING MODE PROPERTY 'net.abcd.logging.level' SET TO: [${mode}]")
println("IT CAN BE SET TO: OFF, ERROR, WARN, INFO, DEBUG, TRACE, ALL, INFO")
println("")
println("***********************************************************")
switch(mode.toLowerCase()){
case 'off':
return OFF
case 'error':
return ERROR
case 'warn':
return WARN
case 'info':
return INFO
case 'debug':
return DEBUG
case 'trace':
return TRACE
case 'all':
return ALL
default:
return INFO
}
}
答案 0 :(得分:3)
我在junit测试中遇到了类似的问题。 我找不到一个好的解决方案。我在下面的工作中使用过:
import ch.qos.logback.classic.Level;
import ch.qos.logback.classic.Logger;
import org.slf4j.LoggerFactory;
...
static Logger logger;
static{
// Logger.ROOT_LOGGER_NAME == "ROOT"
logger = ((Logger) LoggerFactory.getLogger(Logger.ROOT_LOGGER_NAME));
logger.setLevel(Level.INFO);
}
...
我认为在你的情况下,某个库会使用它自己的ConsoleAppender实例,其名称不是'STDOUT'。 我希望设置root日志级别可以解决问题。
root(loglevel, ['ROOT']);
答案 1 :(得分:1)
我们通常通过slf4j路由每个日志记录,然后使用logback配置日志记录。所以我们的Maven依赖关系看起来像:
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>${slf4j.version}</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>jcl-over-slf4j</artifactId>
<version>${slf4j.version}</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>log4j-over-slf4j</artifactId>
<version>${slf4j.version}</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>jul-to-slf4j</artifactId>
<version>${slf4j.version}</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-core</artifactId>
<version>${logback.version}</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>${logback.version}</version>
</dependency>
因此,如果某些依赖项使用java-commons-logging(jcl),log4j或java.util.logging(jul),那么它的日志记录将被桥接到slf4j。应用程序日志记录也使用slf4j,而不是使用logback配置。
因此,您可能需要使用其中一个桥(例如jcl-over-slf4j)来控制外部依赖项的记录。
编辑: Pavel Horal,谢谢jul,是的,你是对的。人们需要做的不仅仅是添加依赖项。我们还有一个logback配置器,它显式调用SLF4JBridgeHandler.install()。我们的配置程序还加载了logback配置文件,我忘记了这个调用。但我主要想指出外部依赖项使用的多个日志记录库的问题方向,以及这些桥接器可以将不同的日志记录库置于logback的顶层。