I work with LogBack and I have several Loggers. I have created a Custom 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
<!--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:
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()); in the LogListenerAppender prints 2.
My problem now is that Logback uses the same instance of LogListenerAppender for all Logger who uses <appender-ref ref="LISTENER"/>.
But I need for every Logger a new LogListenerAppender. How can I configure logBack that he creates every time a new Instance?
My idea is to create appender for every logger like:
<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