Spring Boot 集成日志框架

一个生产系统除了保证正确性、可靠性等因素外,还应保证可维护性。而系统的可维护性,其中一个重要衡量指标就是出现问题后,是否能够快速定位并解决问题。除了系统结构设计合理外,必要的系统日志可以帮助快速定位问题,这也是引入日志框架的意义所在。
接下来简要介绍Spring Boot下日志框架选择。

日志框架选型

在选择日志框架时,既需要选择门面日志,也需要选择日志实现库。所谓门面日志仅定义了接口并未定义实现(这符合面向接口编程)。主流的门面日志有JUL、commons-logging、SLF4j。其中JUL是JDK的java.util.logging提供的门面日志。尽管JDK提供了门面日志框架,但该框架是Java 1.4才引入。而在这之前因为JDK对日志没有提供很好且实用的规范,导致各公司或开发者选择自行造轮子。而JUL也未推广开来。commons-logging则是apache最早提供的日志的门面接口。它的主要作用是提供一个日志门面,使用者可以使用不同的日志实现。目前,commons-logging已处于停止维护阶段,上一个版本还停留在2014年。SLF4j是Simple Logging Facade for Java的简称,也是java的日志门面。类似于apache commons-logging,SLF4j对不同日志框架提供的一个门面封装,可以在部署的时候不修改任何配置即可接入一种日志实现方案。目前,SLF4J使用广泛,已成为日志门面事实上的标准,也是Spring Boot默认的门面日志。
选择完门面日志,接下来选择日志实现库。目前主流的日志实现库主要有两个Logback、Log4j2(Log4j的替代版本,Log4j在2012年已停止维护)。目前,Logback、Log4j2二者生态可谓不相上下。Log4j2 凭借着入场早、背靠 Apache 两大优势有着不错的用户支持,官网文档也很完善。而 Logback 凭借着 SLF4j 的原生实现以及作为Spring Boot 默认的日志框架,同样也拥有着很好的前景。这里,选择Log4j2作为日志实现库。其中一个重要原因是在安全送检阶段时,相较于Logback,Log4j2可以更轻松的实现各组件打印日志的屏蔽。

集成SLF4J+Log4j2日志框架

Spring Boot默认使用SLF4J作为门面日志,所以无需单独引入SLF4J相关依赖。但是,由于Spring Boot默认使用Logback作为日志实现,所以还需主动排除该依赖,然后再引入Log4j2相关依赖。对应pom配置如下:

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</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-log4j2</artifactId>
    </dependency>
</dependencies>

引入Log4j2依赖后,还需手动添加日志配置文件(也可使用默认配置,但生产环境一般都需要配置)。将log4j2.xml文件放置到resources目录下,然后在application.yaml中指定该日志配置文件。对应配置片段如下:

# 日志
logging:
  config: classpath:log4j2.xml

接下来重点介绍下如何书写log4j2.xml文件。
(1) Configuration根节点
Configuration配置节是log4j2.xml文件的根节点。该配置节有两个常用属性:status和monitorinterval。其中,status用来打印到控制台的内部 Log4j 日志事件的级别,设置该属性是查找 Log4j 故障的第一手工具。monitorinterval用于指定检查配置文件是否有更新的间隔秒数,单位是s,默认值是5s。另外,Configuration配置节有两个子节点:Appenders和Loggers。
(2) Appender节点
Log4j 使用 Appender 将日志事件数据写到各种目标位置(如控制台、文件、多种数据库 API、远程套接字服务器、Apache Flume、JMS、远程 UNIX Syslog daemon等)。常见的有三种子节点:Console、RollingFile。
(3) ConsoleAppender
ConsoleAppender 会将输出写入 System.out(默认目标位置)或 System.err 中。必须提供一个 Layout 来格式化 LogEvent 。典型的 ConsoleAppender 配置如下:

<?xml version="1.0" encoding="UTF-8"?>
<Configuration>
  <Appenders>
    <Console name="STDOUT" target="SYSTEM_OUT">
      <PatternLayout pattern="%m%n"/>
    </Console>
  </Appenders>
  <Loggers>
    <Root level="error">
      <AppenderRef ref="STDOUT"/>
    </Root>
  </Loggers>
</Configuration>

(4) RollingFileAppender
RollingFileAppender 会将日志输出到 fileName 参数指定的文件中,且需要指定 TriggeringPolicy 和 RolloverStrategy。其中 TriggeringPolicy 决定是否生成新的日志文件,RolloverStrategy 决定如何生成新的日志文件。如果没有配置 RolloverStrategy,则会使用 DefaultRolloverStrategy 。从 Log4j 2.9 开始,可以在 DefaultRolloverStrategy 中配置一个自定义的 POSIX 文件属性查看动作,如果没有定义该动作,则将会使用从 RollingFileAppender 继承的 POSIX。需要说明的是,RollingFileAppender 不支持文件锁。这也就是说,如果存在并发写入,会导致写覆盖的问题。
(5) 配置 Logger
LoggerConfig 通过 Logger 元素进行配置。Logger 元素可用属性如下:
(a) name :必选,用于标识该 logger
(b) level :可选,用来设置日志级别。其值可以为 TRACE、DEBUG、INFO、WARN、ERROR、ALL 或者 OFF。如果没有指定该属性,则默认为 ERROR;
© additivity :可选的布尔值,用来设置相加性。如果没有指定该属性,则默认为 true。
完成上述配置后,就可以在编码的过程中使用日志组件了。为简化日志组件的使用,引入lombok依赖(lombok提供设计时注解来简化日志组件的使用)。lombok依赖如下:

<dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
</dependency>

这样就可以使用lombok提供的注解来使用日志组件,示例如下:

@SpringBootApplication
@Slf4j
public class SpringBootLogApplication {
    public static void main(String[] args) {
        log.info("[SpringBootLogApplication] main -- begin");
        SpringApplication.run(SpringBootLogApplication.class, args);
        log.info("[SpringBootLogApplication] main -- end");
    }
}

相关示例可参考spring-boot-example源码。
需要说明的是,Log4j2 在用于 Java EE Web 应用时要确保日志资源在容器关闭或 Web 应用取消部署时能恰当地清理。为了做到这一点,需要在 Web 应用中添加 log4j-web 的依赖。该依赖会自动在Web应用取消部署或结束部署时,自动执行清理操作。对应依赖如下:

<dependency>
    <groupId>org.apache.logging.log4j</groupId>
    <artifactId>log4j-web</artifactId>
</dependency>

日志级别

常见的日志级别划分共有8个,按照从低到高为:All < Trace < Debug < Info < Warn < Error < Fatal < OFF。
(1) All:最低等级,用于打开所有日志记录。
(2) Trace:追踪级别,开发者可以通过trace输出跟踪程序执行过程,并通过提升日志级别避免该类日志的输出。
(3) Debug:指出细粒度信息事件对调试应用程序是非常有帮助的。
(4) Info:消息在粗粒度级别上突出强调应用程序的运行过程。
(5) Warn:输出警告及warn以下级别的日志。
(6) Error:输出错误信息日志。
(7) Fatal:输出每个严重的错误事件将会导致应用程序的退出的日志。
(8) OFF:最高等级,用于关闭所有日志记录。

总结

Spring Boot在集成SLF4J+Log4j2日志框架时,可以划分为如下四步:
(1) 引入SLF4J+Log4j2相关依赖。因为Spring Boot默认使用SLF4J作为门面日志,所以无需单独引入SLF4J相关依赖。但是,由于Spring Boot默认使用Logback作为日志实现,所以还需主动排除该依赖,然后再引入Log4j2相关依赖。
(2) 手动引入日志配置文件。将log4j2.xml文件放置到resources目录下,然后在application.yaml中指定该日志配置文件。
(3) 更新log4j2.xml文件。生产环境下,一般需要定义log4j2.xml文件。如实现指定输出日志级别,屏蔽无关日志,指定日志删除策略等。
(4) 使用日志组件,打印系统日志。为简化日志组件的使用,引入lombok依赖。

参考

https://www.cnblogs.com/PerkinsZhu/p/6440584.html 系统日志的重要性
https://zhuanlan.zhihu.com/p/336242688 系统可维护性
https://blog.csdn.net/jiangsir_sub/article/details/97522674 浅谈日志门面
https://www.cnblogs.com/mzc1997/p/14367828.html Springboot日志框架选型
https://www.cnblogs.com/xuningfans/p/12196175.html Java 日志框架选型
https://www.cnblogs.com/simpleito/p/15125369.html Java 日志框架概述
https://www.cnblogs.com/simpleito/p/15132231.html SLF4J 快速入门 / 绑定原理
https://logging.apache.org/log4j/2.x/ Apache Log4j2
https://www.cnblogs.com/bigdataZJ/p/spring-boot-log4j2.html Spring Boot系列——如何集成Log4j2
https://www.cnblogs.com/hafiz/p/6170702.html log4j2配置文件log4j2.xml详解
https://www.cnblogs.com/didispace/p/15674462.html 一行配置搞定 Spring Boot项目的 log4j2 核弹漏洞!
https://www.jianshu.com/p/bfc182ee33db Log4j2详解——XML配置详解
https://www.jianshu.com/p/8b30d312a47b Log4j2详解——XML配置示例

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值