重新创建附加程序实例

时间:2019-02-19 10:41:55

标签: java logback

我使用LogBack,并且有几个Logger。 我创建了一个自定义Appender:

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);
        }
    }
}

此添加程序将向侦听器添加侦听器以捕获日志消息。

现在在我的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);
}

所需的输出是:

测试日志:您好

但是输出是:

测试日志:您好
主要日志:您好

LogListenerAppender中的System.out.println("Current listener: " + listeners.size());打印2。

我现在的问题是,对于所有使用<appender-ref ref="LISTENER"/>的Logger,Logback使用相同的LogListenerAppender实例。

但是我需要为每个Logger一个新的LogListenerAppender。 如何配置他每次创建新实例时创建的logBack?

我的想法是为每个记录器创建appender,例如:

<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...

但我希望它存在一种更简单的方法

1 个答案:

答案 0 :(得分:0)

您可以在此处的代码中查看为什么发生这种情况:

LogListenerAppender附加器=(LogListenerAppender)log.getAppender(“ LISTENER”);

您的代码仅获得您在内存中创建的带有引用“ LISTENER”标记的附加程序。该侦听器列表中的所有内容都将侦听来自带有侦听器标记的附加程序的任何事件。

也许尝试将String添加到您的添加侦听器方法中,如下所示:

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);
}

这样,您可以将适当的附加程序引用(即“ LISTENER1”)传递给方法,以检索适当的附加程序。

同样值得选择合适的裁判,即

<logger name="TestLogger">
    <appender-ref ref="TEST" />
</logger>

<logger name="MainLogger">
    <appender-ref ref="MAIN" />
</logger>

出于可读性和可维护性的考虑,但这是一种样式选择,而不是技术决定