Package org.geoserver.logging

Source Code of org.geoserver.logging.LoggingUtils

/* (c) 2014 Open Source Geospatial Foundation - all rights reserved
* (c) 2001 - 2013 OpenPlans
* This code is licensed under the GPL 2.0 license, available at the root
* application directory.
*/
package org.geoserver.logging;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;
import java.util.Properties;

import javax.servlet.ServletContext;

import org.apache.log4j.Appender;
import org.apache.log4j.ConsoleAppender;
import org.apache.log4j.FileAppender;
import org.apache.log4j.LogManager;
import org.apache.log4j.PropertyConfigurator;
import org.geoserver.platform.GeoServerExtensions;
import org.geoserver.platform.GeoServerResourceLoader;
import org.geoserver.platform.resource.Paths;
import org.geoserver.platform.resource.Resource;
import org.geoserver.platform.resource.Resources;
import org.geoserver.platform.resource.Resource.Type;
import org.vfny.geoserver.global.ConfigurationException;

public class LoggingUtils {
   
    public static final String RELINQUISH_LOG4J_CONTROL = "RELINQUISH_LOG4J_CONTROL"
    public static final String GT2_LOGGING_REDIRECTION = "GT2_LOGGING_REDIRECTION";
    public static final String GEOSERVER_LOG_LOCATION = "GEOSERVER_LOG_LOCATION";
    public static enum GeoToolsLoggingRedirection {
        JavaLogging, CommonsLogging, Log4J;
       
        /**
         * Returns the enum value corresponding to the name (using case insensitive comparison)
         * or Log4j if no match is found
         * @param name
         * @return
         */
        public static GeoToolsLoggingRedirection findValue(String name) {
            for (GeoToolsLoggingRedirection value : values()) {
                if(value.name().equalsIgnoreCase(name))
                    return value;
            }
            return Log4J;
        }
    }

    public static void configureGeoServerLogging(GeoServerResourceLoader loader, InputStream loggingConfigStream, boolean suppressStdOutLogging, boolean suppressFileLogging, String logFileName) throws FileNotFoundException, IOException,
                            ConfigurationException {
            //JD: before we wipe out the logging configuration, save any appenders that are not
            // console or file based. This allows for other types of appenders to remain in tact
            // when geoserver is reloaded.
            List<Appender> appenders = new ArrayList();
            Enumeration a = LogManager.getRootLogger().getAllAppenders();
            while( a.hasMoreElements() ) {
                Appender appender = (Appender) a.nextElement();
                if ( !( appender instanceof ConsoleAppender || appender instanceof FileAppender )  ){
                    //save it
                    appenders.add( appender );
                }
            }
   
            Properties lprops = new Properties();
            lprops.load(loggingConfigStream);
            LogManager.resetConfiguration();
    //        LogLog.setQuietMode(true);
            PropertyConfigurator.configure(lprops);
    //        LogLog.setQuietMode(false);
           
            // configuring the log4j file logger
            if(!suppressFileLogging) {
                    Appender gslf = org.apache.log4j.Logger.getRootLogger().getAppender("geoserverlogfile");
                    if (gslf instanceof org.apache.log4j.RollingFileAppender) {
                        if (logFileName == null ) {
                            logFileName = new File(loader.findOrCreateDirectory("logs")"geoserver.log").getAbsolutePath();
                        } else {
                            if (!new File(logFileName).isAbsolute()) {
                                logFileName = new File(loader.getBaseDirectory(), logFileName).getAbsolutePath();
                                LoggingInitializer.LOGGER.fine("Non-absolute pathname detected for logfile.  Setting logfile relative to data dir.");
                            }
                        }
                        lprops.setProperty("log4j.appender.geoserverlogfile.File", logFileName);
                        PropertyConfigurator.configure(lprops);
                        LoggingInitializer.LOGGER.fine("Logging output to file '" + logFileName + "'");
                    } else if (gslf != null) {
                        LoggingInitializer.LOGGER.warning("'log4j.appender.geoserverlogfile' appender is defined, but isn't a RollingFileAppender.  GeoServer won't control the file-based logging.");
                    } else {
                        LoggingInitializer.LOGGER.warning("'log4j.appender.geoserverlogfile' appender isn't defined.  GeoServer won't control the file-based logging.");
                    }
            }
           
            // ... and the std output logging too
            if (suppressStdOutLogging) {
                LoggingInitializer.LOGGER.info("Suppressing StdOut logging.  If you want to see GeoServer logs, be sure to look in '" + logFileName + "'");
                Enumeration allAppenders = org.apache.log4j.Logger.getRootLogger().getAllAppenders();
                Appender curApp;
                while (allAppenders.hasMoreElements()) {
                    curApp = (Appender)allAppenders.nextElement();
                    if (curApp instanceof org.apache.log4j.ConsoleAppender) {
                        org.apache.log4j.Logger.getRootLogger().removeAppender(curApp);
                    }
                }
            }
           
            //add the appenders we saved above
            for ( Appender appender : appenders ) {
                LogManager.getRootLogger().addAppender( appender );
            }
            LoggingInitializer.LOGGER.fine("FINISHED CONFIGURING GEOSERVER LOGGING -------------------------");
        }

