下面给出一份"logback 速查手册",从"零配置能跑"到"线上调优"一条线捋清,复制即可用。
一、logback 是什么
-
作者:log4j 创始人 Ceki Gülcü 的"亲儿子",SLF4J 默认实现。
-
特点:速度更快、内存占用更低、XML/Groovy 双配置、SiftingAppender(多租户/多文件自动分离)、自动热加载。
二、零依赖就能跑(Spring Boot 已内置)
XML
<!-- 实际不用再引,spring-boot-starter-web 已传递 -->
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
</dependency>
代码里:
java
private static final Logger log = LoggerFactory.getLogger(UserService.class);
log.info("order {} paid", orderId);
三、核心三件套
Logger(写日志) → Appender(写到哪) → Encoder/Layout(怎么格式化)
四、最常用配置文件(src/main/resources/logback-spring.xml,SpringBoot 专用)
XML
<?xml version="1.0" encoding="UTF-8"?>
<configuration scan="true" scanPeriod="30 seconds"> <!-- 30s热加载 -->
<springProfile name="dev,test"> <!-- 开发/测试环境彩色控制台 -->
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<pattern>%cyan(%d{HH:mm:ss.SSS}) %highlight(%-5level) %magenta([%thread]) %yellow(%logger{36}:%line) - %msg%n</pattern>
<charset>UTF-8</charset>
</encoder>
</appender>
<root level="INFO">
<appender-ref ref="CONSOLE"/>
</root>
</springProfile>
<springProfile name="prod"> <!-- 生产只按大小/日期滚动文件 -->
<property name="LOG_HOME" value="/var/log/app"/>
<appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${LOG_HOME}/business.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<fileNamePattern>${LOG_HOME}/business.%d{yyyy-MM-dd}.%i.log.gz</fileNamePattern>
<maxFileSize>200MB</maxFileSize>
<maxHistory>30</maxHistory>
<totalSizeCap>20GB</totalSizeCap>
</rollingPolicy>
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36}:%line - %msg%n</pattern>
<charset>UTF-8</charset>
</encoder>
</appender>
<!-- 异步提升性能,丢日志<0.01%可接受 -->
<appender name="ASYNC" class="ch.qos.logback.classic.AsyncAppender">
<appender-ref ref="FILE"/>
<queueSize>2048</queueSize>
<discardingThreshold>0</discardingThreshold>
<includeCallerData>false</includeCallerData>
</appender>
<root level="INFO">
<appender-ref ref="ASYNC"/>
</root>
</springProfile>
<!-- 单独给 error 再写一份,方便告警 -->
<appender name="ERROR" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${LOG_HOME:-./logs}/error.log</file>
<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_HOME:-./logs}/error.%d{yyyy-MM-dd}.log.gz</fileNamePattern>
<maxHistory>15</maxHistory>
</rollingPolicy>
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %logger{36}:%line - %msg%n</pattern>
</encoder>
</appender>
<root level="INFO">
<appender-ref ref="ERROR"/>
</root>
</configuration>
要点
-
文件名必须是 logback-spring.xml 才能用 <springProfile> 动态区分环境,否则启动报错。
-
scan="true" 修改配置后 30 秒自动生效,无需重启。
-
AsyncAppender 队列满时会丢弃 TRACE/DEBUG,INFO 以上不丢(discardingThreshold=0)。
五、多租户/多文件自动分离(SiftingAppender 实战)
XML
<appender name="SIFT" class="ch.qos.logback.classic.sift.SiftingAppender">
<discriminator>
<key>tenantId</key>
<defaultValue>default</defaultValue>
</discriminator>
<sift>
<appender class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>/var/log/app/${tenantId}.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>/var/log/app/${tenantId}.%d{yyyy-MM-dd}.log.gz</fileNamePattern>
<maxHistory>15</maxHistory>
</rollingPolicy>
<encoder>
<pattern>%d{HH:mm:ss.SSS} [%thread] %level %logger{36} - %msg%n</pattern>
</encoder>
</appender>
</sift>
</appender>
代码里放 discriminator:
java
MDC.put("tenantId", TenantContext.get());
即可按租户自动拆文件,再也不用 if-else 新建 logger。
六、线上调优 checklist
-
关闭 debug 级别:<logger name="com.alibaba.nacos" level="WARN"/>
-
关闭 includeCallerData(AsyncAppender 里拿行号会慢 5~10 倍)。
-
使用 SizeAndTimeBasedRollingPolicy 而非 FixedWindowRollingPolicy,大并发下减少重命名竞争。
-
磁盘独立:日志盘与业务盘分离,避免 java.io.IOException: No space left on device 把应用拖死。
-
监控:
-
文件句柄数 /proc/sys/fs/file-max
-
日志写入延迟:appender.getQueueSize() / appender.getDiscardingCount()
-
接入 Prometheus:通过 logback-metrics 暴露 logback_events_total{level="error"} 做告警。
七、常见坑
| 现象 | 原因 | 快速 fix |
|---|---|---|
| 修改 logback.xml 不生效 | 文件名写成 logback.xml 却被 spring 提前加载 | 改名 logback-spring.xml |
| 控制台彩色失效 | Windows 老版本 ANSI 不支持 | 加 jansi 依赖或关闭彩色 |
| 启动报 "no applicable action for [springProfile]" | 用了普通 logback.xml | 换 logback-spring.xml |
| 日志文件中文乱码 | 没有 <charset>UTF-8</charset> | 全部 encoder 加 charset |
一张图记忆 Logger → 级别开关 ↓ Appender → 写控制台?文件?ES? ↓ Encoder → 长啥样?JSON? pattern? ↓ RollingPolicy → 多大切割?保留几天?
把上面模板直接粘进项目,30 秒内就能拥有"彩色控制台 + 大小时间滚动 + 异步写盘 + ERROR 单独文件"的标配日志,再按环境切 profile,线上稳得一批。祝排错愉快!