【Logback】开发环境怎么组织xml文件构建日志策略

目录

    • 前言
    • Logback 的前世今生
    • 一个基础的配置
      • 解释及理解
    • 需求:某个类/某个包使用特殊的日志等级
      • 解释及理解
    • 需求:写入日志文件
      • 解释及理解
    • 需求:有多个Appender时,只想用其中一个
      • 解释及理解
    • 需求:日志Rolling (按文件滚动增量增加)
      • 解释及理解
    • 后记

前言

  • 思路:官网学习,官网有大量的配置例子,并且都会给出解释
  • 需要前置知识:了解 Spring Boot 的依赖结构、门面模式
  • 最好了解:Spring MVC 的工作原理,可以类比理解 slf4j
  • 学习demo放到文末了(github)

Logback 的前世今生

log4j -> jul -> slf4j -> logback -> log4j2

简单来说,log4j是第一款日志框架,jdk看这个框架反响不错,就在jdk中内置了java.util.logging这个包提供日志功能。当时有两个日志框架在java开发界并存,如果项目A刚开始使用了log4j ,需要跟另外个项目B融合,项目B使用的是jul 。不同的日志框架的编码风格可能会造成混乱,于是乎遵循软件工程沉淀的门面模式经验,诞生了 slf4j这个框架。

  • 可以这么理解:
    slf4j 作为所有日志框架的前置过滤器,类似 Spring MVC 的 DispatcherServlet,log4j、jul 则是不同的view。这么设计的好处是,不论view如何变化,对客户端提供的请求接口不变、model也是不变的。

  • logbacklog4j2
    这两个框架都诞生在 slf4j 之后,完全遵循 slf4j 的接口规范。

  • 为什么选择logback
    本文只是因为这是 Spring Boot 的内置依赖
    【Logback】开发环境怎么组织xml文件构建日志策略_第1张图片

一个基础的配置

<configuration>
    <statusListener class="ch.qos.logback.core.status.OnConsoleStatusListener" />
    
    <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
        <encoder>
            <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%npattern>
        encoder>
    appender>

    <root level="debug">
        <appender-ref ref="STDOUT" />
    root>
configuration>

解释及理解

<statusListener class="ch.qos.logback.core.status.OnConsoleStatusListener" />
  • 打印日志框架本身的运行信息,非常有用,框架启动异常往往就能定位问题
    • 效果
      在这里插入图片描述

<root level="debug">
   <appender-ref ref="STDOUT" />
root>
  • root标签本质代表的是一个 Logger,但是这个Logger 的名称是顶级的,必须为名称为root
  • 日志等级 level

    error > warn > info > debug > trace

  • 一个 Logger 下面可以挂载N个appender
    • 为什么可以挂载N个?

    log.info(“hello") 即要打印到控制台又要打印到日志文件,那么就需要控制台的appender和日志文件的appender


<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
	<encoder>
		<pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%npattern>
	encoder>
appender>
  • 声明一个 Appender
  • 打印日志时候的前缀格式可以自定义,更多自定义的选项可以参考官网

需求:某个类/某个包使用特殊的日志等级

    
    <logger name="com.james.usinglog.InfoTests" level="INFO"/>
    <logger name="com.james.usinglog.TraceTests" level="TRACE"/>
    <root level="debug">
   		<appender-ref ref="STDOUT" />
	root>

值得注意的是,获取Logger时候,使用的.class文件一定要对应当前类
【Logback】开发环境怎么组织xml文件构建日志策略_第2张图片

解释及理解

上文提到 root 是一个特殊的 logger , 也就是所有包的打印都默认继承一个叫 rootlogger
如果要针对某个类或者包覆盖掉父类的实现,非常简单,提供自己的实现即可。所以定义一个logger 并声明一个独有的 level 就能实现需求。官网对这个继承体系提供例子帮助我们理解:

【Logback】开发环境怎么组织xml文件构建日志策略_第3张图片


需求:写入日志文件

    <appender name="FILE" class="ch.qos.logback.core.FileAppender">
        <file>logFile.logfile>

        <encoder>
            <pattern>%date %level [%thread] %logger{10} [%file:%line] %msg%npattern>
        encoder>
    appender>
    <root level="debug">
        <appender-ref ref="STDOUT" />
        <appender-ref ref="FILE" />
    root>

解释及理解

 <appender name="FILE" class="ch.qos.logback.core.FileAppender">
  • 新建一个appender,使用logback 的 ch.qos.logback.core.FileAppender 实现

<file>logFile.logfile>
  • 日志文件的相对路径,当然也可以改为绝对路径

<root level="debug">
    <appender-ref ref="STDOUT" />
    <appender-ref ref="FILE" />
root>
  • 把新的appender加进logger的结构中

需求:有多个Appender时,只想用其中一个


<logger name="com.james.usinglog.FileOnlyTests" additivity="false">
	<appender-ref ref="FILE" />
logger>
<root level="debug">
    <appender-ref ref="STDOUT" />
    <appender-ref ref="FILE" />
root>

解释及理解

上文提到了 logger 的继承体系,深层次来说,他们的Appender也是继承的。怎么理解?如果一个包有自己的logger,它默认继承了root,则自己的Logger和root的logger都会被触发。这个特性使我们配置一个新logger加入到 root标签,就能做到同时往控制台和文件打印日志。

  • 取一个逆向思维,只让自己的logger生效怎么办?
    <logger name="com.james.usinglog.FileOnlyTests" additivity="false">
    

    打破继承体系即可,仅仅声明使用自己的 additivity=“false”


需求:日志Rolling (按文件滚动增量增加)

    <appender name="ROLLING_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <file>rollingLogFile.logfile>
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            
            <fileNamePattern>rollingLogFile.%d{yyyy-MM-dd_HH-mm}.logfileNamePattern>
        rollingPolicy>

        <encoder>
            <pattern>%date %level [%thread] %logger{10} [%file:%line] %msg%npattern>
        encoder>
    appender>
    
    <root level="debug">
        <appender-ref ref="STDOUT" />
        <appender-ref ref="FILE" />
        <appender-ref ref="ROLLING_FILE" />
    root>

值得注意的是: class=“ch.qos.logback.core.rolling.RollingFileAppender” 一定要区分与普通的
FileAppender 实现,不然加载配置文件会报错

解释及理解

仅仅是使用一个logback 的 Appender实现。关键是理解表达式 %d{yyyy-MM-dd_HH-mm} 的副作用。官网明确说明是有两个副作用:
1. 确认文件名格式
2. 以最小单位进行分片。EG:{yyyy-MM-dd_HH-mm} 就是以分钟为单位进行分片,如:
【Logback】开发环境怎么组织xml文件构建日志策略_第4张图片
更多表达式可以参考官网

后记

理解了 logger 的继承体系和 appender 的具体实现后,组织自己的日志策略就相对简单了。诚然,生产环境的配置更加复杂,包括引入了邮件预警等实现,这个需要使用到其他包,后续有机会会研究这个东西。
附上本文练习用的github地址:
https://github.com/ChenghanY/usinglog

你可能感兴趣的:(后端,Spring,架构,logback,xml,spring,boot)