博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
让你的spring-boot应用日志随心所欲--spring boot日志深入分析
阅读量:5974 次
发布时间:2019-06-19

本文共 7497 字,大约阅读时间需要 24 分钟。

1.spring boot日志概述

spring boot使用Commons Logging作为内部的日志系统,并且给Java Util Logging,Log4J2以及Logback都提供了默认的配置。

如果使用了spring boot的Starters,那么默认会使用Logback用于记录日志。

2.spring boot日志默认配置

我们启动一个空的spring-boot项目看一下控制台的日志

控制台的默认配置

logging.pattern.console=%clr(%d{${LOG_DATEFORMAT_PATTERN:-yyyy-MM-dd HH:mm:ss.SSS}}){faint} %clr(${LOG_LEVEL_PATTERN:-%5p}) %clr(${PID:- }){magenta} %clr(---){faint} %clr([%15.15t]){faint} %clr(%-40.40logger{39}){cyan} %clr(:){faint} %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}

其中%clr为配置不同的颜色输出,支持的颜色有以下几种:

blue

cyan
faint
green
magenta
red
yellow
输出顺序分析:

1、日期和时间--精确到毫秒,并按照时间进行简单的排序,格式为:

%clr(%d{${LOG_DATEFORMAT_PATTERN:-yyyy-MM-dd HH:mm:ss.SSS}}){faint}

2、日志级别--ERROR,WARN,INFO,DEBUG,TRACE

%clr(${LOG_LEVEL_PATTERN:-%5p})

3、进程ID号

%clr(${PID:- })

4、日志内容,用"---"分隔符分开

%clr(---){faint}

5、线程名字--括在方括号中

  

%clr([%15.15t]){faint}

6、日志的名字--通常对应的是类名

  

%clr(%-40.40logger{39}){cyan}

注意:Logback没有FATAL级别(映射到ERROR)

不同日志级别对应的颜色如下

3.spring boot日志配置

可以通过application.properties或者application.yml查看所有配置

每个配置后面都有说明,就不一一赘述了。

4.spring boot日志实现原理

点击配置属性,可以进入LoggingApplicationListener这个类,

`/**

  • An {@link ApplicationListener} that configures the {@link LoggingSystem}. If the
  • environment contains a {@code logging.config} property it will be used to bootstrap the
  • logging system, otherwise a default configuration is used. Regardless, logging levels
  • will be customized if the environment contains {@code logging.level.*} entries and
  • logging groups can be defined with {@code logging.group}.
  • <p>
  • Debug and trace logging for Spring, Tomcat, Jetty and Hibernate will be enabled when
  • the environment contains {@code debug} or {@code trace} properties that aren't set to
  • {@code "false"} (i.e. if you start your application using
  • {@literal java -jar myapp.jar [--debug | --trace]}). If you prefer to ignore these
  • properties you can set {@link #setParseArgs(boolean) parseArgs} to {@code false}.
  • <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
  • @author Madhura Bhave
  • @since 2.0.0
  • @see LoggingSystem#get(ClassLoader)
    */`

它实现了GenericApplicationListener接口,它默认定义了日志组DEFAULT_GROUP_LOGGERS和日志级别LOG_LEVEL_LOGGERS

private static final Map
> DEFAULT_GROUP_LOGGERS; static { MultiValueMap
loggers = new LinkedMultiValueMap<>(); loggers.add("web", "org.springframework.core.codec"); loggers.add("web", "org.springframework.http"); loggers.add("web", "org.springframework.web"); loggers.add("web", "org.springframework.boot.actuate.endpoint.web"); loggers.add("web", "org.springframework.boot.web.servlet.ServletContextInitializerBeans"); loggers.add("sql", "org.springframework.jdbc.core"); loggers.add("sql", "org.hibernate.SQL"); DEFAULT_GROUP_LOGGERS = Collections.unmodifiableMap(loggers); } private static final Map
> LOG_LEVEL_LOGGERS; static { MultiValueMap
loggers = new LinkedMultiValueMap<>(); loggers.add(LogLevel.DEBUG, "sql"); loggers.add(LogLevel.DEBUG, "web"); loggers.add(LogLevel.DEBUG, "org.springframework.boot"); loggers.add(LogLevel.TRACE, "org.springframework"); loggers.add(LogLevel.TRACE, "org.apache.tomcat"); loggers.add(LogLevel.TRACE, "org.apache.catalina"); loggers.add(LogLevel.TRACE, "org.eclipse.jetty"); loggers.add(LogLevel.TRACE, "org.hibernate.tool.hbm2ddl"); LOG_LEVEL_LOGGERS = Collections.unmodifiableMap(loggers); }

