日志配置
规范:项目开发不要编写System.out.println(),应该用日志记录信息
1. 日志框架
其中JCL自2014年以来不再更新,比较落后,Spring一直使用JCL作为日志门面,在Spring5.0之后,JCL代码被整合到Spring中,并做了改造,对其他日志框架开发。
jboss-logging很小众用在jboss相关产品比较多,因此门面推荐使用SLF4j。
值得一提的是slf4j、log4j和logback同一人之手开发,由于当时log4j有性能问题,需要的改动有比较大,所以重新开发了新的日志实现框架logback。而jul是java内部担心以后没有与log4j相抗衡的产品急忙推出的,并不推荐,apache借鉴了log4j开发了log4j2, slf4j和logback的整合度最佳(毕竟都是大神开发的)。
2. SpringBoot的日志
SpringBoot默认使用的日志框架就是slf4j+logback。并且SpringBoot3不再支持日志实现使用log4j,log4j发展到现在比较陈旧。 SpringBoot日志配置底层:
SpringBoot的核心starter依赖spring-boot-starter-logging
,因此每一个starter引入都会有spring-boot-starter-logging
, 不像其他starter在spring-boot-autoconfigure
包对应的文件夹下都有xxxAutoConfiguration
, 因为日志不同其他组件是系统一启动就要被使用的。它利用监听器机制,用ApplicationListener监听应用启动。
2. 日志格式
默认日志输出:
2023-03-31T13:56:17.511+08:00 INFO 4944 --- [ main] o.apache.catalina.core.StandardService : Starting service [Tomcat]
2023-03-31T13:56:17.511+08:00 INFO 4944 --- [ main] o.apache.catalina.core.StandardEngine : Starting Servlet engine: [Apache Tomcat/10.1.7]
默认输出格式:
- 时间和日期:毫秒级精度
- 日志级别:ERROR, WARN, INFO, DEBUG, TRACE
- 进程 ID
- ---:消息分割符
- 线程名:使用[]包含
- Logger名:通常是产生日志的类名
- 消息:日志记录的内容
注意:logback没有FATAL级别,对应的是ERROR
默认格式配置:spring-boot包additional-spring-configuration-metadata.json文件。
默认输出格式值:%clr(%d{${LOG_DATEFORMAT_PATTERN:-yyyy-MM-dd'T'HH:mm:ss.SSSXXX}}){faint} %clr(${LOG_LEVEL_PATTERN:-%5p}) %clr(${PID:- }){magenta} %clr(---){faint} %clr([%15.15t]){faint} %clr(%-40.40logger{39}){cyan} %clr(:){faint} %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}
可以按照默认格式做微调:
## 替换LOG_DATEFORMAT_PATTERN变量
logging:
pattern:
dateformat: yyyy-MM-dd HH:mm:ss
3. 记录日志
Logger logger = LoggerFactory.getLogger(getClass());
或者使用Lombok的@Slf4j注解
4. 日志级别
由低到高:ALL,TRACE, DEBUG, INFO, WARN, ERROR,FATAL,OFF; 日志框架只会打印指定级别及以上级别的日志
- ALL:打印所有日志
- TRACE:追踪框架详细流程日志,一般不使用
- DEBUG:开发调试细节日志
- INFO:关键、感兴趣信息日志
- WARN:警告但不是错误的信息日志,比如:版本过时
- ERROR:业务错误日志,比如出现各种异常
- FATAL:致命错误日志,比如jvm系统崩溃
- OFF:关闭所有日志记录
SpringBoot中不指定级别的所有类,都使用root指定的级别作为默认级别, 而root的默认日志级别为INFO。
- 配置全局日志级别:
在application.properties/yaml中配置logging.level.root=<level>
指定日志级别,level可取值范围:TRACE, DEBUG, INFO, WARN, ERROR或OFF - 配置局部包或者类日志级别: 使用
logging.level.包名=<level>
指定日志级别
比如:
logging:
level:
## 指定org.example.web的日志级别,可以精确到类的日志级别
org.example.web: debug
## 指定全局的日志级别,默认是info
root: warn
pattern:
dateformat: yyyy-MM-dd HH:mm:ss
@Controller
@Slf4j
public class UserController {
@RequestMapping("/hello")
@ResponseBody
public String hello(){
log.trace("hello, {}", "trace");
log.debug("hello, {}", "debug");
log.info("hello, {}", "info");
log.warn("hello, {}", "warn");
log.error("hello, {}", "error");
return "请求hello成功";
}
}
Connected to the target VM, address: '127.0.0.1:9693', transport: 'socket'
. ____ _ __ _ _
/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
\\/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot :: (v2.7.18)
2024-03-21 06:21:53 DEBUG 13548 --- [nio-8080-exec-1] org.example.web.UserController : hello, debug
2024-03-21 06:21:53 INFO 13548 --- [nio-8080-exec-1] org.example.web.UserController : hello, info
2024-03-21 06:21:53 WARN 13548 --- [nio-8080-exec-1] org.example.web.UserController : hello, warn
2024-03-21 06:21:53 ERROR 13548 --- [nio-8080-exec-1] org.example.web.UserController : hello, error
5. 日志分组
将相关的logger分组在一起,方便统一配置。
SpringBoot 预定义两个组:
日志组名 | loggers |
---|---|
web | org.springframework.core.codec, org.springframework.http, org.springframework.web, org.springframework.boot.actuate.endpoint.web, org.springframework.boot.web.servlet.ServletContextInitializerBeans |
sql | org.springframework.jdbc.core, org.hibernate.SQL, org.jooq.tools.LoggerListener |
6. 日志文件输出
SpringBoot 默认只把日志写在控制台,如果想额外记录到文件,可以在application.properties中添加logging.file.name
或者logging.file.path
配置项。
logging.file.name | logging.file.path | 示例 | 效果 |
---|---|---|---|
未指定 | 未指定 | 仅控制台输出 | |
指定 | 未指定 | my.log | 写入指定文件。可以加路径 |
未指定 | 指定 | /var/log | 写入指定目录,文件名为spring.log |
指定 | 指定 | 以logging.file.name 为准 | |
推荐使用logging.file.name 配置项,既可以指定文件路径也可以指定文件名, |
7. 日志文件归档与滚动切割
需求:
归档:每天的日志单独存到一个文档中。
切割:每个文件10MB,超过大小切割成另外一个文件。
每天的日志应该独立分割出来存档。如果使用logback(SpringBoot 默认整合),可以通过application.properties/yaml文件指定日志滚动规则。 支持的滚动规则设置如下:
配置项 | 描述 |
---|---|
logging.logback.rollingpolicy.file-name-pattern | 日志存档的文件名格式(默认值:${LOG_FILE}.%d{yyyy-MM-dd}.%i.gz) |
logging.logback.rollingpolicy.clean-history-on-start | 应用启动时是否清除以前存档(默认值:false) |
logging.logback.rollingpolicy.max-file-size | 存档前,每个日志文件的最大大小(默认值:10MB) |
logging.logback.rollingpolicy.total-size-cap | 日志文件被删除之前,可以容纳的最大大小(默认值:0B)。设置1GB则磁盘存储超过 1GB 日志后就会删除旧日志文件 |
logging.logback.rollingpolicy.max-history | 日志文件保存的最大天数(默认值:7). |
8. 自定义日志配置
通常我们配置 application.properties/yml就够了。当然也可以自定义。比如:
日志系统 | 自定义文件名 |
---|---|
Logback | logback-spring.xml, logback-spring.groovy, logback.xml, or logback.groovy |
Log4j2 | log4j2-spring.xml or log4j2.xml |
JDK (Java Util Logging) | logging.properties |
建议您在日志配置文件名中使用-spring 变量(例如,logback-spring.xml而不是logback.xml)。如果您使用标准配置文件,spring无法完全控制日志初始化. |