简体   繁体   English

重新创建附加程序实例

[英]logback create new instance of appender

I work with LogBack and I have several Loggers. 我使用LogBack,并且有几个Logger。 I have created a Custom Appender: 我创建了一个自定义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);
        }
    }
}

This appender is to add listeners to the Logger to catch Log messages. 该追加器将向侦听器添加侦听器以捕获日志消息。

Now in my logback.xml file, I have created the Appender as LISTENER 现在,在我的logback.xml文件中,将Appender创建为LISTENER

<!--Custom Listener Appender-->
<appender name="LISTENER" class="path.to.LogListenerAppender"/>

And some Logger: 还有一些记录器:

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

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

In the code I add LogListener to the 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);
}

The desired output is: 所需的输出是:

TEST LOG: Hello 测试记录:您好

But the output is: 但是输出是:

TEST LOG: Hello 测试记录:您好
MAIN LOG: Hello 主要日志:您好

And the System.out.println("Current listener: " + listeners.size()); 还有System.out.println("Current listener: " + listeners.size()); in the LogListenerAppender prints 2. 在LogListenerAppender中打印2。

My problem now is that Logback uses the same instance of LogListenerAppender for all Logger who uses <appender-ref ref="LISTENER"/> . 我现在的问题是,对于使用<appender-ref ref="LISTENER"/>所有Logger,Logback使用相同的LogListenerAppender实例。

But I need for every Logger a new LogListenerAppender. 但是我需要为每个Logger配备一个新的LogListenerAppender。 How can I configure logBack that he creates every time a new Instance? 如何配置他每次创建新实例时创建的logBack?

My idea is to create appender for every logger like: 我的想法是为每个记录器创建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...

But I hope it exists an easier way 但我希望它存在一个更简单的方法

You can see why this is occuring in your code here: 您可以在这里的代码中查看为什么会发生这种情况:

LogListenerAppender appender = (LogListenerAppender)log.getAppender("LISTENER"); LogListenerAppender附加程序=(LogListenerAppender)log.getAppender(“ LISTENER”);

Your code just gets whatever appender you've created in memory tagged with reference "LISTENER". 您的代码将获得您在内存中创建的带有引用“ LISTENER”标记的任何追加程序。 Everything in that list of listeners will listen for any event from an appender tagged with listener. 该侦听器列表中的所有内容都将侦听来自带有侦听器标记的附加程序的任何事件。

Perhaps try adding a String to your add listener method like so: 也许尝试将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);
}

This way you can pass the appropriate appender ref (ie "LISTENER1") to the method to retrieve the appropriate appenders. 这样,您可以将适当的附加程序引用(即“ LISTENER1”)传递给方法以检索适当的附加程序。

It would be worthwhile to chose appropriate refs as well ie; 同样值得选择合适的参考。

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

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

For the sake of readability and maintainability, but that's a style choice more than a technical decision 出于可读性和可维护性的考虑,但这是一种样式选择,而不是技术决定

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM