Logback快速上手指南

2019-10-30  本文已影响0人  文景大大

一、环境准备

  1. Spring Boot2.x,SpringBoot默认采用的日志就是slf4j+logback,所以无需额外引入日志的依赖;
  2. IDEA集成开发环境;
  3. Lombok的maven依赖;
  4. IDEA中安装Lombok的插件;
  5. 从start.spring.io上新建一个demo工程,仅引入Web组件即可;

二、LogBack快速上手

2.1 最简单的使用

新建一个Rest类:

@RestController
public class DemoRest {
    private static final Logger log = LoggerFactory.getLogger(DemoRest.class);

    @RequestMapping("/hello")
    public String sayHello(){
        log.info("info level...");
        return "success";
    }
}

由于我们使用了lombok,所以可以简写成:

@Slf4j
@RestController
public class DemoRest {

    @RequestMapping("/hello")
    public String sayHello(){
        log.info("info level...");
        return "success";
    }

}

@slf4j注解的作用,就是替代类中的private static final Logger log = LoggerFactory.getLogger(DemoRest.class);,如此logback就能正常输出日志了。

2.2 使用配置文件

在真实的项目开发中,对于日志输出的路径、策略和格式都是有不同要求的,这些就可以在配置文件中进行设置。

Spring Boot默认会检测src/main/resources下面的logback-spring.xml作为logback的配置文件。

现在我们设置配置文件内容如下:

<?xml version="1.0" encoding="utf-8"?>
<configuration>
      <appender name="CONSOLE-LOG" class="ch.qos.logback.core.ConsoleAppender">
        <layout class="ch.qos.logback.classic.PatternLayout">
            <pattern>[%d{yyyy-MM-dd' 'HH:mm:ss.sss}] [%t] [%C] [%L] [%-5p] %m%n</pattern>
        </layout>
      </appender>

        <root level="info">
          <appender-ref ref="CONSOLE-LOG" />
        </root>
</configuration>

这里有两个元素要介绍下:

  1. appender表示一个日志输出组件,我们可以同时配置多个日志输出组件,以满足不同的需求。当然,此处我们配置一个即可,当前只要能实现在控制台打印日志。其中,name是自己起的,表示这是一个用于定义控制台输出日志组件,layout表示输出日志的格式。(有关日志格式的配置参考第三节的推荐资料)
  2. root定义了日志的输出级别,在这里,level为info表示只有等级大于等于info的日志才会被输出。root中的appeder-ref是用来引入日志组件,使得这些组件生效。如果我们定义了appender组件,却没有在root中包含,那这些appender组件就不会启用。

2.3 日志输出到文件

除了要将日志输出到控制台,我们更希望将它们输出到固定目录的文件中保存,这才是标准应用的通用做法。那么我们只需要在上面的基础上增加一个appender日志组件即可。

<?xml version="1.0" encoding="utf-8"?>
<configuration>
      <!--定义全局变量-->
      <property name="LOG_PATTERN" value="%d{yyyy-MM-dd HH:mm:ss.SSS} | %thread | %-5level | %msg%n"/>

       <!--输出到控制台-->
      <appender name="CONSOLE-LOG" class="ch.qos.logback.core.ConsoleAppender">
        <layout class="ch.qos.logback.classic.PatternLayout">
            <pattern>${LOG_PATTERN}</pattern>
        </layout>
      </appender>

       <!--输出到文件-->
       <appender name="FILE-LOG" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <encoder>
            <pattern>${LOG_PATTERN}</pattern>
        </encoder>
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <fileNamePattern>C://Users//xxx//Desktop//info//%d.log</fileNamePattern>
            <maxHistory>30</maxHistory>
        </rollingPolicy>
       </appender>

        <root level="info">
          <appender-ref ref="CONSOLE-LOG" />
          <appender-ref ref="FILE-LOG" />
        </root>
</configuration>

新的日志组件我们取名字叫FILE-LOGencoderpattern也是用来定义日志输出格式的,因为格式和上面已经定义的输出到控制台的日志格式相同,我们将它们提取出来,放到配置文件的最上面property里面,将来调整日志格式只要改这一个地方即可,其它日志组件想要使用相同的输出格式,直接引用该变量。

rollingPolicy表示滚动策略,这里指定基于时间顺序的滚动策略,然后在fileNamePattern中设置日志存放的路径和日志名称,maxHistory表示最多保留天数。

