文章目录

  • 一、日志级别
  • 二、SpringBoot引入logger
  • 三、通过springboot配置文件配置logback
  • 四、通过XMl文件自定义logback配置
  • 4.1configuration父标签
  • 4.2 contextName属性
  • 4.3 property属性
  • 4.4 appender节点
  • 4.4.1 控制台输出appender
  • 4.4.2 文件输入appender
  • 4.5 root节点-启用配置
  • 4.6 logger节点
  • 4.7 root和logger的关系
  • 4.8多环境日志配置


日志处理是一个正式项目必备的功能,日志要能够根据时间、类型等要素,根据指定格式来保存指定的日志,方便我们观察程序运行情况、定位程序bug。

SpringBoot中推荐使用Logback日志框架。


slf4j:一个针对各类Java日志框架的统一facade抽象。

java常见日志框架:java.util.logging, log4j, logback, commons-logging

logback是log4j的作者开发的新一代日志框架,目前应用最广泛。SpringBoot默认使用logback,默认INFO级别

Logback:

日志加载顺序:logback.xml -> application.properties -> logback-spring.xml


一、日志级别

log4j定义的日志级别:debug/info/warn/error/fatal

warn,潜在错误;error,错误,可能导致程序退出;fatal,严重错误,程序会退出

还有两个特殊的级别:OFF-最高级别,ALL-最低级别

log4j建议仅使用debug/info/warn/error四个级别

日志级别:ERROR -> WARN -> INFO -> DEBUG

如配置日志级别为INFO,则INFO及以上级别的日志会输出,而比INFO级别低的日志(debug日志)不会被输出。


二、SpringBoot引入logger

直接引入:

<dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-logging</artifactId>
      <version>2.1.11.RELEASE</version>
      <scope>compile</scope>
    </dependency>

间接引入:

引入spring-boot-starter,会自动引入spring-boot-starter-logging

引入spring-boot-starter-web,会自动引入spring-boot-starter

三、通过springboot配置文件配置logback

配置输出日志到文件:

logging:
  file: logback-demo.log # 输出到项目目录下

默认是叠加输出,即每次启动项目不会删除之前的日志文件,也不会将当前使用的日志文件清空,而是在下面另起一行。

日志级别:logging.level.*: level-name

*指包名或日志名,日志名如root,表示系统日志

level-name指日志级别,常用debug/info/warn/error

比如:

logging:
  level:
    com.apple: debug # 指定包下日志以debug级别输出
    #root: warn # root日志以warn级别输出,不要用debug级别!!---会卡的!

四、通过XMl文件自定义logback配置

上面的配置确实将日志保存到文件中,但是对于实际项目来说用处不大。

比如:日志文件非常庞大,每天产生的日志大小在数百MB,单个文件能处理么?日志需要分类型进行保存怎么办呢?定制日志格式怎么办呢?

这些都是问题。

幸好,包括logback在内的日志框架大多提供了配置文件功能,最常见的是使用xml文件进行配置。

日志框架默认配置文件:

  • Logback:logback-spring.xml, logback-spring.groovy, logback.xml, logback.groovy
  • Log4j:log4j-spring.properties, log4j-spring.xml, log4j.properties, log4j.xml
  • Log4j2:log4j2-spring.xml, log4j2.xml
  • JDK (Java Util Logging):logging.properties

日志加载顺序:logback.xml -> application.properties -> logback-spring.xml

logback框架下:

建议使用logback-spring.xml,也可以在application中通过logging.config=classpath:xxx.xml来指定配置文件。

示例:

<?xml version="1.0" encoding="utf-8"?>
<!--配置文件说明:
共有一个父标签、两种属性、三个节点:
1.一个父标签:configuration
2. 两种属性:contextName和property
3. 三个节点:appender、root、logger

主要就是appender追加到哪里:控制台/文件,然后采用哪种pattern(在property定义了pattern格式)
然后就是logger和root配置,指定日志输出级别,以及引用哪种appender
-->
<configuration>
<!--根节点<configuration>包含的属性:
	scan:当此属性设置为true时,配置文件如果发生改变,将会被重新加载,默认值为true。
	scanPeriod:设置监测配置文件是否有修改的时间间隔,如果没有给出时间单位,默认单位是毫秒。当scan为true时,此属性生效。默认的时间间隔为1分钟。
	debug:当此属性设置为true时,将打印出logback内部日志信息,实时查看logback运行状态。默认值为false。
