logback-spring.xml 完整生产模板

这是一个可直接用于生产环境logback-spring.xml完整模板。

它涵盖了日志滚动策略、多环境配置、JSON结构化输出(ELK兼容)、敏感信息脱敏、性能优化等核心要素。


完整模板

<?xml version="1.0" encoding="UTF-8"?> <configuration scan="true" scanPeriod="60 seconds" debug="false"> <!-- 生产级 Logback 配置模板 特性: 1. 多环境隔离(dev/test/prod) 2. 日志滚动策略(按大小和时间) 3. JSON 格式输出(ELK 友好) 4. 敏感信息脱敏(手机号、身份证、密码等) 5. 异步日志(提升性能) 6. 错误日志单独输出 --> <!-- ==================== 1. 自定义属性 ==================== --> <!-- 日志存放路径 --> <property name="LOG_PATH" value="/var/log/your-app" /> <!-- 应用名称(用于区分不同服务) --> <property name="APP_NAME" value="your-service" /> <!-- 日志保留天数 --> <property name="MAX_HISTORY" value="30" /> <!-- 单文件最大大小 --> <property name="MAX_FILE_SIZE" value="500MB" /> <!-- 总磁盘空间限制 --> <property name="TOTAL_SIZE_CAP" value="20GB" /> <!-- 控制台日志格式(开发环境友好,带颜色) --> <property name="CONSOLE_PATTERN" value="%d{yyyy-MM-dd HH:mm:ss.SSS} %highlight(%-5level) [%thread] %cyan(%logger{36}) - %msg%n" /> <!-- 文件日志格式(普通文本) --> <property name="FILE_PATTERN" value="%d{yyyy-MM-dd HH:mm:ss.SSS} %-5level [%thread] %logger{36} - %msg%n" /> <!-- ==================== 2. 敏感信息脱敏转换器 ==================== --> <!-- 定义脱敏规则,替换日志中的敏感字段 --> <conversionRule conversionWord="mask" converterClass="com.yourpackage.MaskConverter" /> <!-- 如果没有自定义 Converter,可以使用内置的 replace 函数: 例如将手机号替换为 138****1234,详见下面 appender 中的用法 --> <!-- ==================== 3. 日志 Appender 定义 ==================== --> <!-- 3.1 控制台输出(仅开发环境启用,生产环境建议关闭) --> <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender"> <encoder> <pattern>${CONSOLE_PATTERN}</pattern> <charset>UTF-8</charset> </encoder> </appender> <!-- 3.2 常规文件日志(按天滚动,带大小分割) --> <appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender"> <file>${LOG_PATH}/${APP_NAME}.log</file> <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy"> <!-- 滚动文件命名:日期 + 序号 --> <fileNamePattern>${LOG_PATH}/${APP_NAME}.%d{yyyy-MM-dd}.%i.log</fileNamePattern> <!-- 单文件最大大小,达到后触发滚动 --> <maxFileSize>${MAX_FILE_SIZE}</maxFileSize> <!-- 保留天数 --> <maxHistory>${MAX_HISTORY}</maxHistory> <!-- 磁盘总容量限制 --> <totalSizeCap>${TOTAL_SIZE_CAP}</totalSizeCap> </rollingPolicy> <encoder> <pattern>${FILE_PATTERN}</pattern> <charset>UTF-8</charset> </encoder> <!-- 生产环境推荐立即刷新(保证数据完整性),性能要求极高时可改为 false --> <immediateFlush>true</immediateFlush> </appender> <!-- 3.3 错误日志单独输出(只记录 ERROR 级别) --> <appender name="ERROR_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender"> <file>${LOG_PATH}/${APP_NAME}-error.log</file> <!-- 只记录 ERROR 级别 --> <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.SizeAndTimeBasedRollingPolicy"> <fileNamePattern>${LOG_PATH}/${APP_NAME}-error.%d{yyyy-MM-dd}.%i.log</fileNamePattern> <maxFileSize>${MAX_FILE_SIZE}</maxFileSize> <maxHistory>${MAX_HISTORY}</maxHistory> <totalSizeCap>${TOTAL_SIZE_CAP}</totalSizeCap> </rollingPolicy> <encoder> <pattern>${FILE_PATTERN}</pattern> <charset>UTF-8</charset> </encoder> <immediateFlush>true</immediateFlush> </appender> <!-- 3.4 JSON 格式 Appender(用于对接 ELK / 日志中心) --> <appender name="JSON_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender"> <file>${LOG_PATH}/${APP_NAME}-json.log</file> <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy"> <fileNamePattern>${LOG_PATH}/${APP_NAME}-json.%d{yyyy-MM-dd}.%i.log</fileNamePattern> <maxFileSize>${MAX_FILE_SIZE}</maxFileSize> <maxHistory>${MAX_HISTORY}</maxHistory> <totalSizeCap>${TOTAL_SIZE_CAP}</totalSizeCap> </rollingPolicy> <!-- 使用 Logstash 编码器输出 JSON --> <encoder class="net.logstash.logback.encoder.LogstashEncoder"> <!-- 应用名称 --> <customFields>{"app_name":"${APP_NAME}","env":"${SPRING_PROFILES_ACTIVE:-unknown}"}</customFields> <!-- 包含 MDC 上下文 --> <includeMdc>true</includeMdc> <!-- 不包含调用者位置信息(提升性能) --> <includeCallerData>false</includeCallerData> </encoder> </appender> <!-- 3.5 异步 Appender(包装同步 Appender,提升性能) --> <appender name="ASYNC_FILE" class="ch.qos.logback.classic.AsyncAppender"> <!-- 丢失日志时丢弃 DEBUG/TRACE,保留 INFO 及以上 --> <discardingThreshold>0</discardingThreshold> <!-- 队列大小,默认 256,生产环境建议 512~1024 --> <queueSize>512</queueSize> <!-- 如果队列满,是否阻塞主线程(false = 丢弃日志,避免影响业务) --> <neverBlock>true</neverBlock> <!-- 引用的同步 Appender --> <appender-ref ref="FILE" /> <!-- 如果需要 JSON 也异步,再追加一行 --> <!-- <appender-ref ref="JSON_FILE" /> --> </appender> <appender name="ASYNC_ERROR" class="ch.qos.logback.classic.AsyncAppender"> <discardingThreshold>0</discardingThreshold> <queueSize>256</queueSize> <neverBlock>true</neverBlock> <appender-ref ref="ERROR_FILE" /> </appender> <!-- ==================== 4. 第三方库日志级别控制 ==================== --> <!-- 避免第三方框架输出过多无用日志 --> <logger name="org.springframework" level="INFO" /> <logger name="org.springframework.web" level="INFO" /> <logger name="org.springframework.boot" level="INFO" /> <logger name="org.apache" level="WARN" /> <logger name="org.hibernate" level="WARN" /> <logger name="com.netflix" level="WARN" /> <logger name="org.apache.kafka" level="WARN" /> <logger name="io.netty" level="WARN" /> <!-- 业务包路径,可调整到 DEBUG(需配合环境) --> <logger name="com.yourpackage" level="INFO" /> <!-- ==================== 5. Spring Profile 多环境配置 ==================== --> <!-- 开发环境:输出控制台 + 文件,级别 DEBUG --> <springProfile name="dev"> <root level="DEBUG"> <appender-ref ref="CONSOLE" /> <appender-ref ref="ASYNC_FILE" /> <appender-ref ref="ASYNC_ERROR" /> </root> </springProfile> <!-- 测试环境:输出文件 + JSON,级别 INFO --> <springProfile name="test"> <root level="INFO"> <appender-ref ref="ASYNC_FILE" /> <appender-ref ref="ASYNC_ERROR" /> <appender-ref ref="JSON_FILE" /> </root> </springProfile> <!-- 生产环境:只输出文件 + JSON(关闭控制台),级别 INFO --> <springProfile name="prod"> <root level="INFO"> <appender-ref ref="ASYNC_FILE" /> <appender-ref ref="ASYNC_ERROR" /> <appender-ref ref="JSON_FILE" /> </root> </springProfile> <!-- 默认配置(无 profile 时生效) --> <springProfile name="default"> <root level="INFO"> <appender-ref ref="CONSOLE" /> <appender-ref ref="ASYNC_FILE" /> <appender-ref ref="ASYNC_ERROR" /> </root> </springProfile> </configuration>

