org.carrot2.webapp.LogInitContextListener.java Source code

Java tutorial

Introduction

Here is the source code for org.carrot2.webapp.LogInitContextListener.java

Source

/*
 * Carrot2 project.
 *
 * Copyright (C) 2002-2015, Dawid Weiss, Stanisaw Osiski.
 * All rights reserved.
 *
 * Refer to the full license file "carrot2.LICENSE"
 * in the root folder of the repository checkout or at:
 * http://www.carrot2.org/carrot2.LICENSE
 */

package org.carrot2.webapp;

import java.io.File;
import java.io.IOException;
import java.lang.reflect.Method;
import java.util.Collection;
import java.util.Map.Entry;

import javax.servlet.*;

import org.apache.commons.lang.StringUtils;
import org.apache.log4j.*;

import com.google.common.collect.*;

/**
 * Initializes file appenders to save logs to files named after the context path. Works
 * only if the container supports Servlet API 2.5.
 */
public class LogInitContextListener implements ServletContextListener {
    /**
     * An instance of this class will save itself in the application context under this
     * identifier.
     */
    public static final String CONTEXT_ID = LogInitContextListener.class.getName();

    /**
     * Any created {@link Appender}s.
     */
    private Multimap<Logger, Appender> appenders = ArrayListMultimap.create();

    /**
     * Callback hook from the application container. Initialize logging appenders
     * immediately or defer initialization until possible.
     */
    public void contextInitialized(ServletContextEvent event) {
        final ServletContext servletContext = event.getServletContext();
        if (servletContext.getAttribute(CONTEXT_ID) != null) {
            // Only one instance needed.
            return;
        }

        /*
         * If the container has Servlet 2.5 API, init loggers immediately. Otherwise, save
         * itself to the context and wait for {@link QueryProcessorServlet} to perform
         * deferred initialization.
         */
        try {
            final Method method = ServletContext.class.getMethod("getContextPath");
            final String contextPath = (String) method.invoke(servletContext);
            addAppenders(contextPath);
        } catch (RuntimeException e) {
            // Rethrow runtime exceptions, if any.
            throw e;
        } catch (Exception e) {
            /*
             * No servlet 2.5 API (getContextPath), save in the context for deferred
             * initialization.
             */
            servletContext.setAttribute(CONTEXT_ID, this);
        }
    }

    /**
     * Callback hook from the application container. Cleanup any created appenders and
     * unregister them from their loggers.
     */
    public void contextDestroyed(ServletContextEvent event) {
        for (Entry<Logger, Collection<Appender>> e : appenders.asMap().entrySet()) {
            final Logger logger = e.getKey();
            for (Appender a : e.getValue()) {
                logger.removeAppender(a);
                a.close();
            }
        }
        appenders.clear();
    }

    /**
     * Add appenders based on the provided context path.
     */
    void addAppenders(String contextPath) {
        final File logDir = getLogDir();
        if (logDir == null) {
            // No log dir.
            return;
        }

        try {
            final String contextPathName = getContextPathSegment(contextPath);

            addAppender(new File(logDir, "c2-" + contextPathName + "-queries.log"),
                    Logger.getLogger(QueryProcessorServlet.QUERY_LOG_NAME), "%d{ISO8601},%m%n");

            addAppender(new File(logDir, "c2-" + contextPathName + "-full.log"), Logger.getRootLogger(),
                    "%d{ISO8601},[%p],[%t],%c,%m%n");
        } catch (IOException e) {
            Logger.getRootLogger().warn("Could not initialize custom appenders.", e);
        }
    }

    /*
     * 
     */
    private void addAppender(File file, Logger logger, String pattern) throws IOException {
        final FileAppender appender = new DailyRollingFileAppender(new PatternLayout(pattern),
                file.getAbsolutePath(), "'.'yyyy-MM-dd");
        appender.setEncoding("UTF-8");
        appender.setAppend(true);

        logger.addAppender(appender);
        appenders.put(logger, appender);
    }

    /**
     * @return Returns the log directory to dump custom logs to. If null is returned, no
     *         log dir is defined and custom appenders should not be attached.
     */
    private static File getLogDir() {
        /*
         * Check for custom override of logs location.
         */
        final String customLogFolder = System.getProperty("carrot2.logs");
        if (!StringUtils.isEmpty(customLogFolder)) {
            File logDir = new File(customLogFolder);
            if (logDir.isDirectory()) {
                return logDir;
            }
        }

        /*
         * Check for catalina's (Tomcat) default log folder.
         */
        final String catalinaBase = System.getProperty("catalina.base");
        if (!StringUtils.isEmpty(catalinaBase) && new File(catalinaBase).isDirectory()) {
            final File logDir = new File(new File(catalinaBase), "logs");
            if (logDir.isDirectory()) {
                return logDir;
            }
        }

        /*
         * If null is returned, no log dir is defined and custom appenders should not be
         * attached.
         */
        return null;
    }

    /*
     * 
     */
    private static String getContextPathSegment(String contextPath) {
        if (StringUtils.isBlank(contextPath)) {
            contextPath = "root";
        }
        contextPath = contextPath.replaceAll("[^a-zA-Z0-9\\-]", "");
        return contextPath;
    }
}