-->
    <contextName>logback-spring-demo-dev</contextName>
    <property name="pattern" value="%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg %n"/>
    <property name="pattern-color"
              value="%yellow(%d{yyyy-MM-dd HH:mm:ss.SSS}) [%thread] %highlight(%-5level) %green(%logger{50}) - %highlight(%msg) %n"/>
    <!--文件路径输出说明,会自动生成文件夹及log文件,但是由于我这个是多模块,默认生成在父目录下的logs文件夹下面,所以要在子模块下生成要再加一个路径-->
    <property name="LOG_HOME" value="./springboot_log/logs"/>

    <!-- 控制台输出 -->
    <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
        <!--ThresholdFilter为系统定义的拦截器,例如我们用ThresholdFilter来过滤掉ERROR级别以下的日志不输出到文件中。如果不用记得注释掉,不然你控制台会发现没日志~-->
        <!--<filter class="ch.qos.logback.classic.filter.ThresholdFilter">-->
        <!--<level>ERROR</level>-->
        <!--</filter>-->
        <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
            <pattern>${pattern}</pattern>
        </encoder>
    </appender>

    <!-- 控制台输出-带颜色 -->
    <appender name="CONSOLE-WITH-COLOR" class="ch.qos.logback.core.ConsoleAppender">
        <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
            <pattern>${pattern-color}</pattern>
        </encoder>
    </appender>

    <!-- 文件输出 -->
    <appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <fileNamePattern>${LOG_HOME}/%d.%i.log</fileNamePattern>
            <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
                <maxFileSize>10MB</maxFileSize>
            </timeBasedFileNamingAndTriggeringPolicy>
            <maxHistory>30</maxHistory>
        </rollingPolicy>

        <encoder>
            <pattern>${pattern}</pattern>
        </encoder>
    </appender>

    <!--相当于全局的配置-->
    <root level="INFO">
        <appender-ref ref="CONSOLE-WITH-COLOR"/>
        <appender-ref ref="FILE"/>
    </root>
<!--1. root和logger是父子的关系。
   Logger的appender根据参数additivity决定是否要叠加root的appender,logger的级别是其自身定义的级别,和root的级别没什么关系。
	2. logger对单个包或类添加配置,相当于局部配置,root相当于全局配置
   如果logger里面配置了additivity="false",就会覆盖root的,只打印一遍;
   但是additivity="true",就会向上层再次传递,不会覆盖,而是打印两遍!
-->

    <!--相当于局部配置:
    配置特定类/包使用不同的日志输出器appender:TestControoler2的会输出两遍,additivity="true"-->
    <logger name="com.apple.controller.TestController2" level="INFO" additivity="true">
        <appender-ref ref="CONSOLE"/>
    </logger>

</configuration>

下面具体描述一下logback.xml中的配置项:

共有一个父标签、两种属性、三个节点:

1.一个父标签:configuration

2.两种属性:contextName和property

3.三个节点:appender、root、logger


4.1configuration父标签

<configuration  scan="true" scanPeriod="60 seconds" debug="false">

根节点< configuration>包含的属性

  • scan:当此属性设置为true时,配置文件如果发生改变,将会被重新加载,默认值为true。
  • scanPeriod:设置监测配置文件是否有修改的时间间隔,如果没有给出时间单位,默认单位是毫秒。当scan为true时,此属性生效。默认的时间间隔为1分钟。
  • debug:当此属性设置为true时,将打印出logback内部日志信息,实时查看logback运行状态。默认值为false。

根节点<configuration>的子节点:<configuration>下面一共有2个属性,3个子节点,分别是:


4.2 contextName属性

contextName:日志名,可以使用%contextName来引用

如果同时存在logback.xml和logback-spring.xml,或者同时存在logback.xml和自定义的配置文件,则会先加载logback.xml,再根据application配置加载指定配置文件,或加载logback-spring,xml。如果这两个配置文件的contextName不同,就会报错:

ERROR in ch.qos.logback.classic.joran.action.ContextNameAction - Failed to rename context [logback-demo] as [logback-spring-demo-dev] java.lang.IllegalStateException: Context has been already given a name

4.3 property属性

property标签可用于自定义属性,比如定义一个,然后使用${LOG_HOME}去引用它


4.4 appender节点

appender的意思是追加器,在这里可以理解为一个日志的渲染器。比如渲染console日志为某种格式,渲染文件日志为另一种格式。

appender中有name和class两个属性,有rollingPolicy和encoder两个子节点。

name表示该渲染器的名字,class表示使用的输出策略,常见的有控制台输出策略和文件输出策略。

4.4.1 控制台输出appender
<property name="pattern" value="%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg %n"/>

<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
    <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
        <level>ERROR</level>
    </filter>
	<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
  	<pattern>${pattern}</pattern>
  </encoder>
</appender>

ThresholdFilter为系统定义的拦截器,例如我们用ThresholdFilter来过滤掉ERROR级别以下的日志不输出到文件中。如果不用记得注释掉,不然你控制台会发现没日志~

encoder表示输出格式,具体说明如下:

%d表示时间

%thread表示线程名

%-5level 表示日志级别,允许以五个字符长度输出

%logger{50}表示具体的日志输出者,比如类名,括号内表示长度

%msg表示具体的日志消息,就是logger.info("xxx")中的xxx

%n表示换行

还可以定义颜色高亮,比如讲pattern定义为如下:

<property name="pattern-color" value="%yellow(%d{yyyy-MM-dd HH:mm:ss.SSS}) [%thread] %highlight(%-5level) %green(%logger{50}) - %highlight(%msg) %n"/>

