Package com.googlecode.psiprobe.beans

Source Code of com.googlecode.psiprobe.beans.LogResolverBean$LogDestinationComparator

/*
* 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.beans;

import com.googlecode.psiprobe.model.Application;
import com.googlecode.psiprobe.model.DisconnectedLogDestination;
import com.googlecode.psiprobe.tools.ApplicationUtils;
import com.googlecode.psiprobe.tools.Instruments;
import com.googlecode.psiprobe.tools.logging.DefaultAccessor;
import com.googlecode.psiprobe.tools.logging.FileLogAccessor;
import com.googlecode.psiprobe.tools.logging.LogDestination;
import com.googlecode.psiprobe.tools.logging.catalina.CatalinaLoggerAccessor;
import com.googlecode.psiprobe.tools.logging.commons.CommonsLoggerAccessor;
import com.googlecode.psiprobe.tools.logging.jdk.Jdk14LoggerAccessor;
import com.googlecode.psiprobe.tools.logging.jdk.Jdk14ManagerAccessor;
import com.googlecode.psiprobe.tools.logging.log4j.Log4JLoggerAccessor;
import com.googlecode.psiprobe.tools.logging.log4j.Log4JManagerAccessor;
import com.googlecode.psiprobe.tools.logging.logback.LogbackLoggerAccessor;
import com.googlecode.psiprobe.tools.logging.logback.LogbackFactoryAccessor;
import java.io.File;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import org.apache.catalina.Context;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.util.ClassUtils;

/**
*
* @author Mark Lewis
*/
public class LogResolverBean {

    protected final Log logger = LogFactory.getLog(getClass());

    private ContainerWrapperBean containerWrapper;
    private List stdoutFiles = new ArrayList();

    public ContainerWrapperBean getContainerWrapper() {
        return containerWrapper;
    }

    public void setContainerWrapper(ContainerWrapperBean containerWrapper) {
        this.containerWrapper = containerWrapper;
    }

    public List getStdoutFiles() {
        return stdoutFiles;
    }

    public void setStdoutFiles(List stdoutFiles) {
        this.stdoutFiles = stdoutFiles;
    }

    public List getLogDestinations(boolean all) {
        List allAppenders = getAllLogDestinations();

        if (allAppenders != null) {
            //
            // this list has to guarantee the order in which elements are added
            //
            List uniqueList = new LinkedList();
            Comparator cmp = new LogDestinationComparator(all);

            Collections.sort(allAppenders, cmp);
            for (int i = 0; i < allAppenders.size(); i++) {
                LogDestination dest = (LogDestination) allAppenders.get(i);
                if (Collections.binarySearch(uniqueList, dest, cmp) < 0) {
                    if (all || dest.getFile() == null || dest.getFile().exists()) {
                        uniqueList.add(new DisconnectedLogDestination(dest));
                    }
                }
            }
            return uniqueList;
        }
        return null;
    }

    public List getLogSources(File logFile) {
        List filtered = new LinkedList();
        List sources = getLogSources();
        for (int i = 0; i < sources.size(); i++) {
            LogDestination dest = (LogDestination) sources.get(i);
            if (logFile.equals(dest.getFile())) {
                filtered.add(dest);
            }
        }
        return filtered;
    }

    public List getLogSources() {
        List sources = new LinkedList();

        List allAppenders = getAllLogDestinations();
        if (allAppenders != null) {
            Comparator cmp = new LogSourceComparator();

            Collections.sort(allAppenders, cmp);
            for (int i = 0; i < allAppenders.size(); i++) {
                LogDestination dest = (LogDestination) allAppenders.get(i);
                if (Collections.binarySearch(sources, dest, cmp) < 0) {
                    sources.add(new DisconnectedLogDestination(dest));
                }
            }
        }
        return sources;
    }

