You are viewing a plain text version of this content. The canonical link for it is here.
Posted to log4j-user@logging.apache.org by Ramakrishna Menon <ra...@oracle.com> on 2004/06/23 18:12:04 UTC

Re: Fw: ThreadLocalAppender for log4j?resending

Hi Paul
I was supposed to work on this thread and get back to this list but
was caught up in other priorities at work.
I am now trying to redo some of the investigations I did earlier and also
look at
adapting your solution. Thought I would summarize what I am thinking of
doing (my understanding of log4j is fairly limited - I just know how to
get a simple logger up and running with a simple config file:-))

To recall the original issue, it was to log a message on the rendered url.
Now in our application we are using log4j to log messages already. I want
to intercept these messages and render them in a url based on a flag
that is set on the url (or in the session.) Important thing is that a url
should get messages only from the request (or thread) that was handled
while its rendering.)

Now what I am thinking of doing is to
1. create a class which is an appender that intercepts the messsages and
writes it to a
       StringWriter with which it is initialized.
2. at the beginning of the routine that handles a request, I create a new
appender and initialize it
with the stringwriter. It appends to the stringwriter any messages that it
gets.

3. at the end of the routine request handling routine, I get the
stringwriter from the appender and
destroy it in a finally clause.

4. In the logging properties file I would add this appender as well ( I am
not sure if this is necessary
since I create this appender manually ?)

Does that sound right/sane/insane?

Any other comments/thoughts. btw, I remember thinking about using
ThreadLocal but dont see it relevant
here now - not sure I am missing something I thought earlier :)

Best Regards,
Menon:)
-------------------------------------------------------------
Ramakrishna M. Menon (A Rafi Fan - http://www.mohdrafi.com )
MBA, Berkeley
Oracle Corp.-> (650) 506-2343
http://websites.oraclecorp.com/websites/pub/oracleperformance/
-------------------------------------------------------------

----- Original Message ----- 
From: "Paul Smith" <pa...@lawlex.com.au>
To: "Log4J Users List" <lo...@logging.apache.org>
Sent: Tuesday, March 02, 2004 2:22 PM
Subject: Re: Fw: ThreadLocalAppender for log4j? resending


> 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,
>
> Paul Smith
>
>
>
>
>
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: log4j-user-unsubscribe@logging.apache.org
> For additional commands, e-mail: log4j-user-help@logging.apache.org
>
>


---------------------------------------------------------------------
To unsubscribe, e-mail: log4j-user-unsubscribe@logging.apache.org
For additional commands, e-mail: log4j-user-help@logging.apache.org