JDK 8
spring boot 2.4.5
---
S.B. 使用 Apache Commons Logging 记录日志,但开放了 底层具体日志记录实现,默认的实现提供了 Java Util Logging、Log4j2、Logback。
日志记录 预先配置为 1)输出到控制台(Console),但可以选择2)输出到文件。
使用各种 starters 包时,默认使用 Logback记录日志;有些独立的包不使用Logback时,可以通过 Logback路由(Routing) 使之正确输出日志。
默认日志格式
输出的日志(下面是 一行):
2021-08-14 09:30:23.355 [main] INFO org.springframework.boot.web.embedded.tomcat.TomcatWebServer-Tomcat
started on port(s): 8081 (http) with context path ''
分别是:时间、线程名、级别、完整类名、记录的信息,,各段使用 空格 分隔开。
日志级别:ERROR, WARN, INFO, DEBUG, TRACE,,严重性 从高到低(↓)。
改变默认格式:logging.pattern.*
试验配置
# 在 application.properties 配置
logging.pattern.console=IN console %d{yyyy-MM-dd HH:mm:ss.SSS} ${PID} [%thread] [%+5level] L%+5L %logger{100} M:%msg%n
效果:
调试用
默认只输出 INFO及以上级别 的日志,
命令行添加 --debug 可以输出 DEBUG及以上日志,更详细,如名所言,调试时可以使用,
还可以使用 --trace 输出 TRACE及以上 日志,包含内容非常多,,一定是非常特殊的时候才使用(看更具体细节时)。
以上 两个命令行配置 可以分别使用配置 debug=true、trace=true 替代。
注:实测发现 输出TRACE级别+ 日志时,配置在 命令行 和 配置文件中的效果不一致——输入内容或有差别(不再详细区分了)。
输出到文件(简单配置版本)
添加配置 logging.file.name 或 logging.file.path。
测试:Windows 10,,新建立 D:logging 文件夹,配置 logging.file.path=d:\logging。
结果:没有看到日志文件生产。
原因:盘符下顶级目录不可以处理(疑问,TODO)?
进一步:在 d:\logging 下建立 prj1 文件夹,再配置 logging.file.path=d:\logging\prj1。
此时启动prj1项目,启动后,可以看到 新配置的目录下的配置文件了——spring.log:
成功。
进一步:再配置 logging.file.name,启动项目。
结果:d:\logging\prj1 中 附加(append)了新的项目日志,,而my.log没有出现在这里!
那么,在哪里呢?项目根目录下(启动项目 的当前目录,Eclipse启动,则是在 项目根目录中)。
按照 官文 的说明,这两个文件 配置一个即可。
再进一步:
不想my.log出现在 项目根目录下的话,如下配置即可实现:
# 根目录下新建一个 logging 目录来存放 my.log
logging.file.name=logging/my.log
# 存到了 D:logging 目录下了,,这样的话,就可以取代了 logging.file.path 的作用
logging.file.name=d:/logging/my.log
# 注意 单斜杠 和 双反斜杠 的使用,Windows下测试是 都支持的。
上面两个肯定不够 生产使用 啊!生产还需要 更定制化的日志,比如,日志文件名动态变化、每天一个日志文件、不同级别日志输出到不同文件等。
日志归档
日志超过一定大小后,就压缩保存,压缩文件名称可以配置。
不同的日志实现组件 会有不同的、灵活的配置,比如,使用Logback的话(默认使用它),可以在 日志文件中使用下面的配置来实现 更复杂的 日志输出需求。
# 文件名格式
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
试验配置 logging.logback.rollingpolicy.file-name-pattern=${spring.application.name}.%d{yyyy-MM-dd}.%i.gz,但没有看到 任何 gz文件。
原来,上面的配置是用来归档使用的,日志超过某个限制了,就建立 gz 文件,而不是 log文本文件。
再添加下面的配置 logging.logback.rollingpolicy.max-file-size=100KB 就可以看到 各个gz文件了(开启输出 trace日志),这个配置默认 10MB。
gz文件出现在 项目根目录下:
注意,这个大小是 压缩后的,配置的max-file-size 是指 压缩前的log文件大小。
配置中修改日志记录器的日志级别
单个修改:
logging.level.<logger-name>=<level>
<logger-name> 可以简单理解为 包名,配置后,改包下,低于这个<level>的日志不再输出。
项目启动后,可以通过 Spring Environment对象 查询。
可以调高,可以降低。
日志分组:logging.group
上面是一个一个地修改,使用 日志分组功能,可以一组一组地修改。
# 官文示例
logging.group.tomcat=org.apache.catalina,org.apache.coyote,org.apache.tomcat
先配置 分组,再统一设置 分组中 日志记录器 的级别。
S.B. 默认有 web、sql 两个日志分组。
配置 logging.level.web=warn 后,启动时看到更少日志了。
疑问:既然配置可以修改,是否可以动态修改呢?使用actuator。
日志关机钩子
logging.register-shutdown-hook=true
配置后,关闭项目时,只有一条日志输出,默认情况下,会有两条日志输出。
更多区别 说不上来了。
还有什么用呢?
定制文件配置(Logback)
使用 org.springframework.boot.logging.LoggingSystem 来选择不同的 日志实现系统,或者 关闭(none,输出了好多日志)。
这里介绍默认的 Logback 的定制文件配置。可用文件名:
logback-spring.xml // 自己使用过,也是官方推荐
logback-spring.groovy
logback.xml
logback.groovy
建好文件,放到 classpath下即可——/src/main/resources。
日志配置文件中 可以使用一些 系统属性(System Properties),以下是从 Spring Environment对象 中传来的值(官文 截图):
如果是 Logback,还有下面的:
logback-spring.xml 配置技巧:
1、输出进出ID
${PID}
2、输出行号
%L
注:检查了一些 系统包的行号,不准确;自己的包下 还是能很好地定位的。
3、使用配置中的属性
配置文件配置 logging.file.name=${spring.application.name},会被转换为 LOG_FILE,
logback-spring.xml 中使用 ${LOG_FILE}。
搞定。记得之前看过另外的方法的。
4、%号后的 +、- 、数字 用于对齐
+ 右对齐,
- 左对齐。
下面是我自己的一份配置:
logback-spring.xml
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<property name="logDir" value="d:/data/spring" />
<property name="maxHistory" value="30" />
<!-- 控制台输出日志 -->
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} ${PID} [%thread] [%+5level] L%+5L %logger{100} M:%msg%n</pattern>
<charset class="java.nio.charset.Charset">UTF-8</charset>
</encoder>
</appender>
<!--文件日志, 按照每天生成日志文件 -->
<appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!--日志文件输出的文件名-->
<FileNamePattern>${logDir}/${LOG_FILE}.%d{yyyy-MM-dd}.log</FileNamePattern>
<!--日志文件保留天数-->
<MaxHistory>30</MaxHistory>
</rollingPolicy>
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度%msg:日志消息,%n是换行符-->
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} ${PID} [%thread] [%+5level] L%+5L %logger{100} M:%msg%n</pattern>
</encoder>
<!--日志文件最大的大小
<triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
<MaxFileSize>10MB</MaxFileSize>
</triggeringPolicy>-->
</appender>
<root level="INFO">
<appender-ref ref="STDOUT" />
<appender-ref ref="FILE" />
</root>
</configuration>
更多 Logback 的日志配置,请参考其它文档,会更专业。
S.B.的Logback扩展项
特定Profile配置: <springProfile>标签
官文示例如下
<springProfile name="staging">
<!-- configuration to be enabled when the "staging" profile is active -->
</springProfile>
<springProfile name="dev | staging">
<!-- configuration to be enabled when the "dev" or "staging" profiles are active
-->
</springProfile>
<springProfile name="!production">
<!-- configuration to be enabled when the "production" profile is not active -->
</springProfile>
环境变量的使用: <springProperty>标签
前面提到 logback-spring.xml 中使用 spring.application.name,用了特别的方式来处理。
而这里使用 <springProperty>标签 即可搞定。
# 添加
<springProperty scope="context" name="appName" source="spring.application.name" defaultValue="localhost" />
# 使用 替换前面的 ${LOG_FILE}
${appName}
疑问:
1)S.B. 默认使用Logback,对于其它 使用 非Logback 的 包,其日志输出 有什么问题?
2)日志配置生效时机:ApplicationContext 准备好之后吗?那么,之前的日志输出怎么弄的?
3)slf4j是什么?使用 lombok 时,会用到它的一个 lombok.extern.slf4j.Slf4j,直接就可以使用 log对象 记录日志了。
---全文完---
其实自己对 日志系统 其实是一知半解的,就知道这么用了能输出日志,输出到文件,知道配置格式。
所以,本文主要参考官文编写,过程中自己又做一些试验,尽量保证准确性。
继续前进方向:
1)Logback配置、2)日志怎么搞到ELK、3)日志怎么搞到Kafka做分析 等。
S.B.版本 2.4.5 的 4.4. Logging。
2、Spring Boot 日志各种使用姿势,是时候捋清楚了!
5、