Spring-Log
Spring Logging 笔记
Spring Boot Logging
Spring Boot Logging
https://docs.spring.io/spring-boot/docs/current/reference/html/features.html#features.logging
使用 Spring Boot 的 Starters 时,默认使用 Logback 日志框架。
默认控制台日志
即便不加任何日志配置,Spring Boot 也会有默认的控制台日志 Appender CONSOLE
输出,但没有日志文件输出。
默认的控制台日志配置在 spring-boot-3.1.6.jar 包中 org/springframework/boot/logging/logback/console-appender.xml
,内容:
<included>
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
<level>${CONSOLE_LOG_THRESHOLD}</level>
</filter>
<encoder>
<pattern>${CONSOLE_LOG_PATTERN}</pattern>
<charset>${CONSOLE_LOG_CHARSET}</charset>
</encoder>
</appender>
</included>
如果不想再写一个控制台 appender,可以直接 include 引入 Spring Boot 自带的这个默认 CONSOLE appender 配置:
<configuration debug="true">
<include resource="org/springframework/boot/logging/logback/console-appender.xml"/>
<root>
<appender-ref ref="CONSOLE"/>
</root>
</configuration>
默认控制台日志格式:
2023-11-23T13:39:52.622Z INFO 35705 --- [myapp] [ main] o.s.b.d.f.logexample.MyApplication : Starting MyApplication using Java 17.0.9 with PID 35705 (/opt/apps/myapp.jar started by myuser in /opt/apps/)
2023-11-23T13:39:52.628Z INFO 35705 --- [myapp] [ main] o.s.b.d.f.logexample.MyApplication : No active profile set, falling back to 1 default profile: "default"
2023-11-23T13:39:53.900Z INFO 35705 --- [myapp] [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat initialized with port 8080 (http)
2023-11-23T13:39:53.923Z INFO 35705 --- [myapp] [ main] o.apache.catalina.core.StandardService : Starting service [Tomcat]
在 application.yml 中配置日志级别
从 Spring Boot v1.2.0.RELEASE 开始可以在 application.yml/properties 中配置日志级别,这些配置项是独立于任何日志框架实现的
通过 logging.level.<logger-name>=<level>
配置具体类包的日志级别,level 是 TRACE, DEBUG, INFO, WARN, ERROR, FATAL, OFF
之一
logging:
level:
root: INFO
feign.Logger: DEBUG
file:
path: /root/logs/myapp
Spring Boot: How can I set the logging level with application.properties?
https://stackoverflow.com/questions/20485059/spring-boot-how-can-i-set-the-logging-level-with-application-properties
定制日志配置
使用不同的日志框架时,Spring Boot 自动加载的日志配置:
- 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 Boot 建议使用带 -spring 的日志配置文件,例如 logback-spring.xml
代替 logback.xml
,方便应用 Spring Boot 定制的日志扩展
application.yml 中的日志配置参数
SpringBoot application.properties 或 application.yml 中可配置日志相关配置项,这些配置项是独立于任何日志框架实现的
在 application.yml/properties 配置后,可在 logback-spring.xml 中直接使用对应的变量,常用配置对应关系如下:
Spring Boot 2.x 和 3.x 中都有的配置:${LOG_FILE}
对应 SpringBoot 中配置项 logging.file.name
日志文件${LOG_PATH}
对应 SpringBoot 中配置项 logging.file.path
日志目录${FILE_LOG_PATTERN}
对应 SpringBoot 中配置项 logging.pattern.file
文件类型的 appender 中使用的日志输出格式
Spring Boot 2.x 中有的配置,3.x 中删除了:${ROLLING_FILE_NAME_PATTERN}
对应 SpringBoot 中配置项 logging.pattern.rolling-file-name
Spring Boot 3.x 中新增的配置,2.x 中没有:${LOG_EXCEPTION_CONVERSION_WORD}
对应 SpringBoot 中配置项 logging.exception-conversion-word
完整的配置在对应 Spring Boot 版本的源码 org.springframework.boot.logging.LoggingSystemProperties 文件中
Spring Boot 2.x 中的可用日志配置参数:
https://docs.spring.io/spring-boot/docs/2.2.0.RELEASE/api/org/springframework/boot/logging/LoggingSystemProperties.html
全部参数见 4.8. Custom Log Configuration
https://docs.spring.io/spring-boot/docs/current/reference/html/features.html#features.logging.custom-log-configuration
Spring-Logging 配置 logback
https://docs.spring.io/spring-boot/docs/current/reference/html/howto.html#howto.logging.logback
logback.xml 和 logback-spring.xml 区别
logback.xml 是 logback 标准配置文件,加载的时机较早,在其中无法使用 spring 定制化配置。
logback-spring.xml 是 Spring Boot 扩展后的 logback 配置,在其中可使用 Spring 定制化配置。
SpringBoot Logback 扩展
https://docs.spring.io/spring-boot/docs/current/reference/html/features.html#features.logging.logback-extensions
产生 LOG_PATH_IS_UNDEFINED 目录问题
原因:
logback 先于 Spring 初始化,导致初始化时找不到 spring 的 ${LOG_PATH}
变量,logback 不支持懒加载。
解决:
使用 logback-spring.xml 文件
Spring Boot + Logback 配置最佳实践
说明:
1、日志目录配置:
local 和 prod 环境日志目录不同,在 application.yml 中使用 logging.file.path
分 profile 配置,本地启动时使用 logs 相对目录,prod 环境容器启动时使用容器内的固定目录,避免出现 prod 环境的目录本地不存在,本地启动报错的问题。
logback-spring.xml 中使用 ${LOG_PATH}
变量配置日志路径,读取 application.yml/properties 中的 logging.file.path
配置项。
2、日志文件名配置:
local 和 prod 环境的日志文件名是相同的,不需要根据环境改变配置,在 application.yml 中配置默认 logging.file.name
为 ${spring.application.name}
,不管哪个服务都适用。
logback-spring.xml 中使用 ${LOG_PATH}/${LOG_FILE}
拼接在一起作为日志文件名,重新定义了一个变量 LOG_PATH_FILE <property name="LOG_PATH_FILE" value="${LOG_PATH}/${LOG_FILE}"/>
,用于当前日志/错误文件和滚动日志/错误文件。
建议 logging.file.name
不带 .log 扩展名,当前日志/错误文件和滚动日志/错误文件都可以用。
3、日志级别配置:<root>
中不需要再配置 level 属性,完全由 application.yml/properties 中的 logging.level.root
来配置日志级别即可
配置示例:
1、application.yml
spring:
profiles:
active: local
application:
name: blog
logging:
file:
name: ${spring.application.name}
level:
root: info
---
spring:
config:
activate:
on-profile: local
logging:
file:
path: logs
---
spring:
config:
activate:
on-profile: prod
logging:
file:
path: /root/logs/${spring.application.name}
2、logback-spring.xml
<?xml version="1.0" encoding="UTF-8"?>
<configuration debug="true">
<include resource="org/springframework/boot/logging/logback/defaults.xml"/>
<!-- 完整日志文件名,读取 application.yml/properties 中的 logging.file.path 和 logging.file.name 配置项拼接在一起 -->
<property name="LOG_PATH_FILE" value="${LOG_PATH}/${LOG_FILE}"/>
<property name="PATTERN" value="%d{yyyy-MM-dd HH:mm:ss.SSS} %green([%thread]) %highlight(%-5level) %cyan(%logger).%M:%L - %msg%n" />
<!-- 控制台输出,命名为 STDOUT 而不是 CONSOLE 是为了避免和 Spring Boot 自带的 org/springframework/boot/logging/logback/console-appender.xml 中的 CONSOLE appender 重名-->
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
<level>${logging.level}</level>
</filter>
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<pattern>${pattern}</pattern>
</encoder>
</appender>
<!-- 日志文件-->
<appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<encoder>
<pattern>${PATTERN}</pattern>
</encoder>
<file>${LOG_PATH_FILE}.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<cleanHistoryOnStart>${LOGBACK_ROLLINGPOLICY_CLEAN_HISTORY_ON_START:-false}</cleanHistoryOnStart>
<fileNamePattern>${LOGBACK_ROLLINGPOLICY_FILE_NAME_PATTERN:-${LOG_PATH_FILE}.%d{yyyy-MM-dd}.%i.log}</fileNamePattern>
<maxFileSize>${LOGBACK_ROLLINGPOLICY_MAX_FILE_SIZE:-100MB}</maxFileSize>
<maxHistory>${LOGBACK_ROLLINGPOLICY_MAX_HISTORY:-30}</maxHistory>
<totalSizeCap>${LOGBACK_ROLLINGPOLICY_TOTAL_SIZE_CAP:-2GB}</totalSizeCap>
</rollingPolicy>
</appender>
<!-- 仅 error 日志文件-->
<appender name="FILE-ERROR" class="ch.qos.logback.core.rolling.RollingFileAppender">
<encoder>
<pattern>${PATTERN}</pattern>
</encoder>
<file>${LOG_PATH_FILE}-error.log</file>
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
<level>error</level>
</filter>
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<cleanHistoryOnStart>${LOGBACK_ROLLINGPOLICY_CLEAN_HISTORY_ON_START:-false}</cleanHistoryOnStart>
<fileNamePattern>${LOGBACK_ROLLINGPOLICY_FILE_NAME_PATTERN:-${LOG_PATH_FILE}-error.%d{yyyy-MM-dd}.%i.log}</fileNamePattern>
<maxFileSize>${LOGBACK_ROLLINGPOLICY_MAX_FILE_SIZE:-100MB}</maxFileSize>
<maxHistory>${LOGBACK_ROLLINGPOLICY_MAX_HISTORY:-30}</maxHistory>
<totalSizeCap>${LOGBACK_ROLLINGPOLICY_TOTAL_SIZE_CAP:-2GB}</totalSizeCap>
</rollingPolicy>
</appender>
<!-- root 中不需要再配置 level 属性,完全由 application.yml/properties 中的 logging.level.root 来配置日志级别即可 -->
<root>
<appender-ref ref="STDOUT"/>
<appender-ref ref="FILE"/>
<appender-ref ref="FILE-ERROR"/>
</root>
</configuration>
SpringBoot 改用 Log4j2 日志
spring boot 支持的日志框架有,logback,Log4j2,Log4j 和 Java Util Logging
Spring Boot 默认使用 Logback 日志框架
添加maven依赖
编辑pom.xml文件,排除logback的依赖包,添加log4j2的依赖包,如果要使用异步日志还需要添加 disruptor 依赖
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
<exclusions>
<!-- 排除logback -->
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
<!-- log4j2 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-log4j2</artifactId>
</dependency>
<!-- log4j2 异步支持 -->
<dependency>
<groupId>com.lmax</groupId>
<artifactId>disruptor</artifactId>
</dependency>
</dependencies>
注意要从 spring-boot-starter
依赖中排除 spring-boot-starter-logging
, 只从 spring-boot-starter-web
中排除是不行的。
日志配置log4j2.xml
在资源文件夹 src/main/resources
下添加 log4j2.xml
或者 log4j2-spring.xml
,启动后spring boot会自动识别并加载,此外,Spring Boot 还会识别 log4j2.json
和 log4j2.yaml
<?xml version="1.0" encoding="UTF-8"?>
<!-- configuration
status用于设置log4j2自身内部的信息输出,可以不设置,当设置成trace时,你会看到log4j2内部各种详细输出。可以设置成OFF(关闭) 或 Error(只输出错误信息)。
TRACE < DEBUG < INFO < WARN < ERROR < FATAL < OFF
monitorInterval, 30s刷新此配置
-->
<configuration status="WARN" monitorInterval="30">
<properties>
<property name="PATTERN">%d{yyyy-MM-dd HH:mm:ss,SSS} [%-5level] [%thread] %c [%L]: %msg%n</property>
<Property name="LOG_DIR">/data/log/blog</Property>
</properties>
<appenders>
<Console name="Console" target="system_out">
<PatternLayout pattern="${PATTERN}"/>
</Console>
<RollingRandomAccessFile name="RollingRandomAccessFile"
fileName="${LOG_DIR}/blog.log"
filePattern="${LOG_DIR}/blog-%d{yyyy-MM-dd}.log">
<PatternLayout pattern="${PATTERN}"/>
<Policies>
<TimeBasedTriggeringPolicy interval="1"/>
</Policies>
<DefaultRolloverStrategy>
<Delete basePath="${LOG_DIR}" maxDepth="1">
<IfFileName glob="blog-*.log"/>
<IfLastModified age="3d"/>
</Delete>
</DefaultRolloverStrategy>
</RollingRandomAccessFile>
</appenders>
<loggers>
<AsyncRoot level="info" includeLocation="true">
<appenderref ref="Console"/>
<appenderref ref="RollingRandomAccessFile"/>
</AsyncRoot>
</loggers>
</configuration>
log4j2不产生日志文件
sprig boot 配置 log4j2 后不产生日志文件,一开始以为是没有配置异步日志的依赖 disruptor
后来配上发现还是不行,折腾了好几天,最后仔细看了下sprig启动时报的 slf4j 警告,发现启动时有两个 slf4j StaticLoggerBinder
的实现类
SLF4J: Class path contains multiple SLF4J bindings.
SLF4J: Found binding in [jar:file:/Users/si.ma/.m2/repository/ch/qos/logback/logback-classic/1.2.3/logback-classic-1.2.3.jar!/org/slf4j/impl/StaticLoggerBinder.class]
SLF4J: Found binding in [jar:file:/Users/si.ma/.m2/repository/org/apache/logging/log4j/log4j-slf4j-impl/2.10.0/log4j-slf4j-impl-2.10.0.jar!/org/slf4j/impl/StaticLoggerBinder.class]
SLF4J: See http://www.slf4j.org/codes.html#multiple_bindings for an explanation.
SLF4J: Actual binding is of type [ch.qos.logback.classic.util.ContextSelectorStaticBinder]
如上我项目 classpath 中同时有 logback 和 log4j 的 StaticLoggerBinder.class
类实现,slf4j最终自动选择了logback日志实现,感觉可能是这个原因导致log4j日志文件没有创建。
配置maven依赖时已经从 spring-boot-starter-web
中排除了 spring-boot-starter-logging
,但通过查看 maven 依赖树,发现还是有 logback-classic 依赖
通过 mvn dependency:tree
命令查看依赖树,发现确实还有 logback 依赖存在,如下:
[INFO] com.masikkk:blog:jar:0.0.1-SNAPSHOT
[INFO] +- org.springframework.boot:spring-boot-starter:jar:2.0.4.RELEASE:compile
[INFO] | +- org.springframework.boot:spring-boot:jar:2.0.4.RELEASE:compile
[INFO] | | \- org.springframework:spring-context:jar:5.0.8.RELEASE:compile
[INFO] | +- org.springframework.boot:spring-boot-autoconfigure:jar:2.0.4.RELEASE:compile
[INFO] | +- org.springframework.boot:spring-boot-starter-logging:jar:2.0.4.RELEASE:compile
[INFO] | | +- ch.qos.logback:logback-classic:jar:1.2.3:compile
[INFO] | | | \- ch.qos.logback:logback-core:jar:1.2.3:compile
原来 spring-boot-starter
依赖了 spring-boot-starter-logging
依赖了 logback-classic
,将其从依赖中排除,再次启动spring,成功生成log文件,日志所在的目录都会自动创建的。
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
SLF4J: Class path contains multiple SLF4J bindings
https://stackoverflow.com/questions/14024756/slf4j-class-path-contains-multiple-slf4j-bindings
上一篇 Spring-Cloud
下一篇 2019年运动记录
页面信息
location:
protocol
: host
: hostname
: origin
: pathname
: href
: document:
referrer
: navigator:
platform
: userAgent
: