大家好!我是今越。重点梳理一下在 Java 程序开发中关于日志管理的知识点,以及在 Spring Boot 框架中该如何使用日志。
在 Java 中,日志框架主要分为两大类:日志门面和日志实现。
日志门面
日志门面定义了一组日志的接口规范,它并不提供底层具体的实现逻辑,用来解决系统与日志实现框架的耦合性,可以搭配任意的日志实现框架。当在项目中使用日志门面时,无论底层的日志实现框架是哪种,都不用修改代码,就可以直接使用。
Jcl (Apache Commons Logging) 和 Slf4j (Simple Logging Facade for Java) 属于日志门面框架。
日志门面是不能单独使用的,它必须和一种具体的日志实现框架相结合使用。
日志实现
日志实现则是日志具体的实现,包括日志级别控制、日志打印格式、日志输出形式(输出到数据库、输出到文件、输出到控制台等)。
Java Util Logging、Log4j、Logback、Log4j2 属于日志实现框架。
Java Util Logging:是 JDK 在 1.4 版本中引入的 Java 原生日志框架。
Log4j :Apache 的一个开源项目,可以控制日志信息输送的目的地是控制台、文件、GUI组件等,可以控制每一条日志的输出格式,这些可以通过一个配置文件来灵活地进行配置,而不需要修改应用的代码。虽然已经停止维护了,但目前绝大部分企业都是用的 Log4j。
Logback :同样是由 Log4j 的作者设计完成的,拥有更好的特性,用来取代 Log4j 的一个日志框架,是 Slf4j 的原生实现。
Log4j2 :不仅仅是 Log4j 的一个升级版本了,它从头到尾都被重写了。
将日志门面和日志实现分离是一种典型的门面模式,该方式可以让具体业务在不同的日志实现框架之间自由切换,而不需要改动任何代码,开发者只需要掌握日志门面的 API 即可。
日志级别
使用日志级别的好处在于,调整级别就可以屏蔽掉很多调试相关的日志输出。
Java Util Logging
定义了 7 个日志级别,从严重到普通依次是:
SEVERE > WARNING > INFO > CONFIG > FINE > FINER > FINEST
默认级别是 INFO,所以 INFO 级别以下的日志,不会被打印出来。
Log4j & Log4j2
定义了 8 个日志级别(除去 OFF 和 ALL,可以说分为 6 个级别),从严重到普通依次是:
- OFF:最高等级的,用于关闭所有日志记录
- FATAL:重大错误,这种级别可以直接停止程序了
- ERROR:打印错误和异常信息,如果不想输出太多的日志,可以使用这个级别
- WARN:警告提示
- INFO:用于生产环境中输出程序运行的一些重要信息,不能滥用
- DEBUG:用于开发过程中打印一些运行信息
- TRACE:追踪,就是程序推进一下,可以写个 TRACE 输出
- ALL:最低等级,用于打开所有日志记录
Logback
日志级别比较简单,从严重到普通依次是:
ERROR > WARN > INFO > DEBUG > TRACE
使用方案
Java Util Logging 日志实现框架,在 JVM 启动时会读取其配置文件并完成初始化,一旦应用程序开始运行,就无法修改配置。另外,这种日志实现框架配置也不太方便,只能在 JVM 启动时传递参数,像下面这样:
-Djava.util.logging.config.file=<config-file-name>
由于这些局限性,导致 Java Util Logging 并未广泛使用。
Log4j 虽然配置繁琐,但是一旦配置完成,使用起来就非常方便,只需要将相关的配置文件放到 classpath 下面。Log4j 可以和 Apache Commons Logging 搭配使用,Apache Commons Logging 会自动搜索并使用 Log4j,如果没有找到 Log4j,再使用 Java Util Logging。
比 Log4j + Apache Commons Logging 组合更得人心的是 Slf4j + Logback 组合。
Logback 是 Slf4j 的原生实现框架,它也出自 Log4j 作者(Ceki Gülcü)之手,但是相比 Log4j,它拥有更多的优点、特性以及更强的性能。
使用方案推荐
- 如果不想添加任何依赖,使用 Java Util Logging 或框架容器已经提供的日志接口
- 如果比较在意性能,可以使用 Slf4j + Logback 或者 Slf4j + Log4j2,更推荐后者
- 如果项目中已经使用了 Log4j 且没有发现性能问题,推荐组合为:Slf4j + Log4j2
性能对比
引用网上对 Log4j、Logback、Log4j2 的性能评测截图来做说明:
可以看到在同步日志模式下,Logback 的性能是最糟糕的;
Log4j2 的性能无论在同步日志模式还是异步日志模式下都是最佳的;
关于 Log4j2 性能好的原因:因为该日志实现框架使用了 LMAX,一个无锁的线程间通信库代替了 Logback 和 Log4j 的队列,使得并发性能大大提升。
Spring Boot 日志实现
Spring Boot 使用 Apache Commons Logging 作为内部的日志框架门面,它只是一个日志接口,在实际应用中需要为该接口来指定相应的日志实现。Spring Boot 默认的日志实现是 Logback。
在 Spring Boot 项目中,只要添加了如下 web 依赖,日志依赖就自动添加进来了:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
日志配置
Spring Boot 的日志系统会自动根据 classpath 下的内容选择合适的日志配置,在这个过程中首选 Logback。
如果开发者需要修改日志级别,只需在 application.properties 配置文件中通过 logging.level 前缀 + 包名 的形式进行配置,例如
logging.level.indi.demo.logging.mapper=debug
logging.level.org.springframework.web=debug
如果想将日志输出到文件,可以通过如下配置指定日志文件名:
# 指定日志文件名称
logging.file.name=logfile.log
# 指定日志文件全路径
logging.file.name=/Users/jacksons/logfile.log
如果你只是想重新定义输出日志文件的路径,也可以使用 logging.file.path 属性,如下:
# 仅支持配置路径,默认文件名称 spring.log
logging.file.path=/Users/jacksons/dev/workspace/springboot/logs
如果想对输出到文件中的日志进行精细化管理,还有如下一些属性可以配置:
logging.logback.rollingpolicy.file-name-pattern:日志归档的文件名,日志文件达到一定大小之后,自动进行压缩归档
logging.logback.rollingpolicy.clean-history-on-start:是否在应用启动时进行归档管理
logging.logback.rollingpolicy.max-file-size:日志文件大小上限,达到该上限后,会自动压缩
logging.logback.rollingpolicy.total-size-cap:日志文件被删除之前,可以容纳的最大大小
logging.logback.rollingpolicy.max-history:日志文件保存的天数
日志文件归档这块,测试如下
首先,在 application.properties 配置文件中进行设置
# 日志文件大小上限,达到该上限后,会自动压缩
logging.logback.rollingpolicy.max-file-size=1MB
然后,创建测试接口
package indi.demo.logging;
import org.slf4j.Logger;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import static org.slf4j.LoggerFactory.getLogger;
@RestController
public class HelloController {
private static final Logger LOG = getLogger(HelloController.class);
@GetMapping("/hello")
public void hello() {
for (int i = 0; i < 100000; i++) {
LOG.info("hello jackson!");
}
}
}
访问该接口,可以看到最终生成的日志文件被自动压缩了:
在配置文件中还可以配置日志分组。日志分组能够把相关的 Logger 放到一个组统一管理。
例如,我们可以定义一个 tomcat 组:
logging.group.tomcat=org.apache.catalina,org.apache.coyote,org.apache.tomcat
统一管理 tomcat 组中的所有 Logger 的日志级别:
logging.level.tomcat=TRACE
Spring Boot 中还预定义了两个日志分组 web 和 sql,如下:
不过在 application.properties 中只能实现对日志一些非常简单的配置,如果想实现更加细粒度的日志配置,那就需要使用日志实现的原生配置,例如 Logback 的 classpath:logback.xml
,Log4j 的 classpath:log4j.properties
等。如果这些日志配置文件存在于 classpath 下,那么默认情况下,Spring Boot 就会自动加载这些配置文件。
Logback 配置
基本配置
默认的 Logback 配置文件名有两种:
- logback.xml:这种配置文件会直接被日志框架加载。
- logback-spring.xml:这种配置文件不会被日志框架直接加载,而是由 Spring Boot 去解析日志配置,可以使用 Spring Boot 的高级 Profile 功能。
Spring Boot 中为 Logback 提供了四个默认的配置文件,位置在 org/springframework/boot/logging/logback/
,分别是:
- defaults.xml:提供了公共的日志配置,日志输出规则等
- console-appender.xml:使用 CONSOLE_LOG_PATTERN 添加一个ConsoleAppender
- file-appender.xml:添加一个 RollingFileAppender
- base.xml:为了兼容旧版 Spring Boot 而提供的
如果需要自定义 logback.xml 文件,可以在自定义时使用这些默认的配置文件,也可以不使用。例如
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<include resource="org/springframework/boot/logging/logback/defaults.xml"/>
<include resource="org/springframework/boot/logging/logback/console-appender.xml" />
<root level="INFO">
<appender-ref ref="CONSOLE" />
</root>
<logger name="org.springframework.web" level="DEBUG"/>
</configuration>
可以通过 include 引入 Spring Boot 已经提供的配置文件,也可以自定义。
输出到文件
如果想禁止控制台的日志输出,转而将日志内容输出到一个文件,我们可以自定义一个 logback-spring.xml 文件,并引入前面所说的 file-appender.xml 文件。
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<include resource="org/springframework/boot/logging/logback/defaults.xml" />
<property name="LOG_FILE" value="${LOG_FILE:-${LOG_PATH:-${LOG_TEMP:-${java.io.tmpdir:-/tmp}}/}spring.log}"/>
<include resource="org/springframework/boot/logging/logback/file-appender.xml" />
<root level="INFO">
<appender-ref ref="FILE" />
</root>
</configuration>
Log4j 配置
1)引入依赖
Spring Boot 默认是用 Logback 的日志实现框架,所以需要先排除 Logback,否则会出现依赖冲突,然后引入 Log4j 的依赖。
<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-log4j</artifactId>
<version>1.3.8.RELEASE</version>
</dependency>
2)配置文件模版
在引入了 Log4j 依赖之后,只需要在 resources 目录下新建日志配置文件即可使用。Log4j 支持两种配置文件格式,一种是 xml 格式的文件,一种是 properties 属性文件,下面以 properties 属性文件为例来介绍 Log4j 的配置。
# 配置根Logger(记录器):设置日志记录的最低级别,指定日志信息输出源(可以配置多个,用逗号分隔)
log4j.rootLogger=DEBUG,console,infoFile
# 定义控制台输出源
log4j.appender.console=org.apache.log4j.ConsoleAppender
# 指定日志信息的最低输出级别,默认为DEBUG
log4j.appender.console.Threshold=DEBUG
# 默认值为true,表示日志信息会被立即输出
log4j.appender.console.ImmediateFlush=true
# 默认是System.out,指定输出控制台
log4j.appender.console.Target=System.err
# 自定义日志信息的输出格式(布局)
log4j.appender.console.layout=org.apache.log4j.PatternLayout
log4j.appender.console.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss,SSS} [%-5p] [%t] %l -> %m%n
# 定义日志文件输出源
log4j.appender.infoFile=org.apache.log4j.DailyRollingFileAppender
log4j.appender.infoFile.Threshold=INFO
log4j.appender.infoFile.ImmediateFlush=true
# 默认值是true,表示将日志信息追加到指定文件中,false表示将日志信息覆盖指定的文件内容
log4j.appender.infoFile.Append=true
# 指定日志信息的输出文件路径和名称
log4j.appender.infoFile.file=info.log
# 指定多久滚动一次文件,例如'.'yyyy-MM-dd表示每天滚动一次日志文件,即每天产生一个新的日志文件
log4j.appender.infoFile.DatePattern='.'yyyy-MM-dd
log4j.appender.infoFile.layout=org.apache.log4j.PatternLayout
log4j.appender.infoFile.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss,SSS} [%-5p] [%t] %l -> %m%n
# 自定义Logger(记录器),区别于默认的log4j.rootLogger,用log4j.logger.name来定义需要记录的独立日志
log4j.logger.traceLogger=INFO,traceFile
# 指定自定义Logger是否会在父Logger的appender里输出,默认为true,这里的自定义Logger为traceLogger
log4j.additivity.traceLogger=false
# 定义日志文件输出源
log4j.appender.traceFile=org.apache.log4j.DailyRollingFileAppender
log4j.appender.traceFile.Threshold=INFO
log4j.appender.traceFile.ImmediateFlush=true
log4j.appender.traceFile.Append=true
log4j.appender.traceFile.File=service.log
# 指定日志信息输出的文件的最大大小
log4j.appender.traceFile.MaxFileSize=1MB
# 指定日志信息输出的文件的最大数量
log4j.appender.traceFile.MaxBackupIndex=10
log4j.appender.traceFile.DatePattern='.'yyyy-MM-dd
log4j.appender.traceFile.layout=org.apache.log4j.PatternLayout
log4j.appender.traceFile.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss,SSS} [%-5p] [%t] %l -> %m%n
3)配置参数介绍
Log4j 有三个主要的组件:
- Logger:记录器,指定日志级别和输出源
- Appender:输出源,指定日志信息的输出目的地
- Layout:布局,指定日志信息的输出格式
配置根 Logger
log4j.rootLogger=[level], appenderName1, appenderName2, ...
level : 设置日志记录的最低级别,例如测试环境就可以设置成 DEBUG 级别
appenderName : 指定日志信息要输出到哪里,可以同时指定多个输出目的地,用逗号分隔
自定义 Logger
在一些场景下,想用某些特殊的业务日志记录一些问题,又不想和其它日志混在一起,这时可以通过自定义 Logger 去做日志记录。
log4j.logger.name=[level], appenderName1, appenderName2, ...
name : 自定义 Logger 的名称,区别于根 Logger
例如,自定义 Logger 和 Appender 配置如下
log4j.logger.traceLogger=INFO,traceFile
# 指定自定义Logger是否会在父Logger的appender里输出,默认为true,这里的自定义Logger为traceLogger
log4j.additivity.traceLogger=false
log4j.appender.traceFile=org.apache.log4j.DailyRollingFileAppender
log4j.appender.traceFile.Threshold=INFO
log4j.appender.traceFile.ImmediateFlush=true
log4j.appender.traceFile.Append=true
log4j.appender.traceFile.File=service.log
log4j.appender.traceFile.MaxFileSize=1MB
log4j.appender.traceFile.MaxBackupIndex=10
log4j.appender.traceFile.DatePattern='.'yyyy-MM-dd
log4j.appender.traceFile.layout=org.apache.log4j.PatternLayout
log4j.appender.traceFile.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss,SSS} [%-5p] [%t] %l -> %m%n
在代码中,通过定义日志变量来记录独立的业务日志信息,例如
private static Logger traceLogger = LoggerFactory.getLogger("traceLogger");
单独调整某个包的日志记录级别
例如,单独将 org.springframework.boot.autoconfigure 包下的日志级别设置为 INFO
log4j.logger.org.springframework.boot.autoconfigure=INFO
配置日志信息输出目的地 Appender
log4j.appender.appenderName=className
appenderName : 自定义 appderName,在记录器 Logger 设置中使用,例如 log4j.rootLogger
className 可以设置的值如下:
org.apache.log4j.ConsoleAppender(控制台)
org.apache.log4j.FileAppender(文件)
org.apache.log4j.DailyRollingFileAppender(每天产生一个日志文件)
org.apache.log4j.RollingFileAppender(文件大小到达指定尺寸的时候产生一个新的文件)
org.apache.log4j.WriterAppender(将日志信息以流格式发送到任意指定的地方)
ConsoleAppender
Threshold=WARN:指定日志信息的最低输出级别,默认为DEBUG
ImmediateFlush=true:默认值是true,表示日志信息会被立即输出,设为false则不输出
Target=System.err:默认值是System.out,指定输出控制台
FileAppender
Threshold=WARN:指定日志信息的最低输出级别,默认为DEBUG
ImmediateFlush=true:默认值是true,表示日志信息会被立即输出,设为false则不输出
File=mylog.log:指定日志信息输出到mylog.log文件
Append=false:默认值是true,表示将日志信息追加到指定文件中,false表示将日志信息覆盖指定的文件内容
DailyRollingFileAppender
Threshold=WARN:指定日志信息的最低输出级别,默认为DEBUG
ImmediateFlush=true:默认值是true,表示日志信息会被立即输出,设为false则不输出
File=mylog.log:指定日志信息输出到mylog.log文件
Append=false:默认值是true,表示将日志信息追加到指定文件中,false表示将日志信息覆盖指定的文件内容
DatePattern=”.”yyyy-MM:每月滚动一次日志文件,即每月产生一个新的日志文件,当前月的日志文件名为mylog.log,前一个月的日志文件名为mylog.log.yyyy-MM,另外,也可以指定按月、周、天、时和分来滚动日志文件,对应的格式如下:
1) ”.”yyyy-MM: 每月
2) ”.”yyyy-ww: 每周
3) ”.”yyyy-MM-dd: 每天
4) ”.”yyyy-MM-dd-a: 每天两次
5) ”.”yyyy-MM-dd-HH: 每小时
6) ”.”yyyy-MM-dd-HH-mm: 每分钟
RollingFileAppender
Threshold=WARN:指定日志信息的最低输出级别,默认为DEBUG
ImmediateFlush=true:默认值是true,表示日志信息会被立即输出,设为false则不输出
File=mylog.log:指定日志信息输出到mylog.log文件
Append=false:默认值是true,表示将日志信息追加到指定文件中,false表示将日志信息覆盖指定的文件内容
MaxFileSize=100KB:后缀可以是KB, MB或者GB,在日志文件到达该大小时,将会自动滚动,即将原来的内容移到mylog.log.1文件中
MaxBackupIndex=2:指定可以产生的滚动文件的最大数,例如,设为2则可以产生mylog.log.1,mylog.log.2两个滚动文件和一个mylog.log文件
配置日志信息的输出格式 Layout
log4j.appender.appenderName.layout=className
className 可以设置的值如下:
org.apache.log4j.HTMLLayout(以HTML表格形式布局)
org.apache.log4j.PatternLayout(可以灵活地指定布局模式)
org.apache.log4j.SimpleLayout(包含日志信息的级别和信息字符串)
org.apache.log4j.TTCCLayout(包含日志产生的时间、线程、类别等信息)
HTMLLayout
LocationInfo=true:输出java文件名称和行号,默认值是false
Title=My Logging: 默认值是Log4J Log Messages
PatternLayout
ConversionPattern=%m%n:设定以怎样的格式显示消息
格式化符号说明
%p:输出日志信息的优先级,即 DEBUG,INFO,WARN,ERROR,FATAL
%d:输出日志时间点的日期或时间,默认格式为 ISO8601,也可以在其后指定格式,如:%d{yyyy/MM/dd HH:mm:ss,SSS}
%r:输出自应用启动到输出该 log 信息耗费的毫秒数
%c:输出日志信息所属的类目,通常就是所在类的全名
%t:输出产生该日志事件的线程名
%l:输出日志事件的发生位置,相当于 %c.%M(%F:%L) 的组合,包括类全名、方法、文件名以及在代码中的行数。例如:test.TestLog4j.main(TestLog4j.java:10)
%M:输出产生日志信息的方法名
%F:输出日志信息产生时所在的文件名称
%L:输出代码中的行号
%m:输出代码中指定的具体日志信息
%n:输出一个回车换行符,Windows 平台为 ”\r\n”,Unix 平台为 ”\n” 输出日志信息后换行
%x:输出和当前线程相关联的 NDC(嵌套诊断环境),尤其是用到像 java servlets 这样的多客户多线程的应用中
%%:输出一个 ”%” 字符
另外,还可以在%与格式字符之间加上修饰符来控制其最小长度、最大长度、和文本的对齐方式。如:
c:指定输出 category 的名称,最小的长度是 20,如果 category 的名称长度小于 20 的话,默认情况下右对齐
%-20c:“-” 号表示左对齐
%.30c:指定输出 category 的名称,最大的长度是 30,如果 category 的名称长度大于 30 的话,就会将左边多出的字符截掉,但小于 30 的话也不会补空格
Log4j2 配置
1)引入依赖
Spring Boot 默认是用 Logback 的日志实现框架,所以需要先排除 Logback,否则会出现依赖冲突,然后引入 Log4j2 的依赖。
<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>
2)配置文件
如果自定义了文件名,需要在 application.properties 中配置。
logging.config=xxxx.xml
logging.level.cn.com.xxx=debug
默认文件名称:log4j2.xml 、log4j2-spring.xml
3)配置文件模版
Log4j 通常以 properties 属性文件来作为日志配置文件,而现在的 Log4j2 已经弃用了这种方式,采用的是 xml,json 或者 jsn 格式的文件,可能这也是技术发展的一个必然性,因为 properties 属性文件的可阅读性不好。
在 resources 目录下新建 log4j2.xml 日志配置文件,参考模版内容如下:
<?xml version="1.0" encoding="UTF-8"?>
<!--Configuration后面的status,这个用于设置log4j2自身内部的信息输出,可以不设置,当设置成trace时,你会看到log4j2内部各种详细输出-->
<!--monitorInterval:Log4j能够自动检测配置文件的变化,设置检测间隔秒数-->
<Configuration monitorInterval="5">
<!--日志级别以及优先级排序: OFF > FATAL > ERROR > WARN > INFO > DEBUG > TRACE > ALL -->
<!--变量配置-->
<Properties>
<!--格式化输出:%date表示日期,%thread表示线程名,%-5level表示级别从左显示5个字符宽度,%msg表示日志消息,%n表示换行符-->
<Property name="LOG_PATTERN" value="[%d][%t][%p][%c:%L] %m%n" />
<!--定义日志存储的路径-->
<Property name="FILE_PATH" value="日志文件存储的路径" />
<Property name="FILE_NAME" value="日志文件名称" />
</Properties>
<Appenders>
<!--定义控制台输出源-->
<Console name="Console" target="SYSTEM_OUT">
<!--输出日志的格式-->
<PatternLayout pattern="[%d][%t][%p][%l] %m%n" />
<!--控制台只输出level及其以上级别的信息(onMatch),其它的直接拒绝(onMismatch)-->
<ThresholdFilter level="INFO" onMatch="ACCEPT" onMismatch="DENY" />
</Console>
<!--文件会打印出所有信息,这个log每次运行程序会自动清空,由append属性决定,适合临时测试用,默认为true表示追加-->
<File name="Filelog" fileName="${FILE_PATH}/test.log" append="false">
<PatternLayout pattern="${LOG_PATTERN}" />
</File>
<!--这个会打印出所有的info及以下级别的信息,每次大小超过size,则这size大小的日志会自动存入按年份-月份建立的文件夹下面并进行压缩,作为存档-->
<RollingFile name="RollingFileInfo" fileName="${FILE_PATH}/info.log" filePattern="${FILE_PATH}/${FILE_NAME}-INFO-%d{yyyy-MM-dd}_%i.log.gz">
<!--仅输出INFO级别的日志信息-->
<Filters>
<!--文件只输出level及以上级别的信息(onMatch),其它的直接拒绝(onMismatch)-->
<ThresholdFilter level="INFO" onMatch="ACCEPT" onMismatch="DENY" />
<!--文件只输出level以下级别的信息(onMatch),其它的直接拒绝(onMismatch)-->
<ThresholdFilter level="WARN" onMatch="DENY" onMismatch="NEUTRAL" />
</Filters>
<!--输出日志的格式-->
<PatternLayout pattern="${LOG_PATTERN}" />
<!--日志文件触发策略-->
<Policies>
<!--基于时间的触发策略。该策略主要是完成周期性的log文件封存工作。有两个参数:-->
<!--
参数1:interval,integer型,指定两次封存动作之间的时间间隔。
这个配置需要和filePattern结合使用,filePattern日期格式精确到哪一位,interval也精确到哪一个单位。
注意filePattern中配置的文件重命名规则是%d{yyyy-MM-dd HH-mm-ss}-%i,最小的时间粒度是ss,即秒钟。
TimeBasedTriggeringPolicy默认的size是1,结合起来就是每1秒钟生成一个新文件。如果改成%d{yyyy-MM-dd HH},最小粒度为小时,则每一个小时生成一个文件。
参数2:modulate,boolean型,说明是否对封存时间进行调制。若modulate=true, 则封存时间将以0点为边界进行偏移计算。
例如,modulate=true,interval=4hours, 那么假设上次封存日志的时间为03:00,则下次封存日志的时间为04:00,之后的封存时间依次为08:00,12:00,16:00
-->
<!--结合filePattern属性,表示每天生成一个新文件-->
<TimeBasedTriggeringPolicy interval="1" />
<!--基于日志文件大小的触发策略。单位有:KB,MB,GB-->
<SizeBasedTriggeringPolicy size="10MB" />
<!--基于Cron表达式的触发策略,很灵活-->
<!--每12小时生成一个新文件-->
<!--<CronTriggeringPolicy schedule="0 0 */12 * * ?" />-->
</Policies>
<!--日志文件滚动策略-->
<!--默认滚动策略,常用参数max,表示保存日志文件的最大个数,默认是7,大于此值会删除旧的日志文件-->
<DefaultRolloverStrategy max="10" />
<!--DirectWriteRolloverStrategy,表示日志直接写入由文件模式表示的文件-->
</RollingFile>
<!--这个会打印出所有的warn及以下级别的信息,每次大小超过size,则这size大小的日志会自动存入按年份-月份建立的文件夹下面并进行压缩,作为存档-->
<RollingFile name="RollingFileWarn" fileName="${FILE_PATH}/warn.log" filePattern="${FILE_PATH}/${FILE_NAME}-WARN-%d{yyyy-MM-dd}_%i.log.gz">
<!--仅输出WARN级别的日志信息-->
<Filters>
<!--文件只输出level及以上级别的信息(onMatch),其它的直接拒绝(onMismatch)-->
<ThresholdFilter level="WARN" onMatch="ACCEPT" onMismatch="DENY" />
<!--文件只输出level以下级别的信息(onMatch),其它的直接拒绝(onMismatch)-->
<ThresholdFilter level="ERROR" onMatch="DENY" onMismatch="NEUTRAL" />
</Filters>
<!--输出日志的格式-->
<PatternLayout pattern="${LOG_PATTERN}" />
<!--日志文件触发策略-->
<Policies>
<TimeBasedTriggeringPolicy interval="1" />
<SizeBasedTriggeringPolicy size="10MB" />
</Policies>
<!--日志文件滚动策略-->
<!--默认滚动策略,常用参数max,表示保存日志文件的最大个数,默认是7,大于此值会删除旧的日志文件-->
<DefaultRolloverStrategy max="10" />
</RollingFile>
<!--这个会打印出所有的error及以下级别的信息,每次大小超过size,则这size大小的日志会自动存入按年份-月份建立的文件夹下面并进行压缩,作为存档-->
<RollingFile name="RollingFileError" fileName="${FILE_PATH}/error.log" filePattern="${FILE_PATH}/${FILE_NAME}-ERROR-%d{yyyy-MM-dd}_%i.log.gz">
<!--文件只输出level及以上级别的信息(onMatch),其它的直接拒绝(onMismatch)-->
<ThresholdFilter level="ERROR" onMatch="ACCEPT" onMismatch="DENY" />
<!--输出日志的格式-->
<PatternLayout pattern="${LOG_PATTERN}" />
<!--日志文件触发策略-->
<Policies>
<!--interval属性用来指定多久滚动一次,默认是1 hour-->
<TimeBasedTriggeringPolicy interval="1" />
<SizeBasedTriggeringPolicy size="10MB" />
</Policies>
<!--日志文件滚动策略-->
<!--默认滚动策略,常用参数max,表示保存日志文件的最大个数,默认是7,大于此值会删除旧的日志文件-->
<DefaultRolloverStrategy max="10" />
</RollingFile>
</Appenders>
<Loggers>
<!--Logger节点用来单独指定日志的形式,比如要为指定包下的class指定不同的日志级别等-->
<!--Logger还可以配置一个或多个AppenderRef属性-->
<!--例如,过滤掉mybatis和spring的一些无用的DEBUG信息-->
<Logger name="org.mybatis" level="INFO" additivity="false">
<AppenderRef ref="Console" />
</Logger>
<Logger name="org.springframework" level="INFO" additivity="false">
<AppenderRef ref="Console" />
</Logger>
<!--
additivity属性,它是子Logger是否继承父Logger的输出源(appender)的标志位。
具体来说,默认情况下子Logger会继承父Logger的appender,也就是说子Logger会在父Logger的appender里输出。
若是additivity设为false,则子Logger只会在自己的appender里输出,而不会在父Logger的appender里输出。
-->
<!--每个配置都必须有一个根记录器Root。如果未配置,则将使用默认根LoggerConfig,其级别为ERROR且附加了Console Appender-->
<!--根记录器和其它记录器之间的主要区别是:1)根记录器没有name属性;2)根记录器不支持additivity属性,因为它没有父级-->
<Root level="INFO">
<appender-ref ref="Console" />
<appender-ref ref="Filelog" />
<appender-ref ref="RollingFileInfo" />
<appender-ref ref="RollingFileWarn" />
<appender-ref ref="RollingFileError" />
</Root>
</Loggers>
</Configuration>
4)配置参数介绍
日志级别
如果一条日志信息的级别大于等于配置文件的级别,就会被记录下来。日志级别从高到低依次是:
- FATAL:致命错误
- ERROR:错误信息。用的也很多
- WARN:警告,有些信息不是错误信息,但也要给程序员一些提示
- INFO:输出重要的信息,使用较多
- DEBUG:调试,一般作为最低级别,TRACE 基本不用
- TRACE:追踪,就是程序推进一下,可以写个 TRACE 输出
输出源
- 输出到控制台:CONSOLE
- 输出到文件:FILE
格式
- SimpleLayout:以简单的形式显示
- HTMLLayout:以 HTML 表格显示
- PatternLayout:自定义形式显示
PatternLayout 自定义日志布局
- %d{yyyy-MM-dd HH:mm:ss, SSS}:日志生产时间,输出到毫秒的时间
- %-5level:输出日志级别,-5 表示左对齐并且固定输出 5 个字符,如果不足在右边补 0
- %c:logger 的名称(%logger)
- %t:输出当前线程名称
- %p:日志输出格式
- %m:日志内容,即 logger.info(“message”)
- %n:换行符
- %C:Java类名(%F)
- %L:行号
- %M:方法名
- %l:输出语句所在的行数, 包括类名、方法名、文件名、行数
- hostName:本地机器名
- hostAddress:本地 IP 地址
5)使用说明
package indi.demo.logging;
import org.slf4j.Logger;
import static org.slf4j.LoggerFactory.getLogger;
public class 类名 {
private static final Logger LOG = getLogger(类名.class);
public void 方法名() {
LOG.info("提示信息...");
}
}
可以通过 lombok 工具简化创建 Logger 对象。
使用 lombok 后下面的代码等效于上述的代码,这样会更方便的使用日志。
@Slf4j
public class 类名 {
// ...
public void 方法名() {
log.info("提示信息...");
}
}
唯有热爱可抵岁月漫长。我是今越,欢迎大家点赞、收藏和评论,感谢支持!