码迷,mamicode.com
首页 > 移动开发 > 详细

LoggingApplicationListener

时间:2016-08-10 00:33:36      阅读:960      评论:0      收藏:0      [点我收藏+]

标签:

org.springframework.boot:spring-boot:1.3.0.M1

spring-boot-1.3.0.M1.jar

package org.springframework.boot.logging;

import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.boot.ApplicationPid;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.bind.RelaxedPropertyResolver;
import org.springframework.boot.context.event.ApplicationEnvironmentPreparedEvent;
import org.springframework.boot.context.event.ApplicationStartedEvent;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationEvent;
import org.springframework.context.ApplicationListener;
import org.springframework.context.event.ContextClosedEvent;
import org.springframework.context.event.GenericApplicationListener;
import org.springframework.core.Ordered;
import org.springframework.core.ResolvableType;
import org.springframework.core.env.ConfigurableEnvironment;
import org.springframework.core.env.Environment;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.util.ResourceUtils;
import org.springframework.util.StringUtils;

/**
 * An {@link ApplicationListener} that configures the {@link LoggingSystem}. If the
 * environment contains a {@code logging.config} property a then that will be used to
 * initialize the logging system, otherwise a default configuration is used.
 * <p>
 * By default, log output is only written to the console. If a log file is required the
 * {@code logging.path} and {@code logging.file} properties can be used.
 * <p>
 * Some system properties may be set as side effects, and these can be useful if the
 * logging configuration supports placeholders (i.e. log4j or logback):
 * <ul>
 * <li>{@code LOG_FILE} is set to the value of path of the log file that should be written
 * (if any).</li>
 * <li>{@code PID} is set to the value of the current process ID if it can be determined.</li>
 * </ul>
 *
 * @author Dave Syer
 * @author Phillip Webb
 * @author Andy Wilkinson
 * @see LoggingSystem#get(ClassLoader)
 */
public class LoggingApplicationListener implements GenericApplicationListener {

    /**
     * The name of the Spring property that contains a reference to the logging
     * configuration to load.
     */
    public static final String CONFIG_PROPERTY = "logging.config";

    /**
     * The name of the Spring property that contains the path where the logging
     * configuration can be found.
     */
    public static final String PATH_PROPERTY = LogFile.PATH_PROPERTY;

    /**
     * The name of the Spring property that contains the name of the logging configuration
     * file.
     */
    public static final String FILE_PROPERTY = LogFile.FILE_PROPERTY;

    /**
     * The name of the System property that contains the process ID.
     */
    public static final String PID_KEY = "PID";

    private static MultiValueMap<LogLevel, String> LOG_LEVEL_LOGGERS;
    static {
        LOG_LEVEL_LOGGERS = new LinkedMultiValueMap<LogLevel, String>();
        LOG_LEVEL_LOGGERS.add(LogLevel.DEBUG, "org.springframework.boot");
        LOG_LEVEL_LOGGERS.add(LogLevel.TRACE, "org.springframework");
        LOG_LEVEL_LOGGERS.add(LogLevel.TRACE, "org.apache.tomcat");
        LOG_LEVEL_LOGGERS.add(LogLevel.TRACE, "org.apache.catalina");
        LOG_LEVEL_LOGGERS.add(LogLevel.TRACE, "org.eclipse.jetty");
        LOG_LEVEL_LOGGERS.add(LogLevel.TRACE, "org.hibernate.tool.hbm2ddl");
        LOG_LEVEL_LOGGERS.add(LogLevel.DEBUG, "org.hibernate.SQL");
    }

    private static Class<?>[] EVENT_TYPES = { ApplicationStartedEvent.class,
            ApplicationEnvironmentPreparedEvent.class, ContextClosedEvent.class };

    private static Class<?>[] SOURCE_TYPES = { SpringApplication.class,
            ApplicationContext.class };

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

    private LoggingSystem loggingSystem;

    private int order = Ordered.HIGHEST_PRECEDENCE + 11;

    private boolean parseArgs = true;

    private LogLevel springBootLogging = null;

    @Override
    public boolean supportsEventType(ResolvableType resolvableType) {
        return isAssignableFrom(resolvableType.getRawClass(), EVENT_TYPES);
    }

    @Override
    public boolean supportsSourceType(Class<?> sourceType) {
        return isAssignableFrom(sourceType, SOURCE_TYPES);
    }

    private boolean isAssignableFrom(Class<?> type, Class<?>... supportedTypes) {
        if (type != null) {
            for (Class<?> supportedType : supportedTypes) {
                if (supportedType.isAssignableFrom(type)) {
                    return true;
                }
            }
        }
        return false;
    }