    public static void initLogging(GeoServerResourceLoader resourceLoader, String configFileName, boolean suppressStdOutLogging, String logFileName) throws Exception {
        //to initialize logging we need to do a couple of things:
        // 1)  Figure out whether the user has 'overridden' some configuration settings
        // in the logging system (not using log4j in commons-logging.properties or perhaps
        // has set up their own 'custom' log4j.properties file.
        // 2)  If they *have*, then we don't worry about configuring logging
        // 3)  If they haven't, then we configure logging to use the log4j config file
        // specified, and remove console appenders if the suppressstdoutlogging is true.
        LoggingInitializer.LOGGER.fine("CONFIGURING GEOSERVER LOGGING -------------------------");
       
        if (configFileName == null) {
            configFileName = "DEFAULT_LOGGING.properties";
            LoggingInitializer.LOGGER.warning("No log4jConfigFile defined in services.xml:  using 'DEFAULT_LOGGING.properties'");
        }
        Resource resource = resourceLoader.get( Paths.path("logs", configFileName) );
        if( resource == null || resource.getType() == Type.UNDEFINED ){
            //hmm, well, we don't have a log4j config file and this could be due to the fact
            //that this is a data-dir upgrade.  We can count on the DEFAULT_LOGGING.properties file
            //being present on the classpath, so we'll upgrade their data_dir and then use the
            //default DEFAULT_LOGGING.properties configuration.
            LoggingInitializer.LOGGER.warning("log4jConfigFile '" + configFileName + "' couldn't be found in the data dir, so GeoServer will " +
            "install the various logging config file into the data dir, and then try to find it again.");
           
            Resource logs = resourceLoader.get( "logs" );           
            File lcdir = logs.dir();
           
            //now we copy in the various logging config files from the base repo location on the classpath
            final String[] lcfiles = new String[] {
                    "DEFAULT_LOGGING.properties",
                    "GEOSERVER_DEVELOPER_LOGGING.properties",
                    "GEOTOOLS_DEVELOPER_LOGGING.properties",
                    "PRODUCTION_LOGGING.properties",
                    "QUIET_LOGGING.properties",
                    "TEST_LOGGING.properties",
                    "VERBOSE_LOGGING.properties"
                    };
           
            for (int i = 0; i < lcfiles.length; i++) {
                File target = new File(lcdir.getAbsolutePath(), lcfiles[i]);
                if (!target.exists()) {
                    resourceLoader.copyFromClassPath(lcfiles[i], target);
                }
            }
           
            //ok, the possibly-new 'logs' directory is in-place, with all the various configs there.
            // Is the originally configured log4jconfigfile there now?
            if (resource.getType() != Type.RESOURCE) {
                LoggingInitializer.LOGGER.warning("Still couldn't find log4jConfigFile '" + configFileName + "'.  Using DEFAULT_LOGGING.properties instead.");
            }
           
            resource = resourceLoader.get( Paths.path("logs", "DEFAULT_LOGGING.properties") );
        }
   
        if (resource == null || resource.getType() != Type.RESOURCE) {
            throw new ConfigurationException("Unable to load logging configuration '" + configFileName + "'.  In addition, an attempt " +
                    "was made to create the 'logs' directory in your data dir, and to use the DEFAULT_LOGGING configuration, but" +
                    "this failed as well.  Is your data dir writeable?");
        }
       
        // reconfiguring log4j logger levels by resetting and loading a new set of configuration properties
        InputStream loggingConfigStream = resource.in();
        if (loggingConfigStream == null) {
            LoggingInitializer.LOGGER.warning("Couldn't open Log4J configuration file '" + resource);
            return;
        } else {
            LoggingInitializer.LOGGER.fine("GeoServer logging profile '" + resource.name() + "' enabled.");
        }
   
        configureGeoServerLogging(resourceLoader, loggingConfigStream, suppressStdOutLogging, false,
                                logFileName);
       
       
    }

    /**
     * Finds the log location in the "context" (system variable, env variable, servlet context)
     * or uses the provided base location otherwise
     */
    public static String getLogFileLocation(String baseLocation) {
        return getLogFileLocation(baseLocation, null);
    }

    /**
     * Finds the log location in the "context" (system variable, env variable, servlet context)
     * or uses the provided base location otherwise.
     * <p>
     * This method accepts a servlet context directly for cases where the logging location must
     * be known but the spring application context may not be initialized yet.
     * </p>
     */
    public static String getLogFileLocation(String baseLocation, ServletContext context) {
        //accept a servlet context directly in the case of startup where the application context
        // is not yet available, in other cases (like a logging change) we can fall back on the
        // app context and dervive the servlet context from that
        String location = context != null ?
            GeoServerExtensions.getProperty(LoggingUtils.GEOSERVER_LOG_LOCATION, context) :
            GeoServerExtensions.getProperty(LoggingUtils.GEOSERVER_LOG_LOCATION);
        if(location == null) {
            return baseLocation;
        } else {
            return location;
        }
    }

}
TOP

Related Classes of org.geoserver.logging.LoggingUtils

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.