[slf4j-user] slf4j logger -> Servlet container log : How to?

Jacob Kjome hoju at visi.com
Thu May 13 07:51:51 CEST 2010


See comments inline below...

On 5/12/2010 10:35 AM, Thorbjoern Ravn Andersen wrote:
> Den 12/05/10 06.27, Jacob Kjome skrev:
>>
>>> Ok. So if I understand this correctly, your approach uses a servlet
>>> listener to register all contexts keyed by the last part of their
>>> context path, and you tell the appender in question which ServletContext
>>> to retrieve and then forward to that logger.
>>>
>>
>> Each webapp that defines the servlet context listener can participate
>> in servlet context logging.  However, how many contexts the the
>> servlet context appender handles depends on how you set up
>> classloading.  If you deploy the log4j-sandbox.jar, along with
>> log4j.jar, in WEB-INF/lib and use child-first classloading, then the
>> servlet context appender will only ever deal with a single context;
>> the current one.  On the other hand, if log4j-sandbox.jar and
>> log4j.jar are shared, e.g., at the container level, then it would
>> handle more context paths.
> 
> Ok, the crucial trick is child-first loading and log4j deployments in
> each web container.  Makes sense now.
> 

That's not quite the point I was trying to make.  Using child-first classloading
with log4j.jar and log4j-sandbox.jar in WEB-INF/lib, the servlet context
appender's static map of servlet contexts will only ever contain one context.  I
was just pointing this out as a clarification, but I think it may have confused
matters.  Anyway, you can certainly place log4j.jar and log4j-sandbox.jar in a
shared location.  In that case, the static map would contain multiple contexts.
It should work either way.

The important bit is that each webapp loads their context in the servlet context
appender's static map, using the servlet context listener, prior to configuring
the logger repository.  This necessarily means that each app uses its own logger
repository, which can be the default one **only** if using child-first
classloading.  Otherwise, you must use a repository selector to maintain a
separate logger repository.  Either way, you must manually configure Log4j
**after** the servlet context listener has had a chance to register the servlet
context in the servlet context appender's static map.

I hope that's a bit more clear.  I was a bit foggy on this stuff myself after
having not looked at it for a while.

> 
>>> Will this also work with multiple web apps using slf4j, or will they go
>>> to the same appender?
>>>
>>
>> It's been a while since I used it or studied it closely, but it should
>> handle as many contexts as you give it.  Note that I've never tried it
>> via SLF4J, only directly using Log4j.
>>
>> BTW, the way I've used this in the past is either to place the jars in
>> WEB-INF/lib and use child-first classloading or use a logger
>> repository selector.  I always manually configure Log4j after letting
>> the servlet context listener register the context to the appender. 
>> Then in Tomcat, for instance, I place log4j.jar in a shared lib
>> location along with log4j.properties, meant for configuring the server
>> to use Log4j, which looks somewhat like below.  So, the server has its
>> own log4j configuration while each webapp has its own configuration. 
>> And when my app either logs directly to the servlet context or logs
>> via the servlet context log appender, I have defined exactly where the
>> output goes; to "${catalina.base}/logs/localhost_mycontext.log".
>>
>> Oh, and I had to follow these instructions to get Tomcat to use Log4j...
>> http://tomcat.apache.org/tomcat-6.0-doc/logging.html#log4j

> Thank you.  It is a very interesting approach.
> 

You're welcome.

Note that I've only ever tested this to work under Tomcat.  YMMV under other
containers.  Also note that this stuff was written a fairly long time ago and
never placed into any official release.  It can probably use improvement.  I
encourage you to add to it if you see deficiencies or possibly a better approach.


Jake


More information about the slf4j-user mailing list