java - Logback Appender 的静态上下文配置
问题描述
我找到了一些关于 Logback 日志记录附加程序的编程配置的示例(甚至在 Stack Overflow 上),但是到目前为止,我已将其纳入自己的设置中并没有为我工作。一些示例产生了一个实际Logger
实例,但考虑到我已经Logger
在我的类中静态实例化了一个,我希望能够以编程方式启用Appender
我为单元测试目的而定义的一个。
这是我的自定义附加程序:
package org.example.logging;
import ch.qos.logback.classic.spi.ILoggingEvent;
import ch.qos.logback.core.AppenderBase;
import java.util.ArrayList;
import java.util.List;
// Credit to https://stackoverflow.com/a/29077499/5476186
public class TestAppender extends AppenderBase<ILoggingEvent> {
private static List<ILoggingEvent> events = new ArrayList<>();
@Override
protected void append(ILoggingEvent e) {
events.add(e);
}
public static List<ILoggingEvent> events() {
return List.copyOf(events);
}
public static void clear() {
events.clear();
}
}
在我的测试代码中,我正在尝试将我的配置TestAppender
为“启动”,以便在我的测试设置中调用此方法后,我可以捕获日志并验证它们:
package org.example.logging;
import ch.qos.logback.classic.LoggerContext;
import org.slf4j.LoggerFactory;
// ...
// Mostly modeled after https://stackoverflow.com/a/7825548/5476186
private static void startAppender() {
LoggerContext logCtx = (LoggerContext) LoggerFactory.getILoggerFactory();
TestAppender appender = new TestAppender();
appender.setContext(logCtx);
appender.setName("TEST");
// I was hoping this would statically allow the appender to kick in,
// but all of the examples then attach this appender to a Logger instance.
appender.start();
}
显然,这对我不起作用。所以我想我有两个或有问题。
- 这可能吗?如果可以,我怎样才能让它发挥作用?
- 如果这是不可能的,那么完成我想做的最干净的方法是什么?(在测试期间启用/禁用附加程序,而不必手动弄乱配置文件。)
在上面链接的一个线程中,我发现这个答案看起来像是一种可能的解决方案是修改配置文件中的文本并强制重新加载,但这对我来说似乎不是很干净。另一种选择是创建我自己的包装器工厂,我可以使用它在测试执行期间通过依赖注入Logger
为记录器提供我的记录器。TestAppender
无论如何,我可能会创建一个包装器,即使我使用的是 SLF4J。
旁注:我知道我目前编写的测试代码与 Logback 而不是 SLF4J 紧密耦合,因此我也愿意接受有关该问题的批评/建议。
解决方案
如果您在生产代码中使用 slf4j,那么已经有一个项目可以帮助测试:它称为slf4j-test
简而言之,它提供了一个 API 来检索测试中的“测试记录器”,它将所有记录的消息保存在内存中,以便您能够验证它们。
这样你:
- 执行记录某些内容的方法
- 检索测试记录器
- 调用
getLoggingEvents()
测试记录器并验证记录的事件
我提供的链接包含 API 示例以及 maven 集成示例。
如果,或者您想直接将 logback 用于测试或其他东西,那么已经有一个ListAppender
作为 logback 分发的一部分提供的,它允许检索已经通过 appender 的事件。您可以以编程方式将其添加到记录器并在测试中使用。
在这里你可以找到一个全面的例子
推荐阅读
- excel - 当我运行代码时,只有一个工作表被更新,例如 Apple。其他 3 个工作表未更新。我该如何解决这个问题?
- docker - 将 docker 镜像拉到 EC2 实例时设备上没有剩余空间(实例中不存在镜像或容器)
- r - R中Y轴上有两个变量的频率分布直方图
- mongodb - AWS DocumentDB 中架构验证的替代方法
- css - 如何防止背景图像像素化?
- sql-server - SSIS -- 未能部署项目。错误 27203
- python - 根据条件生成新列
- javascript - Angular Router usehash:导航不保留hastag之前的url
- html - 如何在使用 puppeteer 生成的 pdf 上使用 Roboto 字体系列
- swift - 在 List SwiftUI 2.0 中的 TextField 之间切换焦点