依赖引入(Maven)

确保pom.xml中包含以下依赖:

<!-- Spring Boot 默认已包含 Logback + SLF4J,只需添加以下增强包 --> <!-- JSON 格式编码器(用于 ELK) --> <dependency> <groupId>net.logstash.logback</groupId> <artifactId>logstash-logback-encoder</artifactId> <version>7.4</version> <!-- 使用最新稳定版 --> </dependency> <!-- 如果需要自定义脱敏 Converter,需引入工具类 --> <dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-lang3</artifactId> </dependency>

关键配置说明

配置项作用生产建议
scan="true" scanPeriod="60 seconds"动态检测配置文件变更,无需重启建议开启,但debug="false"避免日志泛滥
SizeAndTimeBasedRollingPolicy同时按时间和大小滚动防止单文件过大导致磁盘爆满
AsyncAppender异步写日志,不阻塞主线程强烈推荐neverBlock=true防止业务夯住
LogstashEncoder输出 JSON 格式对接 ELK 时必须,支持customFields注入元数据
<springProfile>多环境隔离开发环境输出控制台,生产环境关闭
immediateFlush=true每次写入立即刷新生产环境建议true(可靠性优先),压测可调false

自定义脱敏 Converter(可选)

如果你需要精确脱敏(如手机号、身份证),创建以下类:

import ch.qos.logback.classic.pattern.ClassicConverter; import ch.qos.logback.classic.spi.ILoggingEvent; public class MaskConverter extends ClassicConverter { @Override public String convert(ILoggingEvent event) { String msg = event.getFormattedMessage(); // 手机号脱敏:13812345678 → 138****5678 msg = msg.replaceAll("(1\\d{2})\\d{4}(\\d{4})", "$1****$2"); // 身份证脱敏 msg = msg.replaceAll("(\\d{6})\\d{8}(\\d{4})", "$1********$2"); // 密码脱敏 msg = msg.replaceAll("(?i)(password|pwd|passwd)[\\s]*[=:][\\s]*\\S+", "$1=******"); return msg; } }

然后在模板顶部使用<conversionRule>注册,并在pattern中通过%mask引用。


避坑提醒

  1. 日志路径权限:确保${LOG_PATH}目录存在且应用有读写权限,否则启动失败。

  2. 磁盘监控:务必对日志目录配置磁盘告警(如 80% 触发预警),防止日志打满磁盘。

  3. 异步队列监控AsyncAppender队列满时若neverBlock=true会丢弃日志,需配合监控发现。

  4. 不要同时使用CONSOLE+FILE同步模式:生产环境关闭 CONSOLE,否则磁盘 IO 翻倍。