Java 日志重点梳理

大家好!我是今越。重点梳理一下在 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性能评测

关于 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("提示信息...");
    }
}

唯有热爱可抵岁月漫长。我是今越,欢迎大家点赞、收藏和评论,感谢支持!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值