Ela*_*ich 6 java logging slf4j
如何配置slf4j将所有记录的信息重定向到Java字符串?
这有时在单元测试中很有用,例如,测试在加载servlet时不会打印警告,或者确保从不使用禁用的SQL表.
有点晚了,但还是...
由于在单元测试时日志配置应该很容易替换,因此您只需配置为记录标准输出,然后在执行日志主题之前捕获它。然后将记录器设置为对除被测对象以外的所有对象保持静音。
@Test
public void test()
{
String log = captureStdOut(() -> {
// ... invoke method that shouldn't log
});
assertThat(log, is(emptyString()));
}
public static String captureStdOut(Runnable r)
{
ByteArrayOutputStream baos = new ByteArrayOutputStream();
PrintStream out = System.out;
try {
System.setOut(new PrintStream(baos, true, StandardCharsets.UTF_8.name()));
r.run();
return new String(baos.toByteArray(), StandardCharsets.UTF_8);
} catch (UnsupportedEncodingException e) {
throw new RuntimeException("End of the world, Java doesn't recognise UTF-8");
} finally {
System.setOut(out);
}
}
Run Code Online (Sandbox Code Playgroud)
如果在测试中使用 slf4j 而不是 log4j,一个简单的log4j.properties:
log4j.rootLogger=OFF, out
log4j.category.com.acme.YourServlet=INFO, out
log4j.appender.out=org.apache.log4j.ConsoleAppender
log4j.appender.out.layout=org.apache.log4j.PatternLayout
log4j.appender.out.layout.ConversionPattern=%-5p %c{1}:%L - %m%n
Run Code Online (Sandbox Code Playgroud)
或者,如果您不喜欢在单元测试中将配置作为外部依赖项,那么以编程方式配置 log4j:
//...
static final String CONSOLE_APPENDER_NAME = "console.appender";
private String pattern = "%d [%p|%c|%C{1}] %m%n";
private Level threshold = Level.ALL;
private Level defaultLevel = Level.OFF;
//...
public void configure()
{
configureRootLogger();
configureConsoleAppender();
configureCustomLevels();
}
private void configureConsoleAppender()
{
ConsoleAppender console = new ConsoleAppender();
console.setName(CONSOLE_APPENDER_NAME);
console.setLayout(new PatternLayout(pattern));
console.setThreshold(threshold);
console.activateOptions();
Logger.getRootLogger().addAppender(console);
}
private void configureRootLogger()
{
Logger.getRootLogger().getLoggerRepository().resetConfiguration();
Logger.getRootLogger().setLevel(defaultLevel);
}
Run Code Online (Sandbox Code Playgroud)
在我看来,你有两个选择。
首先,您可以实现一个自定义 Appender(取决于您使用的 slf4j 实现),它只需将每个记录的语句附加到 StringBuffer 中。在这种情况下,您可能必须保存对 StringBuffer 的静态引用,以便您的测试类可以访问它。
其次,您可以编写自己的 ILoggerFactory 和 Logger 实现。同样,您的记录器只会将所有消息附加到内部 StringBuffers,尽管在这种情况下您可能有多个缓冲区,每个日志级别一个。如果您这样做,您将有一个简单的方法来检索 Logger 实例,因为您拥有分发它们的工厂。