Java 日志重点梳理

news2025/1/13 13:49:15

大家好!我是今越。重点梳理一下在 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("提示信息...");
    }
}

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/693716.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

LangChain-Agent自定义Tools类 ——输入参数篇(二)

给自定义函数传入输入参数&#xff0c;分别有single-input 参数函数案例和multi-input 参数函数案例&#xff1a; from langchain.agents import Tool from langchain.tools import BaseTool from math import pi from typing import Union from math import pi from typing …

StringBuffer和正则表达式

StringBuffe 获取int类型的最大值和最小值 System.out.println(Integer.MAX_VALUE);//int类型的最大值 System.out.println(Integer.MIN_VALUE);//int类型的最小值输出结果 Integer和String相互转换 Integer i1 new Integer(100); System.out.println(i1);Integer i2 new…

08 | 事务到底是隔离的还是不隔离的?

以下内容出自《MySQL 实战 45 讲》 08 | 事务到底是隔离的还是不隔离的&#xff1f; 事务启动时机 事务启动时机&#xff1a; begin/start transaction 命令并不是一个事务的起点&#xff0c;在执行到它们之后的第一个操作 InnoDB 表的语句&#xff0c;事务才真正启动。如果想…

Gradio的Button组件介绍

❤️觉得内容不错的话&#xff0c;欢迎点赞收藏加关注&#x1f60a;&#x1f60a;&#x1f60a;&#xff0c;后续会继续输入更多优质内容❤️ &#x1f449;有问题欢迎大家加关注私戳或者评论&#xff08;包括但不限于NLP算法相关&#xff0c;linux学习相关&#xff0c;读研读博…

从0到1精通自动化测试,pytest自动化测试框架,配置文件pytest.ini(十三)

一、前言 pytest配置文件可以改变pytest的运行方式&#xff0c;它是一个固定的文件pytest.ini文件&#xff0c;读取配置信息&#xff0c;按指定的方式去运行 二、ini配置文件 pytest里面有些文件是非test文件pytest.ini pytest的主配置文件&#xff0c;可以改变pytest的默认…

SpringBoot多环境启动

文章目录 多环境启动多环境启动基本格式多环境启动命令格式多环境启动的兼容性 多环境启动 多环境启动基本格式 我们在开发中和上线后的环境中, 有些配置文件的值是不相同的, 但是当项目上线后我们肯定是不能修改配置文件的, 于是我们需要针对不同的环境进行不同的配置 例如下…

【C语言之区分sizeof 和 strlen】

C语言之区分sizeof 和 strlen 详解C语言sizeof 和 strlen1、单目操作符1.1、详解sizeof单目操作符1.2、sizeof代码部分1.2.1、sizeof例程11.2.2、sizeof例程21.2.3、sizeof例程3 2、详解strlen函数2.1、strlen代码部分2.1.1、strlen例程1 3、区别strlen函数和sizeof操作符3.1、…

数据库—属性闭包

属性闭包 要理解属性闭包先理解以下概念 U属性集合&#xff0c;比如一个表A有这些属性**{a,b,c,d,e}**F函数依赖集 这个就是由已知的一些函数依赖组成的集合&#xff0c;比如&#xff1a; F {a->b,b->c,c->d,ab->e} //F函数依赖集R(U&#xff0c;F)表示一个关系模…

linux工程管理工具make

linux工程管理工具make 一、make 工具的功能二、makefile 文件三、makefile 的规则Makefile 介绍一、Makefile 的规则二、一个示例三、其他例子makefiletest.cprocess.cprocess.h截图 一、make 工具的功能 1、主要负责一个软件工程中多个源代码的自动编译工作 2、还能进行环境…

Spring boot装载模板代码工程实践问题之二

Spring boot装载模板代码工程实践问题解决方案 替代方案解决方案及解释 Spring boot装载模板代码工程中&#xff0c;后续有自定注解的要求&#xff0c;在本地运行无恙&#xff0c;打成jar启动后&#xff0c;自定义注解会无效。 替代方案 在测试compiler.getTask多种参数后&…

