Package com.googlecode.psiprobe.tools.logging.logback

Source Code of com.googlecode.psiprobe.tools.logging.logback.LogbackFactoryAccessor

/*
* Licensed under the GPL License.  You may not use this file except in
* compliance with the License.  You may obtain a copy of the License at
*
*     http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
*
* THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
* MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*/
package com.googlecode.psiprobe.tools.logging.logback;

import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import org.apache.commons.beanutils.MethodUtils;

import com.googlecode.psiprobe.tools.logging.DefaultAccessor;

/**
* Wraps a Logback logger factory from a given web application class loader.
*
* <p>
* All Logback classes are loaded via the given class loader and not via psi-probe's own
* class loader. For this reasons, all methods on Logback objects are invoked via reflection.
* </p>
* <p>
* This way, we can even handle different versions of Logback embedded in different WARs.
* </p>
*
* @author Harald Wellmann
*/
public class LogbackFactoryAccessor extends DefaultAccessor {

    private LogbackFactoryAccessor() {
       
    }

    /**
     * Attempts to access a Logback logger factory via the given class loader.
     * 
     * @param cl the ClassLoader to use when fetching the factory
     * @return Logback factory wrapper, or {@code null} if the SLF4J binding is
     *         not Logback or if there is no SLF4J binding at all
     */
    public static LogbackFactoryAccessor create(ClassLoader cl) {
        try {
            // Get the singleton SLF4J binding, which may or may not be Logback, depending on the           
            // binding.
            Class clazz = cl.loadClass("org.slf4j.impl.StaticLoggerBinder");
            Method m1 = MethodUtils.getAccessibleMethod(clazz, "getSingleton", new Class[]{});
            Object singleton = m1.invoke(null, null);
            Method m = MethodUtils.getAccessibleMethod(clazz, "getLoggerFactory", new Class[]{});
            Object loggerFactory = m.invoke(singleton, null);
           
            // Check if the binding is indeed logback, return null otherwise
            Class loggerFactoryClass = cl.loadClass("ch.qos.logback.classic.LoggerContext");           
            if (loggerFactoryClass.isInstance(loggerFactory)) {
                LogbackFactoryAccessor accessor = new LogbackFactoryAccessor();           
                accessor.setTarget(loggerFactory);
                return accessor;
            } else {
                return null;
            }
        } catch (Exception e) {
            return null;
        }
    }

    /**
     * Returns the Logback root logger.
     *
     * @return the root logger
     */
    public LogbackLoggerAccessor getRootLogger() {
        // Logback has no dedicated getRootLogger() method, so we simply access the root logger
        // by its well-defined name.
        return getLogger("ROOT");
    }

    /**
     * Returns the Logback logger with a given name.
     *
     * @return the Logger with the given name
     */
    public LogbackLoggerAccessor getLogger(String name) {
        try {
            Class clazz = getTarget().getClass();
            Method m = MethodUtils.getAccessibleMethod(clazz, "getLogger", new Class[] {String.class});
            Object logger = m.invoke(getTarget(), new Object[] {name});

            LogbackLoggerAccessor accessor = new LogbackLoggerAccessor();
            accessor.setTarget(logger);
            accessor.setApplication(getApplication());
            return accessor;

        } catch (Exception e) {
            log.error(getTarget() + ".getLogger(\"" + name + "\") failed", e);
            return null;
        }
    }

    /**
     * Returns a list of wrappers for all Logback appenders that have an
     * associated logger.
     *
     * @return a list of {@link LogbackAppenderAccessor}s representing all
     *         appenders that are in use
     */
    public List getAppenders() {
        List appenders = new ArrayList();
        try {
            Class clazz = getTarget().getClass();
            Method m = MethodUtils.getAccessibleMethod(clazz, "getLoggerList", new Class[]{});
            List loggers = (List) m.invoke(getTarget(), null);
            Iterator it = loggers.iterator();
            while (it.hasNext()) {
                LogbackLoggerAccessor accessor = new LogbackLoggerAccessor();
                accessor.setTarget(it.next());
                accessor.setApplication(getApplication());

                appenders.addAll(accessor.getAppenders());
            }
        } catch (Exception e) {
            log.error(getTarget() + ".getLoggerList() failed", e);
        }
        return appenders;
    }

}
TOP

Related Classes of com.googlecode.psiprobe.tools.logging.logback.LogbackFactoryAccessor

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.