14 messages in org.apache.logging.log4j-userRe: Fw: ThreadLocalAppender for log4j...
FromSent OnAttachments
Ramakrishna MenonMar 1, 2004 5:25 pm 
Ceki GülcüMar 2, 2004 2:18 am 
Ramakrishna MenonMar 2, 2004 7:26 am 
Ceki GülcüMar 2, 2004 8:13 am 
Paul SmithMar 2, 2004 11:56 am 
Ramakrishna MenonMar 2, 2004 12:12 pm 
Paul SmithMar 2, 2004 1:22 pm 
Ramakrishna MenonMar 2, 2004 3:33 pm 
Paul SmithMar 2, 2004 3:42 pm 
Ramakrishna MenonMar 2, 2004 4:36 pm 
Ramakrishna MenonJun 23, 2004 9:11 am 
Ramakrishna MenonJun 25, 2004 9:44 am 
Paul SmithJun 27, 2004 2:53 pm 
Ramakrishna MenonJun 28, 2004 8:39 am 
Actions with this message:
Paste this link in email or IM:
Paste this link in email or IM:
Atom feed for this thread
Paste this URL into your reader:
Subject:Re: Fw: ThreadLocalAppender for log4j? resendingActions...
From:Paul Smith (paul@lawlex.com.au)
Date:Mar 2, 2004 1:22:25 pm
List:org.apache.logging.log4j-user

Ok, to get some context to what we did, our App had a MessageListener interface that was used a lot as a Listener callback to pass Informational messages to our GUI (I've put notes in []):

public interface MessageListener extends EventListener { /** * This listener receives a notification */ public void receiveMessage(MessageEvent message); }

[MessageEvent is a trivial class, MessageType=ERROR|INFO|WARN etc, plus a String message, I won't paste it here]

//-----

[Now we needed to adapt this interface to an Appender, here's the appender with the Thread specific filter. Note: convertLog4JToMessageEvent just converts LoggingEvent to MessageEvent]

//----- .... public static final Appender createLog4JAppenderAdpater(MessageListener listener) { return Log4jAppender.create(listener); }

private static final class Log4jAppender extends AppenderSkeleton { private MessageListener listener;

private Log4jAppender(){} public static Log4jAppender create(MessageListener listener) { Log4jAppender appender = new Log4jAppender();

appender.listener = listener;

final Thread threadThatCreatedTheAppender = Thread.currentThread();

appender.addFilter(new Filter(){ public int decide(LoggingEvent event) { if (Thread.currentThread() == threadThatCreatedTheAppender) { return Filter.ACCEPT; } return Filter.DENY; } }); return appender; }

protected void append(LoggingEvent event) { listener.receiveMessage(convertLog4JToMessageEvent(event)); }

public void close() { listener = null; }

public boolean requiresLayout() { return false; } }

// -------------

[Now, at the point of code where you can use this:]

.... Logger loggerWeAreInterestedIn = Logger.getLogger(ClassWayDownHierachy.class);

Appender appender = MessageListenerUtils.createLog4JAppenderAdpater(messageListener);

loggerWeAreInterestedIn.addAppender(appender);

try{ someObject.doSomeMethod(); }finally{ loggerWeAreInterestedIn.removeAppender(appender); }

It's very important to remove the appender in the finally block otherwise you will be adding lots of appenders over time and will leak memory. There is probably a performance hit in doing all this, but sometimes that's better than the alternatives. It's not clean, but it does work. You might want to do something different than adapt the LoggingEvent to another class, but hopefully you can see the pattern.

Hope this helps someone, or is food for further discussion.

regards,