7.MMM

文章目录 MMM概念配置mysql配置文件主主复制主从服务器配置--只需要配置一个主服务器的安装mysql-MMM 测试故障测试客户端测试 MMM 概念 MMM&#xff08;Master-Master replication manager for MvSQL&#xff0c;MySQL主主复制管理器&#xff09; 是一套支持双主故障切换和双…

git merge和git rebase的区别

本文来说下git merge和git rebase的区别 文章目录 分支合并解决冲突git rebase和git merge的区别本文小结 分支合并 git merge是用来合并两个分支的。比如&#xff1a;将 b 分支合并到当前分支。同样git rebase b&#xff0c;也是把 b 分支合并到当前分支。他们的 「原理」如下…

并发-操作系统底层工作的整体认识

冯诺依曼计算机模型 五大模块&#xff1a;输入、输出、计算器【cpu】、存储器【内存】、控制器 现在计算机硬件结构设计 CPU&#xff1a;控制、运算、数据

工业机器人运动学与Matlab正逆解算法学习笔记(用心总结一文全会)(三)

文章目录 机器人逆运动学△ 代数解求 θ 4 \theta_4 θ4​、 θ 5 \theta_5 θ5​、 θ 6 \theta_6 θ6​○ 求解 θ 4 \theta_4 θ4​○ 求解 θ 5 \theta_5 θ5​○ 求解 θ 6 \theta_6 θ6​ CSDN提示我字数太多&#xff0c;一篇发不下&#xff0c;只好拆分开x2。。。 关于…

shiro-all由1.3.2 升级到1.11.0后出现重定向次数过多的问题:ERR_TOO_MANY_REDIRECTS

最近漏洞升级, shiro-all由1.3.2 升级到1.11.0后, 导致系统登录首页打不开, 一直提示重定向次数过多: ERR_TOO_MANY_REDIRECTS: 经定位: 是shiroFilter配置中: loginUrl配置问题 以一下例子具体说明参数含义&#xff1a; 1&#xff0c;假设网站的网址是http://localhost…

基于STM32F407的智慧农业系统

文章目录 一、设备平台二、功能说明三、硬件系统设计实现与图表四、软件系统设计实现与流程图五、调试过程中出现的问题及相应解决办法六、程序设计1. 开始任务函数2. LED任务函数3. KEY任务函数4. UART任务函数5. OLED任务函数6. DHT11任务函数7. BEEP任务函数8. ADC任务函数9…

写一个简单的静态html页面demo,包含幻灯片

效果图&#xff1a; 代码如下&#xff0c;图片文件可自行更换&#xff1a; <!DOCTYPE html> <html> <head><title>公司网站</title><style>/* 样式定义 */body {font-family: Arial, sans-serif;margin: 0;padding: 0;}header {backgrou…

什么是Session

1、web中什么是会话 &#xff1f; 用户开一个浏览器&#xff0c;点击多个超链接&#xff0c;访问服务器多个web资源&#xff0c;然后关闭浏览器&#xff0c;整个过程称之为一个会话。 2、什么是Session &#xff1f; Session:在计算机中&#xff0c;尤其是在网络应用中&…

Linux学习之进程概念和ps命令

进程概念和启动关闭进程 进程就是运行中的程序 在C语言中进程只能只能从main()函数开始运行。 进程终止的方式有两种&#xff1a; 正常终止&#xff1a;从main()函数返回、调用exit()等方式 异常终止&#xff1a;调用abort、接收信号等。有可能 ps ps是“process status”的缩…

华为OD机试真题 Python 实现【光伏场地建设规划】【2023Q1 100分】

一、题目描述 祖国西北部有一片大片荒地&#xff0c;其中零星的分布着一些湖泊&#xff0c;保护区&#xff0c;矿区&#xff1b;整体上常年光照良好&#xff0c;但是也有一些地区光照不太好。某电力公司希望在这里建设多个光伏电站&#xff0c;生产清洁能源。对每平方公里的土…