Uploaded image for project: 'logback'
  1. logback
  2. LOGBACK-326

LoggerContextFilter is useless (org.slf4j.Loggerfactory bug ++)



    • Icon: Bug Bug
    • Resolution: Fixed
    • Icon: Major Major
    • 0.9.19
    • None
    • logback-classic
    • None
    • Operating System: All
      Platform: All

    • 84


      Since LoggerFactory obtains the LoggerContext to use in its static init stage, using a LoggerContextFilter as described in Chapter 8 is completely useless, since the JNDI selector is never consulted again.

      Digging deeper on that issue reveals, that using a ContextJNDISelector (even if it would work) rarely leads to the intended behavior (e.g. webapp related logging), and is probably not thread safe wrt. common practice and intended logging. E.g. in tomcat we have two different cases:
      a) each webapp provides its own slfj4*.jar as well as logback.jar
      b) slfj4*.jar as well as logback.jar are shared via tomcat/common/lib or
      c) a und b mixed

      Well, to get things right, one can say case c) is unsupported .
      In case a) logback has its own playground, so using JNDI doesn't make sense at all, since the webapp/logback has its own playground - doesn't interfere with
      other web apps since loaded via its dedicated classloader.

      However case b) is a little bit more challenging. Here the LoggerFactory and other classes are Unable to render embedded object: File (shared) not found. between several webapps, since loading is delegated from the dedicated webapp classloader to the shared webapp classloader, which picks up everything in share/lib , common/lib. So right now in 0.9.7, even if one uses JNDISelector a per webapp logging is impossible: The first webapp, which asks for a LoggerFactory always wins! All other webapps, which ask later for a LoggerFactory.getLogger() will get a Logger from the LoggerContext associated with the first webapp, since the context is "cached", i.e. the JNDI selector gets never consulted again.

      Assuming the LoggerFactory problem gets fixed by using e.g.
      public static Logger getLogger(* *) {
      return StaticLoggerBinder.SINGLETON.getLoggerFactory().getLogger(**);
      there is still a problem wrt. common practice aka log* usage pattern and webapp shared classes, which can not be resolved by JNDI: Today most developer use something like:
      public class XY {
      private static [final] Logger log = LoggerFactory.getLogger(XY.class);
      That implies the same problem, as with the current LoggerFactory bug: The class gets the Logger from the context associated with the first webapp, which needs the shared class. And that's why all other webapps, which later need this class will use the the logger context of the first webapp. So e.g. if webapp A is configured to log to /var/log/a.log and another webapp B is configured to log to /var/log/b.log the loging output of shared classes will always go to /var/log/a.log if webapp used the classes in question first, no matter on which thread aka in which webapp the shared classes are used.

      So even if LoggerFactory gets fixed, JNDI selector is of little use, if one wants to have a webapp dedicated log as soon as shared classes are involved.

      The only way to solve the didcated webapp log problem a can think of, to introduce another level of indirection in the Logger.log* etc. method, which takes care of thread local settings and the settings of its parent threads (e.g. an application may start other threads, which do not inherit the thread local settings from the current thread ...). But this would probably influence the performance of logback in a rather negative way.

      Another idea might be an architecture re-design: sharing Loggers would be no problem because of thread local AppenderContext soft ref, which points to an Appender in the global AppenderStore singleton ...

      RFE: These problems should be reflected chapter 8 of the logback manual to avoid further confusion ...




            logback-dev Logback dev list
            elkner Jens Elkner
            0 Vote for this issue
            3 Start watching this issue