Skip to content

日志配置

规范:项目开发不要编写System.out.println(),应该用日志记录信息

1. 日志框架

Alt text 其中JCL自2014年以来不再更新,比较落后,Spring一直使用JCL作为日志门面,在Spring5.0之后,JCL代码被整合到Spring中,并做了改造,对其他日志框架开发。 Alt text 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监听应用启动。 Alt text

2. 日志格式

默认日志输出:

shell
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}
    可以按照默认格式做微调:
yml
## 替换LOG_DATEFORMAT_PATTERN变量
logging:
  pattern:
    dateformat: yyyy-MM-dd HH:mm:ss

3. 记录日志

java
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
  1. 配置全局日志级别:
    在application.properties/yaml中配置logging.level.root=<level>指定日志级别,level可取值范围:TRACE, DEBUG, INFO, WARN, ERROR或OFF
  2. 配置局部包或者类日志级别: 使用logging.level.包名=<level>指定日志级别
    比如:
yml
logging:
  level:
    ## 指定org.example.web的日志级别,可以精确到类的日志级别
    org.example.web: debug
    ## 指定全局的日志级别,默认是info
    root: warn
  pattern:
    dateformat: yyyy-MM-dd HH:mm:ss
java
@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成功";
    }
}
sh
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
weborg.springframework.core.codec, org.springframework.http, org.springframework.web, org.springframework.boot.actuate.endpoint.web, org.springframework.boot.web.servlet.ServletContextInitializerBeans
sqlorg.springframework.jdbc.core, org.hibernate.SQL, org.jooq.tools.LoggerListener

6. 日志文件输出

SpringBoot 默认只把日志写在控制台,如果想额外记录到文件,可以在application.properties中添加logging.file.name或者logging.file.path配置项。

logging.file.namelogging.file.path示例效果
未指定未指定仅控制台输出
指定未指定my.log写入指定文件。可以加路径
未指定指定/var/log写入指定目录,文件名为spring.log
指定指定logging.file.name为准
推荐使用logging.file.name配置项,既可以指定文件路径也可以指定文件名,

7. 日志文件归档与滚动切割

需求:

  1. 归档:每天的日志单独存到一个文档中。

  2. 切割:每个文件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就够了。当然也可以自定义。比如:

日志系统自定义文件名
Logbacklogback-spring.xml, logback-spring.groovy, logback.xml, or logback.groovy
Log4j2log4j2-spring.xml or log4j2.xml
JDK (Java Util Logging)logging.properties
建议您在日志配置文件名中使用-spring变量(例如,logback-spring.xml而不是logback.xml)。如果您使用标准配置文件,spring无法完全控制日志初始化.