即使用%color(xxx)来指定对应列的输出颜色,可以实现控制台输出的颜色高亮。

<appender name="CONSOLE-WITH-COLOR" class="ch.qos.logback.core.ConsoleAppender">
   <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
        <pattern>${pattern-color}</pattern>
   </encoder>
</appender>
4.4.2 文件输入appender

文件输出主要包括配置:以指定格式将日志输出到指定文件夹下的文件中,可以配置该文件的名称、最大大小、保存时间

例如:

<property name="LOG_HOME" value="logs"/>
<property name="pattern" value="%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg %n"/>

<appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
  <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
    <fileNamePattern>${LOG_HOME}/all.%d.%i.log</fileNamePattern>
    <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
    	<maxFileSize>10MB</maxFileSize>
    </timeBasedFileNamingAndTriggeringPolicy>
    <maxHistory>30</maxHistory>
  </rollingPolicy>

  <encoder>
    <pattern>${pattern}</pattern>
    </encoder>
</appender>

上述配置的主要内容是:以指定的格式向logs文件下的文件输出日志,文件名称格式被指定为logs/all.日期.索引号.log,日志文件最大大小为10MB,超出则创建新文件,日志文件保留三十天

索引从0开始递增

rollingPolicy指滚动粗略,具体配置如上。

关于日志文件大小限制也可以使用1GB配置。


4.5 root节点-启用配置

root节点实际上是配置启用哪种appender,可以添加多个appender。

比如:

<root level="INFO">
  <appender-ref ref="CONSOLE-WITH-COLOR"/>
  <appender-ref ref="FILE"/>
</root>

表示level为info级别,启用渲染器CONSOLE-WITH-COLOR和FILE。

按照这样配置,输出日志时,控制台会按照CONSOLE定义的格式输出,而日志文件会按照CONSOLE-WITH-COLOR的配置去输出。


4.6 logger节点

对单个包或类添加配置:

<!-- logger节点可以指定具体包或类的日志配置 -->
    <!-- name属性为必选,指定要配置的包或类,level和additivity为可选,有缺省值 -->
    <!-- level表示日志级别,这里配置info级别,表示info及以上级别的日志被输出 -->
    <!-- additivity表示日志是否传递到上一级,默认为true -->
    <logger name="com.apple.controller.TestController2" level="info" additivity="false">
        <appender-ref ref="CONSOLE"/>
    </logger>

这里我们添加了一个测试接口类:

@GetMapping("/log3")
    public String getLog() {
        if (log.isDebugEnabled()) {
            log.debug("debug日志输出吗");
        }
        log.error("error日志输出吗");
        log.info("info日志输出吗");
        return "log";
    }

启动项目,调用接口测试一下:

spring boot logback 配置日志到本地文件 springboot logback配置详解_spring

发现TestContronller2类的控制台日志输出是无颜色的,即logger配置生效。additivity设为true后,发现控制台输出了两遍相同的内容。

<!--相当于局部配置:
    配置特定类/包使用不同的日志输出器appender:TestControoler2的会输出两遍,additivity="true"-->
    <logger name="com.apple.controller.TestController2" level="INFO" additivity="true">
        <appender-ref ref="CONSOLE"/>
    </logger>

spring boot logback 配置日志到本地文件 springboot logback配置详解_spring_02

此外,还有一个用于指定springboot配置文件对应日志配置的springProfile标签,在下面会讲到其应用。

4.7 root和logger的关系

  1. root和logger是父子的关系。
    Logger的appender根据参数additivity决定是否要叠加root的appender,logger的级别是其自身定义的级别,和root的级别没什么关系。
  2. logger对单个包或类添加配置,相当于局部配置,root相当于全局配置
    如果logger里面配置了additivity=“false”,就会覆盖root的,只打印一遍;
    但是additivity=“true”,就会向上层再次传递,不会覆盖,而是打印两遍!

4.8多环境日志配置

  1. springboot指定启用哪个xml
    我们可以在springboot的配置文件中指明使用哪个xml作为logger的配置,比如:logging.config=classpath:logback-spring-dev.xml。
    如果不指定,则会按照logback.xml->application.yml->logback-spring.xml的顺序去查找是否存在默认的配置。
  2. xml中使用springProfile标签指定哪些环境下应该使用哪些配置
    我们也可以在具体的日志配置xml文件中指定在哪些环境下使用哪些配置,比如:
<springProfile name="local,dev">
	<root level="INFO">
		<appender-ref ref="CONSOLE-WITH-COLOR"/>
		<appender-ref ref="FILE"/>
	</root>
</springProfile>

<springProfile name="prod">
	<root level="INFO">
		<appender-ref ref="CONSOLE-WITH-COLOR"/>
		<appender-ref ref="FILE"/>
	</root>
</springProfile>

这样的话,就不需要建议多个xml文件了,使用一个默认的logback-spring.xml即可。