java - logback 创建 appender 的新实例
问题描述
我使用 LogBack,我有几个 Logger。我创建了一个自定义附加程序:
public class LogListenerAppender extends AppenderBase<ILoggingEvent> {
private List<LogListener> listeners;
public LogListenerAppender() {
listeners = new ArrayList<>();
}
public void addListener(LogListener listener){
listeners.add(listener);
System.out.println("Current listener: " + listeners.size());
}
/**
* Send the LogEvent to all Listeners
* @param eventObject the LogEventObject
*/
@Override
protected void append(ILoggingEvent eventObject) {
for(LogListener listener : listeners){
listener.receiveLogMessage(eventObject);
}
}
}
这个 appender 是为 Logger 添加监听器来捕获 Log 消息。
现在在我的 logback.xml 文件中,我将 Appender 创建为 LISTENER
<!--Custom Listener Appender-->
<appender name="LISTENER" class="path.to.LogListenerAppender"/>
还有一些记录器:
<logger name="TestLogger">
<appender-ref ref="LISTENER" />
</logger>
<logger name="MainLogger">
<appender-ref ref="LISTENER" />
</logger>
在代码中,我将 LogListener 添加到 Logger:
public static void main(String[] args){
Logger testLogger = LoggerFactory.getLogger("TestLogger");
Logger mainLogger = LoggerFactory.getLogger("MainLogger");
addListenerToLogger(testLogger, new LogListener(Level.TRACE) {
@Override
public void log(String message, long timestamp) {
System.out.println("TEST LOG: " + message);
}
});
addListenerToLogger(mainLogger, new LogListener(Level.TRACE) {
@Override
public void log(String message, long timestamp) {
System.out.println("MAIN LOG: " + message);
}
});
testLogger.info("Hello");
}
private static void addListenerToLogger(Logger logger, LogListener loglistener){
ch.qos.logback.classic.Logger log = (ch.qos.logback.classic.Logger) logger;
LogListenerAppender appender = (LogListenerAppender)log.getAppender("LISTENER");
appender.addListener(loglistener);
}
所需的输出是:
测试日志:你好
但输出是:
测试日志:你好
主日志:你好
而System.out.println("Current listener: " + listeners.size());
在 LogListenerAppender 中打印 2。
我现在的问题是 Logback 对所有使用<appender-ref ref="LISTENER"/>
.
但是我需要为每个 Logger 一个新的 LogListenerAppender。如何配置他每次创建新实例时创建的 logBack?
我的想法是为每个记录器创建附加程序,例如:
<appender name="LISTENER1" class="path.to.LogListenerAppender"/>
<appender name="LISTENER2" class="path.to.LogListenerAppender"/>
//etc...
<logger name="TestLogger">
<appender-ref ref="LISTENER1" />
</logger>
<logger name="MainLogger">
<appender-ref ref="LISTENER2" />
</logger>
//etc...
但我希望它存在一种更简单的方法
解决方案
您可以在此处查看代码中出现这种情况的原因:
LogListenerAppender appender = (LogListenerAppender)log.getAppender("LISTENER");
您的代码只会获取您在内存中创建的任何附加程序,并标记为“LISTENER”。该侦听器列表中的所有内容都将侦听来自带有侦听器标记的附加程序的任何事件。
也许尝试像这样向您的添加侦听器方法添加一个字符串:
private static void addListenerToLogger(Logger logger, LogListener loglistener, String appenderRef){
ch.qos.logback.classic.Logger log = (ch.qos.logback.classic.Logger) logger;
LogListenerAppender appender = (LogListenerAppender)log.getAppender(appenderRef);
appender.addListener(loglistener);
}
这样,您可以将适当的 appender ref(即“LISTENER1”)传递给该方法以检索适当的 appender。
选择适当的参考也是值得的,即;
<logger name="TestLogger">
<appender-ref ref="TEST" />
</logger>
<logger name="MainLogger">
<appender-ref ref="MAIN" />
</logger>
为了可读性和可维护性,但这是一种风格选择,而不是技术决策
推荐阅读
- sql-server - SQL Server - 使用 while 循环缩短几个联合联接
- jquery - 在变量中查找文本
- laravel - 在 Webpack 构建后执行 shell 命令
- xpath - 在 Xpath Contains 中传递 Cyrilics 会返回 XML 值错误。刮痧。蟒蛇2
- r - 基于多列的r plotly图表
- r - 一起使用 LaF 和 grepl
- tensorflow - TensorFlow 网络在使用“dataset.map()”后接收到错误的张量形状
- arrays - 如何通过作为数字数组的参数对对象进行排序(Swift)
- php - 只想从搜索栏中搜索具有指定“字符串”的“字符串”.html 文件 - PHP
- java - 尝试测试 servlet 时出现 MockitoException