    private List getAllLogDestinations() {
        if (Instruments.isInitialized()) {
            List allAppenders = new ArrayList();

            //
            // interrogate classloader hierarchy
            //
            ClassLoader cl2 = Thread.currentThread().getContextClassLoader().getParent();
            while (cl2 != null) {
                interrogateClassLoader(cl2, null, allAppenders);
                cl2 = cl2.getParent();
            }

            //
            // check for known stdout files, such as "catalina.out"
            //
            interrogateStdOutFiles(allAppenders);

            //
            // interrogate webapp classloaders and avilable loggers
            //
            List contexts = getContainerWrapper().getTomcatContainer().findContexts();
            interrogateApplicationClassLoaders(contexts, allAppenders);

            return allAppenders;
        }
        return null;
    }

    public LogDestination getLogDestination(String logType, String webapp, boolean context, boolean root, String logName, String logIndex) {
        Context ctx = null;
        Application application = null;
        if (webapp != null) {
            ctx = getContainerWrapper().getTomcatContainer().findContext(webapp);
            if (ctx != null) {
                application = ApplicationUtils.getApplication(ctx);
            }
        }

        if ("stdout".equals(logType) && logName != null) {
            return getStdoutLogDestination(logName);
        } else if ("catalina".equals(logType) && ctx != null) {
            return getCatalinaLogDestination(ctx, application);
        } else if (logIndex != null
                && ("jdk".equals(logType)
                || "log4j".equals(logType)
                || "logback".equals(logType))) {
            if (context && ctx != null) {
                return getCommonsLogDestination(ctx, application, logIndex);
            }
            ClassLoader cl;
            ClassLoader prevCl = null;
            if (ctx != null) {
                cl = ctx.getLoader().getClassLoader();
                prevCl = ClassUtils.overrideThreadContextClassLoader(cl);
            } else {
                cl = Thread.currentThread().getContextClassLoader().getParent();
            }
            try {
                if ((root || logName != null) && logIndex != null) {
                    if ("jdk".equals(logType)) {
                        return getJdk14LogDestination(cl, application, root, logName, logIndex);
                    } else if ("log4j".equals(logType)) {
                        return getLog4JLogDestination(cl, application, root, logName, logIndex);
                    } else if ("logback".equals(logType)) {
                        return getLogbackLogDestination(cl, application, root, logName, logIndex);
                    }
                }
            } finally {
                if (prevCl != null) {
                    ClassUtils.overrideThreadContextClassLoader(prevCl);
                }
            }
        }
        return null;
    }

    private void interrogateApplicationClassLoaders(List contexts, List allAppenders) {
        for (int i = 0; i < contexts.size(); i++) {

            Context ctx = (Context) contexts.get(i);
            Application application = ApplicationUtils.getApplication(ctx);

            ClassLoader cl = ctx.getLoader().getClassLoader();

            try {
                Object contextLogger = getContainerWrapper().getTomcatContainer().getLogger(ctx);
                if (contextLogger != null) {
                    if (contextLogger.getClass().getName().startsWith("org.apache.commons.logging")) {
                        CommonsLoggerAccessor commonsAccessor = new CommonsLoggerAccessor();
                        commonsAccessor.setTarget(contextLogger);
                        commonsAccessor.setApplication(application);
                        allAppenders.addAll(commonsAccessor.getDestinations());
                    } else if (contextLogger.getClass().getName().startsWith("org.apache.catalina.logger")) {
                        CatalinaLoggerAccessor catalinaAccessor = new CatalinaLoggerAccessor();
                        catalinaAccessor.setApplication(application);
                        catalinaAccessor.setTarget(contextLogger);
                        allAppenders.add(catalinaAccessor);
                    }
                }
            } catch (Throwable e) {
                logger.error("Could not interrogate context logger for " + ctx.getName() + ". Enable debug logging to see the trace stack");
                logger.debug(e);
                //
                // make sure we always re-throw ThreadDeath
                //
                if (e instanceof ThreadDeath) {
                    throw (ThreadDeath) e;
                }
            }

            if (application.isAvailable()) {
                ClassLoader prevCl = ClassUtils.overrideThreadContextClassLoader(cl);
                try {
                    interrogateClassLoader(cl, application, allAppenders);
                } catch (Exception e) {
                    logger.error("Could not interrogate classloader loggers for " + ctx.getName() + ". Enable debug logging to see the trace stack");
                    logger.debug(e);
                } finally {
                    if (prevCl != null) {
                        ClassUtils.overrideThreadContextClassLoader(prevCl);
                    }
                }
            }
        }
    }

