让你的spring-boot应用日志随心所欲--spring boot日志深入分析

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<String, List<String>> DEFAULT_GROUP_LOGGERS;
    static {
        MultiValueMap<String, String> 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<LogLevel, List<String>> LOG_LEVEL_LOGGERS;
    static {
        MultiValueMap<LogLevel, String> 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指定

<dependency>
 <groupId>org.springframework.boot</groupId>
 <artifactId>spring-boot-starter</artifactId>
 <exclusions>
  <exclusion>
   <groupId>org.springframework.boot</groupId>
   <artifactId>spring-boot-starter-logging</artifactId>
  </exclusion>
 </exclusions>
</dependency>
<dependency>
 <groupId>org.springframework.boot</groupId>
 <artifactId>spring-boot-starter-log4j</artifactId>
</dependency> 
参考资料

【1】https://docs.spring.io/spring-boot/docs/2.1.2.RELEASE/reference/htmlsingle/#boot-features-logging-format

【2】https://www.jb51.net/article/133795.htm

原文地址:https://blog.51cto.com/davidwang456/2410579

时间: 2024-08-29 02:36:28

让你的spring-boot应用日志随心所欲--spring boot日志深入分析的相关文章

spring boot 2.0.3+spring cloud (Finchley)7、微服务监控Spring Cloud Admin

参考:Spring Boot Admin 2.0 上手 Spring Boot Admin 用于管理和监控一个或多个Spring Boot程序,在 Spring Boot Actuator 的基础上提供简洁的可视化 WEB UI,提供如下功能: 显示 name/id 和版本号 显示在线状态 Logging 日志级别管理 JMX beans 管理 Threads 会话和线程管理 Trace 应用请求跟踪 应用运行参数信息,如: Java 系统属性 Java 环境变量属性 内存信息 Spring 环

Spring Boot 应用系列 5 -- Spring Boot 2 整合logback

上一篇我们梳理了Spring Boot 2 整合log4j2的配置过程,其中讲到了Spring Boot 2原装适配logback,并且在非异步环境下logback和log4j2的性能差别不大,所以对于那些日志量不算太高的项目来说,选择logback更简单方便. 1. pom.xml pom.xml不需要添加任何依赖. 2. logback的配置文件 系统启动时,logback按照下列顺序加载第一个找到的配置文件: (1) classpath: logback-test.xml (2) clas

Spring Boot 必须先说说 Spring 框架!

现在 Spring Boot 非常火,各种技术文章,各种付费教程,多如牛毛,可能还有些不知道 Spring Boot 的,那它到底是什么呢?有什么用?今天给大家详细介绍一下. Spring Boot 的背景了解 Spring Boot 必须先说说 Spring 框架! 在 Java 后端框架繁荣的今天,Spring 框架无疑是最最火热,也是必不可少的开源框架,更是稳坐 Java 后端框架的龙头老大. 用过 Spring 框架的都知道 Spring 能流行是因为它的两把利器:IOC 和 AOP,I

Spring Data JPA例子[基于Spring Boot、Mysql]

关于Spring Data Spring社区的一个顶级工程,主要用于简化数据(关系型&非关系型)访问,如果我们使用Spring Data来开发程序的话,那么可以省去很多低级别的数据访问操作,如编写数据查询语句.DAO类等,我们仅需要编写一些抽象接口并定义相关操作即可,Spring会在运行期间的时候创建代理实例来实现我们接口中定义的操作. 关于Spring Data子项目 Spring Data拥有很多子项目,除了Spring Data Jpa外,还有如下子项目. Spring Data Comm

从启动日志看Spring IOC的初始化和Bean生命周期

一.Tomcat中启动IoC容器的日志 启动Tomcat等容器时,控制台每次都打印出一些日志. 最近刚好在研究Spring源码,所以换个角度,从启动日志来简单的看看Spring的初始化过程! 以下是Tomcat启动时日志,截取Spring部分. //------------------------------------- //从这里开始Spring的初始化 十一月 10, 2015 8:52:03 上午 org.apache.catalina.core.ApplicationContext l

spring cloud教程之使用spring boot创建一个应用

<7天学会spring cloud>第一天,熟悉spring boot,并使用spring boot创建一个应用. Spring Boot是Spring团队推出的新框架,它所使用的核心技术还是Spring框架,主要是Spring 4.x,所以如果熟悉spring 4的人,能够更快的接受和学会这个框架.Spring boot可以看做是在spring框架基础上再包了一层,这一层包含方便开发者进行配置管理和快速开发的模块,以及提供了一些开箱即用的工具,比如监控等. Spring Boot官方文档有中

初入spring boot(八 )Spring Data REST

1. 什么是Spring Data REST Spring Data JPA是基于Spring Data 的Repository之上,可以将Repository自动输出为REST资源.目前Spring Data REST支持将Spring Data JPA.Spring Data MongoDB.Spring Data Neo4j.Spring Data Gemfire以及Spring Data Cassandra的Repository自动转换成REST服务. 2. Spring mvc中配置使

Spring Boot——2分钟构建spring web mvc REST风格HelloWorld

之前有一篇<5分钟构建spring web mvc REST风格HelloWorld>介绍了普通方式开发spring web mvc web service.接下来看看使用spring boot如何快速构建一个. Spring Boot使我们更容易去创建基于Spring的独立和产品级的可以”即时运行“的应用和服务.支持约定大于配置,目的是尽可能快地构建和运行Spring应用. 之前我们创建基于Spring的项目需要考虑添加哪些Spring依赖和第三方的依赖.使用Spring Boot后,我们可

Spring Boot示例 - 1. 使用Spring Boot Actuator构建RESTful web service

一.概述 Spring Boot Actuator是Spring Boot的子项目.使用它无需特别配置,即可为应用增加一些生产级别的服务.本教程展示使用Eclipse + Maven来从零开始构建一个RESTful的应用. 该应用作用是访问http://localhost:8080/fuck?name=xxx,会返回json字符串,并且访问http://localhost:8080/metrics 可以看到应用堆的一些信息. 什么是Spring Boot Actuator? Actuator是个