logging-log4j-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Ceki Gülcü <c...@qos.ch>
Subject Re: cvs commit: jakarta-log4j-sandbox/src/java/org/apache/log4j/selector ContextClassLoaderSelector.java
Date Fri, 14 Feb 2003 15:32:26 GMT
Jake,

Have you already tried using JNDI-based RepositorySelector?

At 05:58 14.02.2003 +0000, you wrote:
>hoju        2003/02/13 21:58:56
>
>   Modified:    src/java/org/apache/log4j/selector
>                         ContextClassLoaderSelector.java
>   Log:
>   Updated Javadoc.  Also, modified code to conform to checkstyle.
>
>   Jake
>
>   Revision  Changes    Path
>   1.2       +94 
> -45 
> jakarta-log4j-sandbox/src/java/org/apache/log4j/selector/ContextClassLoaderSelector.java
>
>   Index: ContextClassLoaderSelector.java
>   ===================================================================
>   RCS file: 
> /home/cvs/jakarta-log4j-sandbox/src/java/org/apache/log4j/selector/ContextClassLoaderSelector.java,v
>   retrieving revision 1.1
>   retrieving revision 1.2
>   diff -u -r1.1 -r1.2
>   --- ContextClassLoaderSelector.java   4 Feb 2003 06:28:16 -0000       1.1
>   +++ ContextClassLoaderSelector.java   14 Feb 2003 05:58:56 -0000      1.2
>   @@ -4,64 +4,113 @@
>     * This software is published under the terms of the Apache Software
>     * License version 1.1, a copy of which has been included with this
>     * distribution in the LICENSE.txt file.  */
>   -
>    package org.apache.log4j.selector;
>
>   -import org.apache.log4j.spi.RepositorySelector;
>   -import org.apache.log4j.spi.LoggerRepository;
>   -import org.apache.log4j.spi.RootCategory;
>    import org.apache.log4j.Hierarchy;
>    import org.apache.log4j.Level;
>    import org.apache.log4j.LogManager;
>   +import org.apache.log4j.spi.LoggerRepository;
>   +import org.apache.log4j.spi.RepositorySelector;
>   +import org.apache.log4j.spi.RootCategory;
>   +
>    import java.util.Collections;
>    import java.util.Map;
>    import java.util.WeakHashMap;
>
>   +
>    /**
>   - * @author  Jacob Kjome
>   + * Log4j Contextual ClassLoader Selector
>   + *
>   + * <p>based primarily on Ceki Gülcü's article <h3>Supporting the Log4j
>   + * <code>RepositorySelector</code> in Servlet Containers</h3> at:
>   + * http://qos.ch/containers/sc.html</p>
>   + *
>   + * <p>By default, the class static <code>RepositorySelector</code>

> variable
>   + * of the <code>LogManager</code> class is set to a trivial
>   + * <code>RepositorySelector</code> implementation which always
>   + * returns the same logger repository, which also happens to be a
>   + * <code>Hierarchy</code> instance. In other words, by default log4j 
> will use
>   + * one hierarchy, the default hierarchy. This behavior can be 
> overridden via
>   + * the <code>LogManager</code>'s
>   + * <code>setRepositorySelector(RepositorySelector, Object)</code> 
> method.</p>
>   + *
>   + * <p>That is where this class enters the picture.  It can be used to 
> define a
>   + * custom logger repository.  It makes use of the fact that each 
> webapp runs
>   + * in its own classloader.  This means we can track hierachies using the
>   + * webapp classloader as the key to each individual hierarchy.  That 
> is what
>   + * is meant by "contextual classloader" selector.  Each classloader 
> provides a
>   + * unique logging context.</p>
>   + *
>   + * <p>Of course, this means that this class will only work in 
> containers which
>   + * provide for separate classloaders, so that is something to keep in 
> mind.
>   + * This methodology will certainly work in containers such as Tomcat 
> 4/5 and
>   + * probably a multitude of others.  However, Tomcat 4.x.x and 5.x.x 
> are the only
>   + * containers currently tested.</p>
>   + *
>   + * @author  Jacob Kjome
>   + * @since 1.3
>     */
>    public class ContextClassLoaderSelector implements RepositorySelector {
>   -
>   -  // key: current thread's ContextClassLoader,
>   -  // value: Hierarchy instance
>   -  final private static Map hierMap = Collections.synchronizedMap(new 
> WeakHashMap());
>   -
>   -  final private static ContextClassLoaderSelector singleton = new 
> ContextClassLoaderSelector();
>   -  private static boolean initialized = false;
>   -
>   -  private ContextClassLoaderSelector() {}
>   -
>   -  public LoggerRepository getLoggerRepository() {
>   -    ClassLoader cl = Thread.currentThread().getContextClassLoader();
>   -    Hierarchy hierarchy = (Hierarchy) hierMap.get(cl);
>   -
>   -    if(hierarchy == null) {
>   -      hierarchy = new Hierarchy(new RootCategory((Level) Level.DEBUG));
>   -      hierMap.put(cl, hierarchy);
>   -    }
>   -    return hierarchy;
>   -  }
>   -
>   -  /**
>   -   * The Container should initialize the logger repository for each
>   -   * webapp upon startup or reload.  In this case, it is controllable
>   -   * via each webapp.
>   -   */
>   -  public static void doIdempotentInitialization() {
>   -    if(!initialized) {
>   -      try {
>   -        Object guard = new Object();
>   -        LogManager.setRepositorySelector(singleton, guard);
>   -        initialized = true;
>   -      } catch (IllegalArgumentException iae) {
>   -        //either ignore the exception or log the fact that the setting 
> of this
>   -        //custom repository selector failed because another had been 
> set previously
>   -        // and maybe we should set "initialized" to "true" in here so 
> this exception doesn't
>   -        // occur again in this class
>   -      }
>   +    /**
>   +     * key: current thread's ContextClassLoader,
>   +     * value: Hierarchy instance
>   +     */
>   +    private static final Map HIER_MAP =
>   +        Collections.synchronizedMap(new WeakHashMap());
>   +
>   +    /**
>   +     * singleton instance for this class
>   +     */
>   +    private static final ContextClassLoaderSelector SINGLETON =
>   +        new ContextClassLoaderSelector();
>   +
>   +    /**
>   +     * remember idempotent initialization status
>   +     */
>   +    private static boolean initialized = false;
>   +
>   +    /**
>   +     * private no-args constructor to guarantee no outside code can 
> create an
>   +     * instance
>   +     */
>   +    private ContextClassLoaderSelector() {
>        }
>   -  }
>
>   -}
>   +    /**
>   +     * implemented RepositorySelector interface method.
>   +     *
>   +     * @return the appropriate classloader-keyed 
> Hierarchy/LoggerRepository
>   +     */
>   +    public LoggerRepository getLoggerRepository() {
>   +        ClassLoader cl = Thread.currentThread().getContextClassLoader();
>   +        Hierarchy hierarchy = (Hierarchy) HIER_MAP.get(cl);
>   +
>   +        if (hierarchy == null) {
>   +            hierarchy = new Hierarchy(new RootCategory((Level) 
> Level.DEBUG));
>   +            HIER_MAP.put(cl, hierarchy);
>   +        }
>
>   +        return hierarchy;
>   +    }
>
>   +    /**
>   +     * The Container should initialize the logger repository for each
>   +     * webapp upon startup or reload.  In this case, it is controllable
>   +     * via each webapp.
>   +     */
>   +    public static void doIdempotentInitialization() {
>   +        if (!initialized) {
>   +            try {
>   +                Object guard = new Object();
>   +                LogManager.setRepositorySelector(SINGLETON, guard);
>   +                initialized = true;
>   +            } catch (IllegalArgumentException iae) {
>   +                // either ignore the exception or log the fact that the
>   +                // setting of this custom repository selector failed 
> because
>   +                // another had been set previously and maybe we should set
>   +                // "initialized" to "true" in here so this exception 
> doesn't
>   +                // occur again in this class
>   +            }
>   +        }
>   +    }
>   +}
>
>
>
>
>---------------------------------------------------------------------
>To unsubscribe, e-mail: log4j-dev-unsubscribe@jakarta.apache.org
>For additional commands, e-mail: log4j-dev-help@jakarta.apache.org

--
Ceki 


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


Mime
View raw message