    private void interrogateClassLoader(ClassLoader cl, Application application, List appenders) {

        Jdk14ManagerAccessor jdk14accessor = Jdk14ManagerAccessor.create(cl);
        if (jdk14accessor != null) {
            jdk14accessor.setApplication(application);
            appenders.addAll(jdk14accessor.getHandlers());
        }

        // check for Log4J loggers
        Log4JManagerAccessor log4JAccessor = Log4JManagerAccessor.create(cl);
        if (log4JAccessor != null) {
            log4JAccessor.setApplication(application);
            appenders.addAll(log4JAccessor.getAppenders());
        }

        // check for Logback loggers
        LogbackFactoryAccessor logbackAccessor = LogbackFactoryAccessor.create(cl);
        if (logbackAccessor != null) {
            logbackAccessor.setApplication(application);
            appenders.addAll(logbackAccessor.getAppenders());
        }
    }

    private void interrogateStdOutFiles(List appenders) {
        for (Iterator it = stdoutFiles.iterator(); it.hasNext(); ) {
            String fileName = (String) it.next();
            File stdout = new File(System.getProperty("catalina.base"), "logs/" + fileName);
            if (stdout.exists()) {
                FileLogAccessor fla = new FileLogAccessor();
                fla.setName(fileName);
                fla.setFile(stdout);
                appenders.add(fla);
            }
        }

    }

    private LogDestination getStdoutLogDestination(String logName) {
        for (Iterator it = stdoutFiles.iterator(); it.hasNext(); ) {
            String fileName = (String) it.next();
            if (fileName.equals(logName)) {
                File stdout = new File(System.getProperty("catalina.base"), "logs/" + logName);
                if (stdout.exists()) {
                    FileLogAccessor fla = new FileLogAccessor();
                    fla.setName(fileName);
                    fla.setFile(stdout);
                    return fla;
                }
            }
        }
        return null;
    }

    private LogDestination getCatalinaLogDestination(Context ctx, Application application) {
        Object log = getContainerWrapper().getTomcatContainer().getLogger(ctx);
        if (log != null) {
            CatalinaLoggerAccessor logAccessor = new CatalinaLoggerAccessor();
            logAccessor.setTarget(log);
            logAccessor.setApplication(application);
            if (logAccessor.getFile().exists()) {
                return logAccessor;
            }
        }
        return null;
    }

    private LogDestination getCommonsLogDestination(Context ctx, Application application, String logIndex) {
        Object contextLogger = getContainerWrapper().getTomcatContainer().getLogger(ctx);
        CommonsLoggerAccessor commonsAccessor = new CommonsLoggerAccessor();
        commonsAccessor.setTarget(contextLogger);
        commonsAccessor.setApplication(application);
        return commonsAccessor.getDestination(logIndex);
    }

    private LogDestination getJdk14LogDestination(ClassLoader cl, Application application, boolean root, String logName, String handlerIndex) {
        Jdk14ManagerAccessor manager = Jdk14ManagerAccessor.create(cl);
        if (manager != null) {
            manager.setApplication(application);
            Jdk14LoggerAccessor log = (root ? manager.getRootLogger() : manager.getLogger(logName));
            if (log != null) {
                return log.getHandler(handlerIndex);
            }
        }
        return null;
    }

    private LogDestination getLog4JLogDestination(ClassLoader cl, Application application, boolean root, String logName, String appenderName) {
        Log4JManagerAccessor manager = Log4JManagerAccessor.create(cl);
        if (manager != null) {
            manager.setApplication(application);
            Log4JLoggerAccessor log = (root ? manager.getRootLogger() : manager.getLogger(logName));
            if (log != null) {
                return log.getAppender(appenderName);
            }
        }
        return null;
    }

