- *** 作系统:Ubuntu 20.04
- 开发工具:IntelliJ IDEA 2022.1 (Community Edition)
- JDK:17.0.1
在 https://start.spring.io/ 创建项目 test0509_2
,添加 Spring Web
依赖。
创建package controller
,并创建class HelloController
如下:
package com.example.test0509_2.controller;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.Map;
@RestController
public class HelloController {
private Logger logger = LoggerFactory.getLogger(this.getClass());
@GetMapping("/test")
public Map<String, String> test() {
logger.trace("trace");
logger.debug("debug");
logger.info("info");
logger.warn("warn");
logger.error("error");
return Map.of("key1", "value1");
}
}
运行程序,然后打开浏览器,访问 http://localhost:8080/test ,最后查看命令行,结果如下:
2022-05-10 20:19:38.506 INFO 76371 --- [nio-8080-exec-3] c.e.t.controller.HelloController : info
2022-05-10 20:19:38.507 WARN 76371 --- [nio-8080-exec-3] c.e.t.controller.HelloController : warn
2022-05-10 20:19:38.508 ERROR 76371 --- [nio-8080-exec-3] c.e.t.controller.HelloController : error
可见,默认的log级别是 INFO
。
Spring Boot默认使用 SLF4J
+ Logback
的组合:
SLF4J
:log的门面(抽象);Logback
:log的实现;
项目的依赖关系如下:
可见, spring-boot-starter
包依赖于 spring-boot-starter-logging
包,所以我们可以在Spring Boot项目里直接使用log。而 spring-boot-starter-logging
包又依赖于 logback
、 log4j
、 jul
(即Java Util Logging,JDK自带的log功能)这三个包,这是log的三种实现,Spring默认使用的是 Logback
。
要设置整个Spring Boot应用的log级别,可以给应用程序添加命令行参数,或者通过配置文件来设置。比如,添加命令行参数 --trace
(或者在 application.properties
文件中添加 trace=true
):
运行程序,可见命令行输出了很多 TRACE
和 DEBUG
的log。
同理,也可以设置成 DEBUG
级别。
注意:当启用trace或者debug模式时,Spring Boot的核心log为 TRACE
或者 DEBUG
级别,但是应用程序的log级别并不受影响。刷新浏览器页面,命令行的输出仍然是 INFO
级别的log。
测试完毕,别忘了还原设置,以免影响到下面的测试。
设置应用程序的log级别打开 application.properties
文件,添加内容如下:
logging.level.root=WARN
再次运行程序,刷新浏览器页面,可见命令行只有 WARN
和 ERROR
的log。
注意:该配置也会影响Spring Boot的核心log,Spring Boot启动时的 INFO
log都不见了。
上面设置了应用程序整体的log级别,事实上也可以设置特定包或者类的log级别,如下:
# root log level
logging.level.root=WARN
# package(包含子) log level
logging.level.=WARN
# class log level
logging.level.<class全名>=WARN
......
测试完毕,别忘了还原设置,以免影响到下面的测试。
配置log格式logging.pattern.console
logging.pattern.file
注意:只有使用Logback时才有效。
输出log到文件可通过如下配置:
logging.file.name
:文件名logging.file.path
:文件目录
注意:
- 如果只指定
path
,不指定name
,则默认文件名为spring.log
; - 如果只指定
name
,不指定path
,则在当前目录下生成log文件;
注:参见上面图片中的 Working directory
设置,当前目录是项目的根目录。
例如:
logging.file.path=.
logging.file.name=mylog.log
当使用 Logback
时,可配置如下参数:
logging.logback.rollingpolicy.max-file-size
:设置文件大小,默认为10MB;logging.logback.rollingpolicy.max-history
:设置保留天数,默认为7天;- ……
对于其它log实现,则需要修改对应的配置文件,比如 Log4j
,就需要修改 log4j.xml
/ log4j-spring.xml
文件进行配置。
运行程序,可见当前目录(即项目的根目录)里面的 mylog.log
文件生效了,同时命令行log仍然生效。
配置 logging.group
,把多个package和class放到一个group里统一设置级别,方便管理。例如:
logging.group.=xxx,xxx,......
logging.level.=trace
显式指定log实现(关闭log)
Spring Boot默认使用Logback作为log实现。可以通过系统属性 org.springframework.boot.logging.LoggingSystem
显式指定log实现。其值可以是 LoggingSystem
实现类的全名,也可以指定为 none
,关闭log。
我们来尝试关闭log。 Run
-> Edit Configurations...
,在 VM options
处,添加 -Dorg.springframework.boot.logging.LoggingSystem=none
,如下图:
注意:默认并没有显示 VM options
编辑框,需要点击 Modify options
,然后勾选 Add VM Options
。
注意: VM options
即系统属性(System Property),可以理解为JVM的环境变量,通过 -D
来设置。
运行程序,我测试的效果为:
- 文件log确实关闭了(Spring Boot核心log和应用程序log都关闭了);
- 命令行log不但没有关闭,反而级别变成了
DEBUG
(Spring Boot核心log和应用程序log都变成DEBUG
级别了);
用命令行运行 java -jar -Dorg.springframework.boot.logging.LoggingSystem=none ./target/test0509_2-0.0.1-SNAPSHOT.jar
也是同样效果。
注:为何要通过系统属性,而不能通过 application.properties
文件来配置 org.springframework.boot.logging.LoggingSystem
呢?Spring Boot的官方文档(https://docs.spring.io/spring-boot/docs/2.6.7/reference/htmlsingle/#features.logging.custom-log-configuration)如是说:
Logging在ApplicationContext创建之前就初始化了,因此无法通过Spring的 @Configuration
文件的 @PropertySources
来控制logging。改变或者关闭logging system的唯一方法是通过系统属性。
我测试过,如果清空 VM options
,同时把 org.springframework.boot.logging.LoggingSystem=none
添加到 application.properties
文件里,确实命令行log和文件log都不生效。
前面的测试都没有涉及log实现的配置文件。事实上Logback,Log4j2等log实现,也支持配置文件。Spring Boot默认从类加载路径的根路径下加载log配置文件。Spring Boot自动识别并加载的配置文件如下:
- Logback:
logback-spring.xml
、logback.xml
等 - Log4j2:
log4j2-spring.xml
、log4j2.xml
等 - JUL:
logging.properties
注:Spring Boot推荐使用带 -spring
后缀的配置文件。
可以通过 logging.config
系统属性来指定log配置文件。
比如,我们创建 logback-spring.xml
文件,内容如下:
<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>
注: :-
是Logback语法,用来作为属性名和默认值之间的分隔符。本例中 LOG_FILE
的设置,我没仔细研究其作用。看起来貌似并不影响log:如果 application.properties
里设置了 logging.file.name
,就会用指定的命名,否则就用默认值 spring.log
命名。
注意,配置文件指定了log级别为 INFO
,且只用文件log(没有命令行log)。至于Log文件的路径和命名,在 application.properties
文件中指定(参见上面的配置)。
把 logback-spring.xml
文件复制到任意目录,比如项目的根目录下。
由于该文件不在类加载路径的根路径下,我们需要显式告诉Spring Boot来加载它。指定 VM options
为 -Dlogging.config=logback-spring.xml
。运行程序,项目的根目录(即当前目录)里面的 logback-spring.xml
配置文件就会生效。该配置文件配置了log级别为 INFO
,且只用文件log。
可以看到,命令行确实没有输出了,同时项目的根目录(即当前目录)里面的 mylog.log
文件生效了。
同样的问题:能否不使用系统属性,而使用 application.properties
文件来配置呢?我测试过,如果清空 VM options
,同时把 logging.config=logback-spring.xml
添加到 application.properties
文件里,它仍然生效:命令行log没有了,同时 mylog.log
文件生效了。
具体对应关系,参见Spring官网: https://docs.spring.io/spring-boot/docs/2.6.7/reference/htmlsingle/#features.logging.custom-log-configuration
隐式指定log实现前面提到,可以通过系统属性 org.springframework.boot.logging.LoggingSystem
来显式指定log实现。如果不指定,则Spring Boot默认会根据依赖关系,自动选取log实现。
在本文开头的项目依赖关系图里,我们看到 spring-boot-starter-logging
包依赖于 logback
、 log4j
、 jul
,即log的三种实现,其中 Logback
优先级较高,所以Spring默认使用的是 Logback
。
下面我们来尝试通过改变依赖关系来指定log实现。修改 pom.xml
文件,在 spring-boot-starter
下添加 exclusion
,排除对 spring-boot-starter-logging
的依赖,同时添加对 spring-boot-starter-log4j2
的依赖,如下:
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starterartifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-loggingartifactId>
exclusion>
exclusions>
dependency>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-log4j2artifactId>
dependency>
注:添加对 spring-boot-starter-log4j2
的依赖,就会自动传递对 SLF4J
的依赖。
刷新Maven依赖关系,如下图:
可见已经没有对 Logback
的依赖了。
Maven
-> Compile
,重新编译项目,然后去掉所有logging相关的配置,只保留 application.properties
文件里的log文件配置:
logging.file.path=.
logging.file.name=mylog.log
运行程序,可见和Logback的log并没什么区别,在命令行和 mylog.log
文件都输出了 INFO
级别的log。
可以在debug模式下设置断点观察Logger:
可见这是 Log4jLogger
。
补一张之前使用 Logback
时的图:
可见这是Logback的Logger。
注意:如果使用了其它log实现,就不要再指定跟Logback相关的配置,否则会有问题。比如,在 application.properties
文件中添加如下配置:
logging.config=logback-spring.xml
运行程序,则命令行只有 ERROR
级别的log,而文件log无效了。不知道为啥,但总之,如果使用某种log实现,就不要再指定其它log实现的配置了,以免产生不必要的问题。
- https://docs.spring.io/spring-boot/docs/2.6.7/reference/htmlsingle/
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)