    @Override
    public void onApplicationEvent(ApplicationEvent event) {
        if (event instanceof ApplicationStartedEvent) {
            onApplicationStartedEvent((ApplicationStartedEvent) event);
        }
        else if (event instanceof ApplicationEnvironmentPreparedEvent) {
            onApplicationEnvironmentPreparedEvent((ApplicationEnvironmentPreparedEvent) event);
        }
        else if (event instanceof ContextClosedEvent) {
            onContextClosedEvent();
        }
    }

    private void onApplicationStartedEvent(ApplicationStartedEvent event) {
        this.loggingSystem = LoggingSystem.get(event.getSpringApplication()
                .getClassLoader());
        this.loggingSystem.beforeInitialize();
    }

    private void onApplicationEnvironmentPreparedEvent(
            ApplicationEnvironmentPreparedEvent event) {
        if (this.loggingSystem == null) {
            this.loggingSystem = LoggingSystem.get(event.getSpringApplication()
                    .getClassLoader());
        }
        initialize(event.getEnvironment(), event.getSpringApplication().getClassLoader());
    }

    private void onContextClosedEvent() {
        if (this.loggingSystem != null) {
            this.loggingSystem.cleanUp();
        }
    }

    /**
     * Initialize the logging system according to preferences expressed through the
     * {@link Environment} and the classpath.
     * @param environment the environment
     * @param classLoader the classloader
     */
    protected void initialize(ConfigurableEnvironment environment, ClassLoader classLoader) {
        if (System.getProperty(PID_KEY) == null) {
            System.setProperty(PID_KEY, new ApplicationPid().toString());
        }
        initializeEarlyLoggingLevel(environment);
        initializeSystem(environment, this.loggingSystem);
        initializeFinalLoggingLevels(environment, this.loggingSystem);
    }

    private void initializeEarlyLoggingLevel(ConfigurableEnvironment environment) {
        if (this.parseArgs && this.springBootLogging == null) {
            if (environment.containsProperty("debug")) {
                this.springBootLogging = LogLevel.DEBUG;
            }
            if (environment.containsProperty("trace")) {
                this.springBootLogging = LogLevel.TRACE;
            }
        }
    }

    private void initializeSystem(ConfigurableEnvironment environment,
            LoggingSystem system) {
        LogFile logFile = LogFile.get(environment);
        String logConfig = environment.getProperty(CONFIG_PROPERTY);
        if (StringUtils.hasLength(logConfig)) {
            try {
                ResourceUtils.getURL(logConfig).openStream().close();
                system.initialize(logConfig, logFile);
            }
            catch (Exception ex) {
                this.logger.warn("Logging environment value ‘" + logConfig
                        + "‘ cannot be opened and will be ignored "
                        + "(using default location instead)");
                system.initialize(null, logFile);
            }
        }
        else {
            system.initialize(null, logFile);
        }
    }

    private void initializeFinalLoggingLevels(ConfigurableEnvironment environment,
            LoggingSystem system) {
        if (this.springBootLogging != null) {
            initializeLogLevel(system, this.springBootLogging);
        }
        setLogLevels(system, environment);
    }

    protected void initializeLogLevel(LoggingSystem system, LogLevel level) {
        List<String> loggers = LOG_LEVEL_LOGGERS.get(level);
        if (loggers != null) {
            for (String logger : loggers) {
                system.setLogLevel(logger, level);
            }
        }
    }

    protected void setLogLevels(LoggingSystem system, Environment environment) {
        Map<String, Object> levels = new RelaxedPropertyResolver(environment)
                .getSubProperties("logging.level.");
        for (Entry<String, Object> entry : levels.entrySet()) {
            setLogLevel(system, environment, entry.getKey(), entry.getValue().toString());
        }
    }

    private void setLogLevel(LoggingSystem system, Environment environment, String name,
            String level) {
        try {
            if (name.equalsIgnoreCase("root")) {
                name = null;
            }
            level = environment.resolvePlaceholders(level);
            system.setLogLevel(name, LogLevel.valueOf(level));
        }
        catch (RuntimeException ex) {
            this.logger.error("Cannot set level: " + level + " for ‘" + name + "‘");
        }
    }

    public void setOrder(int order) {
        this.order = order;
    }

    @Override
    public int getOrder() {
        return this.order;
    }

    /**
     * Sets a custom logging level to be used for Spring Boot and related libraries.
     * @param springBootLogging the logging level
     */
    public void setSpringBootLogging(LogLevel springBootLogging) {
        this.springBootLogging = springBootLogging;
    }

    /**
     * Sets if initialization arguments should be parsed for {@literal --debug} and
     * {@literal --trace} options. Defaults to {@code true}.
     * @param parseArgs if arguments should be parsed
     */
    public void setParseArgs(boolean parseArgs) {
        this.parseArgs = parseArgs;
    }

}

 

LoggingApplicationListener

标签:

原文地址:http://www.cnblogs.com/softidea/p/5755025.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!