最后,别忘了在root中引入我们的文件日志输出组件,使之生效。

2.4 日志按级别分类存储到文件

在每天日志量都很多的情况下,我们想查看ERROR级别的日志来定位问题,使用如上一个日志文件的方式,显得很费劲。此时我们可以将ERROR级别的日志分类到一个单独的日志文件中。

<?xml version="1.0" encoding="utf-8"?>
<configuration>
      <!--定义全局变量-->
      <property name="LOG_PATTERN" value="%d{yyyy-MM-dd HH:mm:ss.SSS} | %thread | %-5level | %msg%n"/>
      <property name="LOG_DIR" value="C:\\Users\\xxx\\Desktop\\info"/>

       <!--输出到控制台-->
      <appender name="CONSOLE-LOG" class="ch.qos.logback.core.ConsoleAppender">
        <layout class="ch.qos.logback.classic.PatternLayout">
            <pattern>${LOG_PATTERN}</pattern>
        </layout>
      </appender>

       <!--输出到文件-->
       <appender name="FILE-LOG" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <!--设置过滤器过滤ERROR级别的日志-->
        <filter class="ch.qos.logback.classic.filter.LevelFilter">
            <level>ERROR</level>
            <onMatch>DENY</onMatch>
            <onMismatch>ACCEPT</onMismatch>
        </filter>
        <encoder>
            <pattern>${LOG_PATTERN}</pattern>
        </encoder>
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <fileNamePattern>${LOG_DIR}/%d.log</fileNamePattern>
            <maxHistory>30</maxHistory>
        </rollingPolicy>
       </appender>

        <!--错误日志设置-->
        <appender name="ERROR_LOG" class="ch.qos.logback.core.rolling.RollingFileAppender">
          <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
            <level>ERROR</level>
          </filter>
          <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <FileNamePattern>${LOG_DIR}/error.%d{yyyy-MM-dd}.log</FileNamePattern>
            <MaxHistory>30</MaxHistory>
          </rollingPolicy>
          <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
            <pattern>${LOG_PATTERN}</pattern>
          </encoder>
        </appender>

        <root level="info">
          <appender-ref ref="CONSOLE-LOG" />
          <appender-ref ref="FILE-LOG" />
          <appender-ref ref="ERROR-LOG" />
        </root>
</configuration>

首先,我们需要重新设置FILE-LOG日志组件,让它不再将ERROR级别的日志记录到文件中,因为我们在下面会设置专门的日志组件来记录它。

filter采用的是LevelFilter,严格匹配ERROR级别的日志,当匹配onMatch的时候,就deny拒绝记录,当不匹配onMismatch的时候,就access接受记录。

当然,如果你仍然需要将ERROR级别的日志记录到该日志文件中,上述filter不用配置就行。

接下来,我们定义一个ERROR-LOG的输出组件,专门用来收集ERROR级别的日志。ThresholdFilter表示设定的日志级别及以上级别将会被记录。

最后,别忘了引用我们的错误日志输出组件。

2.5 日志按类名分类存储到文件

有的时候,我们需要单独监控某一个模块的日志,那么logback也支持为某一个类或者某一个包单独打印日志到另外的文件中。

