Spring Boot 日志系统集成与多场景输出配置
Spring Boot日志系统深度解析
在Spring Boot生态中,开发者可以自由选择Java Util Logging、Log4j2或Logback作为底层日志框架。当使用官方提供的Starter启动器构建项目时,Spring
Boot默认采用Logback作为日志实现方案。无论选择哪种日志框架,Spring Boot均提供了统一的配置方式,支持将日志内容输出到控制台或持久化到文件中。
实际上,spring-boot-starter基础启动器已自动集成了spring-boot-starter-logging,该模块通过SLF4J日志门面抽象层,将Logback作为默认的日志实现框架。
通过配置文件调整日志行为
Spring Boot允许在配置文件中直接定义日志参数,这种方式虽然简单但灵活性有限,以下为常用配置示例:
# 日志配置文件路径,例如使用Logback时可指定:classpath:logback.xml
logging.config=
# 异常日志转换格式
logging.exception-conversion-word=%wEx
# 日志文件名称,例如:application.log
logging.file=
# 包路径日志级别映射,例如:logging.level.org.springframework=DEBUG
logging.level.*=
# 日志文件存储目录,例如:/var/log
logging.path=
# 控制台输出格式(仅默认Logback配置有效)
logging.pattern.console=
# 文件输出格式(仅默认Logback配置有效)
logging.pattern.file=
# 日志级别显示格式(默认%5p,仅默认Logback配置有效)
logging.pattern.level=
# 是否注册日志系统关闭钩子
logging.register-shutdown-hook=false
实际应用配置示例:
# 全局日志级别设置为DEBUG
logging.level.root=DEBUG
# Spring Web模块日志级别为DEBUG
logging.level.org.springframework.web=DEBUG
# Hibernate框架日志级别设置为ERROR
logging.level.org.hibernate=ERROR
自定义日志配置文件进阶指南
不同日志框架会自动加载特定名称的配置文件,这些文件需放置在资源根目录下,其他目录或命名方式将无法被识别。
| 日志框架 | 可识别的配置文件名称 |
|---|---|
| Logback | logback-spring.xml, logback-spring.groovy, logback.xml, logback.groovy |
| Log4j2 | log4j2-spring.xml, log4j2.xml |
| JDK(Java Util Logging) | logging.properties |
考虑到Logback作为Spring Boot的默认选择且功能强大,我们可以在资源目录下创建logback-spring.xml文件。以下是一个高度定制化的配置参考:
<?xml version="1.0" encoding="UTF-8"?>
<configuration debug="false">
<springProperty scope="context" name="APP_NAME" source="spring.application.name"/>
<springProperty scope="context" name="APP_PORT" source="server.port"/>
<springProperty scope="context" name="DEFAULT_APP_PORT" source="spring.application.port"/>
<property name="OS_NAME" value="${os.name}"/>
<if condition='property("OS_NAME").contains("Windows")'>
<then>
<property name="LOG_PATH" value="${LOG_PATH:-E:/logs}"/>
</then>
<else>
<property name="LOG_PATH" value="${LOG_PATH:-/log}"/>
</else>
</if>
<property name="LOG_DIR" value="${APP_NAME:-system}"/>
<property name="APP_PORT" value="${APP_PORT:-${DEFAULT_APP_PORT:-0}}"/>
<if condition='!property("APP_PORT").equals("0")'>
<then>
<property name="LOG_DIR" value="${LOG_DIR}-${APP_PORT}"/>
</then>
</if>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>
</encoder>
</appender>
<appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
<level>INFO</level>
</filter>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<FileNamePattern>${LOG_PATH}/${LOG_DIR}/info.log.%d{yyyy-MM-dd}.log</FileNamePattern>
<MaxHistory>30</MaxHistory>
</rollingPolicy>
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>
</encoder>
<triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
<MaxFileSize>10MB</MaxFileSize>
</triggeringPolicy>
</appender>
<appender name="FILE-ERROR" class="ch.qos.logback.core.rolling.RollingFileAppender">
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>ERROR</level>
<onMatch>ACCEPT</onMatch>
<onMismatch>DENY</onMismatch>
</filter>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<FileNamePattern>${LOG_PATH}/${LOG_DIR}/error.log.%d{yyyy-MM-dd}.log</FileNamePattern>
<MaxHistory>30</MaxHistory>
</rollingPolicy>
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>
</encoder>
<triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
<MaxFileSize>10MB</MaxFileSize>
</triggeringPolicy>
</appender>
<logger name="com.apache.ibatis" level="TRACE"/>
<logger name="java.sql.Connection" level="DEBUG"/>
<logger name="java.sql.Statement" level="DEBUG"/>
<logger name="java.sql.PreparedStatement" level="DEBUG"/>
<root level="INFO">
<appender-ref ref="STDOUT"/>
<appender-ref ref="FILE"/>
<appender-ref ref="FILE-ERROR"/>
</root>
</configuration>
重要建议:优先使用logback-spring.xml作为配置文件名。因为标准的logback.xml加载时机过早,此时Spring的ApplicationContext尚未创建,导致无法读取通过@PropertySources注解加载的属性。但以下类型的属性仍可正常访问:
- 系统环境变量
- Spring Environment中的属性
application和bootstrap配置文件中的值
属性读取示例:
- 读取系统环境变量(带默认值):
<property name="LOG_PATH" value="${LOG_PATH:-E:/logs}" /> - 读取Spring Environment中的属性:
<springProperty scope="context" name="fluentHost" source="myapp.fluentd.host" defaultValue="localhost"/>
环境感知配置:Spring Boot支持通过<springProfile>标签实现不同环境下的差异化配置:
<springProfile name="staging">
</springProfile>
<springProfile name="dev, staging">
</springProfile>
<springProfile name="!production">
</springProfile>本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来源 只有那年胜过年年!
评论