    private LogDestination getLogbackLogDestination(ClassLoader cl, Application application, boolean root, String logName, String appenderName) {
        LogbackFactoryAccessor manager = LogbackFactoryAccessor.create(cl);
        if (manager != null) {
            manager.setApplication(application);
            LogbackLoggerAccessor log = (root ? manager.getRootLogger() : manager.getLogger(logName));
            if (log != null) {
                return log.getAppender(appenderName);
            }
        }
        return null;
    }

    private static class LogDestinationComparator implements Comparator {

        private boolean all;

        public LogDestinationComparator(boolean all) {
            this.all = all;
        }

        public int compare(Object o1, Object o2) {
            LogDestination d1 = (LogDestination) o1;
            LogDestination d2 = (LogDestination) o2;
            File f1 = d1.getFile();
            File f2 = d2.getFile();
            String name1 = (f1 == null ? "" : f1.getAbsolutePath());
            String name2 = (f2 == null ? "" : f2.getAbsolutePath());
            if (all) {
                Application a1 = d1.getApplication();
                Application a2 = d2.getApplication();
            if (a1 == null || a2 == null) {
                a1 = null;
                a2 = null;
            }
                String appName1 = (a1 == null ? "" : a1.getName());
                String appName2 = (a2 == null ? "" : a2.getName());
                String context1 = (d1.isContext() ? "is" : "not");
                String context2 = (d2.isContext() ? "is" : "not");
                String root1 = (d1.isRoot() ? "is" : "not");
                String root2 = (d2.isRoot() ? "is" : "not");
                String logType1 = d1.getLogType();
                String logType2 = d1.getLogType();
                char delim = '!';
                name1 = appName1 + delim + context1 + delim + root1 + delim + logType1 + delim + name1;
                name2 = appName2 + delim + context2 + delim + root2 + delim + logType2 + delim + name2;
            }
            return name1.compareTo(name2);
        }
    }

    private static class LogSourceComparator implements Comparator {

        public int compare(Object o1, Object o2) {
            if (o1 instanceof DefaultAccessor && o2 instanceof DefaultAccessor) {
                DefaultAccessor da1 = (DefaultAccessor) o1;
                DefaultAccessor da2 = (DefaultAccessor) o2;
                if (da1.getTarget() == da2.getTarget()) {
                    return 0;
                }
            }
            LogDestination d1 = (LogDestination) o1;
            LogDestination d2 = (LogDestination) o2;
            File f1 = d1.getFile();
            File f2 = d2.getFile();
            String filename1 = (f1 == null ? "" : f1.getAbsolutePath());
            String filename2 = (f2 == null ? "" : f2.getAbsolutePath());
            Application a1 = d1.getApplication();
            Application a2 = d2.getApplication();
            if (a1 == null || a2 == null) {
                a1 = null;
                a2 = null;
            }
            String appName1 = (a1 == null ? "" : a1.getName());
            String appName2 = (a2 == null ? "" : a2.getName());
            String logType1 = d1.getLogType();
            String logType2 = d1.getLogType();
            String context1 = (d1.isContext() ? "is" : "not");
            String context2 = (d2.isContext() ? "is" : "not");
            String root1 = (d1.isRoot() ? "is" : "not");
            String root2 = (d2.isRoot() ? "is" : "not");
            String logName1 = d1.getName();
            String logName2 = d2.getName();
            //String logIndex1 = d1.getIndex();
            //String logIndex2 = d2.getIndex();
            char delim = '!';
            String name1 = appName1 + delim + logType1 + delim + context1 + delim + root1 + delim + logName1 + delim + filename1;
            String name2 = appName2 + delim + logType2 + delim + context2 + delim + root2 + delim + logName2 + delim + filename2;
            return name1.compareTo(name2);
        }

    }

}
TOP

Related Classes of com.googlecode.psiprobe.beans.LogResolverBean$LogDestinationComparator

TOP
Copyright © 2015 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.