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

25 篇文章 0 订阅
16 篇文章 0 订阅

前言

  • 思路:官网学习,官网有大量的配置例子,并且都会给出解释
  • 需要前置知识:了解 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 的内置依赖
    在这里插入图片描述

一个基础的配置

<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%n</pattern>
        </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%n</pattern>
	</encoder>
</appender>
  • 声明一个 Appender
  • 打印日志时候的前缀格式可以自定义,更多自定义的选项可以参考官网

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

    <!--顶级是debug日志; 这里也可以设置包名-->
    <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文件一定要对应当前类
在这里插入图片描述

解释及理解

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

请添加图片描述


需求:写入日志文件

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

        <encoder>
            <pattern>%date %level [%thread] %logger{10} [%file:%line] %msg%n</pattern>
        </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.log</file>
  • 日志文件的相对路径,当然也可以改为绝对路径

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

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

<!--该类(也可以写包名)不让root接管, 所以这个类的日志不会打印到控制台-->
<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.log</file>
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <!-- 表达式有两个作用 1.确认滚动增加的最小单位 2. 文件格式 -->
            <fileNamePattern>rollingLogFile.%d{yyyy-MM-dd_HH-mm}.log</fileNamePattern>
        </rollingPolicy>

        <encoder>
            <pattern>%date %level [%thread] %logger{10} [%file:%line] %msg%n</pattern>
        </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} 就是以分钟为单位进行分片,如:
在这里插入图片描述
更多表达式可以参考官网

后记

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值