你也可以自定义logging.level和logging.group,它们都是map结构。LoggingApplicationListener重写了onApplicationEvent方法,实现日志的打印

@Override    public void onApplicationEvent(ApplicationEvent event) {        if (event instanceof ApplicationStartingEvent) {            onApplicationStartingEvent((ApplicationStartingEvent) event); //1        }        else if (event instanceof ApplicationEnvironmentPreparedEvent) {            onApplicationEnvironmentPreparedEvent(                    (ApplicationEnvironmentPreparedEvent) event); //2         }        else if (event instanceof ApplicationPreparedEvent) {            onApplicationPreparedEvent((ApplicationPreparedEvent) event); //3        }        else if (event instanceof ContextClosedEvent && ((ContextClosedEvent) event)                .getApplicationContext().getParent() == null) {            onContextClosedEvent();  //4        }        else if (event instanceof ApplicationFailedEvent) {            onApplicationFailedEvent();  //5        }    }

第一步:根据classloader里加载的依赖决定使用哪个日志系统?

主要实现有JavaLoggingSystem,Log4J2LoggingSystem,LogbackLoggingSystem

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

第二步:通过classpath,enviroment等获取参数初始化日志系统

/**     * 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) {        new LoggingSystemProperties(environment).apply();        LogFile logFile = LogFile.get(environment);        if (logFile != null) {            logFile.applyToSystemProperties();        }        initializeEarlyLoggingLevel(environment);        initializeSystem(environment, this.loggingSystem, logFile);        initializeFinalLoggingLevels(environment, this.loggingSystem);        registerShutdownHookIfNecessary(environment, this.loggingSystem);    }

第三步:注册springBootLoggingSystem

private void onApplicationPreparedEvent(ApplicationPreparedEvent event) {        ConfigurableListableBeanFactory beanFactory = event.getApplicationContext()                .getBeanFactory();        if (!beanFactory.containsBean(LOGGING_SYSTEM_BEAN_NAME)) {            beanFactory.registerSingleton(LOGGING_SYSTEM_BEAN_NAME, this.loggingSystem);        }    }

第四步和第五步:日志系统清洗

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

5.自定义配置文件

日志系统 自定义配置文件

Logback

logback-spring.xml, logback-spring.groovy, logback.xml, or logback.groovy

Log4j2

log4j2-spring.xml or log4j2.xml

JDK (Java Util Logging)

logging.properties

6.总结

  spring boot日志系统封装了logback,log4j2和java log,默认情况下使用java log,一旦使用各种starts,则默认使用Log4J2,也可以通过classpath来改变,pom.xml指定

org.springframework.boot
spring-boot-starter
org.springframework.boot
spring-boot-starter-logging
org.springframework.boot
spring-boot-starter-log4j
参考资料

【1】

【2】

转载于:https://blog.51cto.com/davidwang456/2410579

你可能感兴趣的文章
索尼高清影视技术学院参观观后感
查看>>
jQuery 文本编辑器插件 HtmlBox 使用
查看>>
怎么看自己服务器的带宽?
查看>>
go的错误处理
查看>>
apache2.4.4的安装过程
查看>>
php5.3安装oracle的扩展oci8与pdo_oci
查看>>
发送超长短信的协议格式
查看>>
CentOS 6.x 快速安装L2TP ***
查看>>
mysql主主复制(双主复制)配置步骤
查看>>
一篇文章能够看懂基础源代码之JAVA篇
查看>>
什么是大数据技术架构
查看>>
【分享】如何救援記憶卡中誤刪的資料
查看>>
北方计算机专修学院“展示自我 秀出风采” 网页创意设计大赛成功举办
查看>>
DNS解析相关实验:7台主机的恩怨情仇
查看>>
Goldengate双向复制配置
查看>>
Oracle官方内部MAA教程
查看>>
DNS相关配置
查看>>
Nginx-location配置
查看>>
扫描线
查看>>
设计模式--模板方法(Template Method)
查看>>