<?xml version="1.0" encoding="utf-8"?>
<configuration>
      <!--定义全局变量-->
      <property name="LOG_PATTERN" value="%d{yyyy-MM-dd HH:mm:ss.SSS} | %thread | %-5level | %msg%n"/>
      <property name="LOG_DIR" value="C:\\Users\\xxx\\Desktop\\info"/>

       <!--输出到控制台-->
      <appender name="CONSOLE-LOG" class="ch.qos.logback.core.ConsoleAppender">
        <layout class="ch.qos.logback.classic.PatternLayout">
            <pattern>${LOG_PATTERN}</pattern>
        </layout>
      </appender>

       <!--输出到文件-->
       <appender name="FILE-LOG" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <!--设置过滤器过滤ERROR级别的日志-->
        <filter class="ch.qos.logback.classic.filter.LevelFilter">
            <level>ERROR</level>
            <onMatch>DENY</onMatch>
            <onMismatch>ACCEPT</onMismatch>
        </filter>
        <encoder>
            <pattern>${LOG_PATTERN}</pattern>
        </encoder>
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <fileNamePattern>${LOG_DIR}/%d.log</fileNamePattern>
            <maxHistory>30</maxHistory>
        </rollingPolicy>
       </appender>

        <!--错误日志设置-->
        <appender name="ERROR_LOG" class="ch.qos.logback.core.rolling.RollingFileAppender">
          <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
            <level>ERROR</level>
          </filter>
          <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <FileNamePattern>${LOG_DIR}/error.%d{yyyy-MM-dd}.log</FileNamePattern>
            <MaxHistory>30</MaxHistory>
          </rollingPolicy>
          <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
            <pattern>${LOG_PATTERN}</pattern>
          </encoder>
        </appender>

        <!--输出到文件-->
       <appender name="BB-FILE-LOG" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <encoder>
            <pattern>${LOG_PATTERN}</pattern>
        </encoder>
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <fileNamePattern>${LOG_DIR}/bb-%d.log</fileNamePattern>
            <maxHistory>30</maxHistory>
        </rollingPolicy>
       </appender>

        <logger name="com.xxx.yyy.bb" level="INFO" additivity="false">
            <appender-ref ref="BB_FILE_LOG"/>
        </logger>

        <root level="info">
          <appender-ref ref="CONSOLE-LOG" />
          <appender-ref ref="FILE-LOG" />
          <appender-ref ref="ERROR-LOG" />
        </root>
</configuration>

我们在原有的配置文件基础上,加上一个logger配置,将指定包com.xxx.yyy.bb下的info级别及以上的日志输出都会使用BB_FILE_LOG输出组件。而在BB_FILE_LOG我们可以自定义输出的格式及文件。

需要额外注意additivity这个属性,其默认值为true,表示同时会记录到该包专属的日志文件bb-%d.log中和外层的统一日志文件%d.log中。这个其实很好理解,该包的代码是包含在整个工程里面的,外层日志输出组件当然也有记录它的必要。然而,当设置其值为false时,外层的日志输出组件就不再对它进行记录。

2.6 异步日志输出

当系统并发量较大,日志输出较多的时候,可以考虑使用异步日志输出的方案。

由于2.5节的配置文件已经内容较多了,我们使用2.2节的配置说剑做出说明。

<?xml version="1.0" encoding="utf-8"?>
<configuration>
      <!--定义全局变量-->
      <property name="LOG_PATTERN" value="%d{yyyy-MM-dd HH:mm:ss.SSS} | %thread | %-5level | %msg%n"/>

       <!--输出到控制台-->
      <appender name="CONSOLE-LOG" class="ch.qos.logback.core.ConsoleAppender">
        <layout class="ch.qos.logback.classic.PatternLayout">
            <pattern>${LOG_PATTERN}</pattern>
        </layout>
      </appender>

       <!--输出到文件-->
       <appender name="FILE-LOG" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <encoder>
            <pattern>${LOG_PATTERN}</pattern>
        </encoder>
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <fileNamePattern>C://Users//xxx//Desktop//info//%d.log</fileNamePattern>
            <maxHistory>30</maxHistory>
        </rollingPolicy>
       </appender>

        <!--异步文件日志设置-->
        <appender name="ASYNC-FILE-LOG" class="ch.qos.logback.classic.AsyncAppender">
            <discardingThreshold>0</discardingThreshold>
            <queueSize>256</queueSize>
            <appender-ref ref="FILE-LOG"/>
        </appender>

        <root level="info">
          <appender-ref ref="CONSOLE-LOG" />
          <appender-ref ref="ASYNC-FILE-LOG" />
        </root>
</configuration>

我们需要增加一个异步日志输出组件,在这个组件中引用原来同步输出日志组件,然后设置以下参数信息即可。

首先,discardingThreshold设置为0表示不丢弃任何日志。因为,默认情况下,当队列容量只剩下20%的时候,会自动丢弃WARN级别以下的日志,而我们是想要记录INFO级别的,不允许丢弃任何日志,所以设置为0。

其次,queueSize表示容纳日志事件的队列,默认情况下就是256,当队列已满的情况下,新的日志事件将会全部丢弃,直到日志队列被消费后不再已满,才能接受新的日志事件。

这两个参数都是可以自己调整设置的,看系统需求。

三、推荐资料

  1. logback中文网
  2. logback高级特性使用
上一篇下一篇

猜你喜欢

热点阅读