[logback-dev] [JIRA] Commented: (LBCLASSIC-166) Static logger references in shared classes doesn't work with JNDIContextSelector

Gabriele Contini (JIRA) noreply-jira at qos.ch
Tue Nov 3 17:44:44 CET 2009

    [ http://jira.qos.ch/browse/LBCLASSIC-166?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=11354#action_11354 ] 

Gabriele Contini commented on LBCLASSIC-166:

Hi Ceki,
My situation is a bit different. I have two ear inside the container (jboss):

  |__ ejbjar1.ejb
  |__ web1.war
  |__ ejbjar2.ejb
  |__ web2.war
I want to be able to separate their logs in two different directories, simply placing two configuration files in my jboss classpath directory, let's say logback-app1.xml and logback-app2.xml. (I also placed a third file logback.xml to capture logs without a context.)

Then i configured the ContextJNDISelector as explained in wiki. This works fine, the logs produced from web1.war and web2.war are fully separated and the ejb ones are "almost" separated (there is a little issue with static logger and ejb timers but not important here).

Problem arises with the logs generated by Hibernate (latest version of this library use slf4j api). Jboss uses Hibernate for persistence and includes it in its shared libraries. So when my ejbs need to be persisted call Jboss EntityManager that in turn calls Hibernate. I want the logs of Hibernate generated by app1 are separated from the logs of hibernate generated by app2, and i want to enable debug logs for app1 from logback-app1.xml leaving unchanged the logs produced by app2. 

ClassLoader schema could be like this:

Jboss CLassLoader (hibernate.jar, logback-classic.jar, slf4j.jar, logback-app1.xml, logback-app2.xml, logback.xml )
   |__ ejbjar1.ejb ClassLoader 
   |         |__ web1.war ClassLoader
   |__ ejbjar2.ejb ClassLoader    
             |__ web2.war ClassLoader
Hibernate uses static loggers and it seem to ignore the context selector: all the hibernate logs produced by the two application are catched by the (no context) logback.xml. (i suspect the static loggers are already initialized when the logging call arrives and the threadLocal variable inside ContextJNDISelector is ignored). Seem that context selection had to be done at a later stage (maybe when the logger is used).

Hibernate is just an example. Many other libraries (such as jdbc drivers, jca connectors...) requires some installation in container's shared libs, and the static logger approach is quite used. 

Let me know if you need further explanation. 
Thanks in advance for your attention.

> Static logger references in shared classes doesn't work with JNDIContextSelector
> --------------------------------------------------------------------------------
>                 Key: LBCLASSIC-166
>                 URL: http://jira.qos.ch/browse/LBCLASSIC-166
>             Project: logback-classic
>          Issue Type: New Feature
>          Components: Other
>    Affects Versions: 0.917
>            Reporter: Gabriele Contini
>            Assignee: Logback dev list
> The issue was already described in: LBCLASSIC-87 by Lars Ködderitzsch
> {quote}
> As Jens already pointed out the most common pattern to logging (even in common libaries as Jakarta Commons, Spring whatsoever) is using a static logger, eg.
> public class XY {
>     private static [final] Logger log = LoggerFactory.getLogger(XY.class);
>     ...
> }
> If such libraries are shared (either by being in tomcats shared libs, or by being directly in the ear) by multiple webapps, the logger context wins in which the original loading of the logging class (aka XY, see above) happens.
> To make an example.
> An ear contains two webapplications A and B, both have different logger context CtxA and CtxB.
> A library (say Spring for instance) is place in the ear and both webapps reference the library through their MANIFEST.MF.
> On application startup webapp A gets initialized first, during initialisation the classes of the shared libary (Spring) are loaded, therefor static loggers initialized with the context CtxA.
> Now webapp B gets initialized, classes of the shared libary are already loaded by the EARClassloader, the loggers continue to use CtxA.
> At runtime regardless of wich logger context will be set by context selectors of the webapps, all logging done by the shared classes will always go to CtxA.
> One can argue that common libaries should not use static loggers, but always obtain loggers freshly from the LoggerFactory. But that is a pipe dream, because the de-facto pattern in obtaining and using a logger is through a static field as depicted above.
> To achieve true per-webapp logging, already initialized loggers need to be able to switch logger contexts, for instance through TreadLocal or other mechanisms.
> {quote}
> And was closed with:
> {quote}
> If you need static references problem to be dealt with, then please file a *new* jira issue.
> {quote}
> I want to separate hibernate logs in my j2ee application (under jboss).  Hibernate is included in server libs, and it uses static loggers:
> {code}
> public class XY {
>     private static [final] Logger log = LoggerFactory.getLogger(XY.class);
>     ...
> }
> {code}
> I also want to use separate configuration files for each j2ee application (so sifting appender is not enough), thus i'm using the JndiContextSelector. 
> Logback is unable to switch context once hibernate is initialized, and the logger separation doesn't work for static loggers in shared libraries.
> ---
> I also tried to do my own ContextSelector in order to have a Logger that perform a jndi lookup when it's needed but:
> * ''LoggerContext'' has a method ''getLogger(String)'' that is final. I can't override LoggerContext and return my own instance of Logger.
> * In my opinion the ''contextSelector.getLoggerContext()'' could return a ''ILoggerFactory'' (there is no need it returns a full ''LoggerContext''
> Best regards.
> Gabriele Contini

This message is automatically generated by JIRA.
If you think it was sent incorrectly contact one of the administrators: http://jira.qos.ch/secure/Administrators.jspa
For more information on JIRA, see: http://www.atlassian.com/software/jira


More information about the logback-dev mailing list