logback 速查上手

下面给出一份"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

  1. 关闭 debug 级别:<logger name="com.alibaba.nacos" level="WARN"/>

  2. 关闭 includeCallerData(AsyncAppender 里拿行号会慢 5~10 倍)。

  3. 使用 SizeAndTimeBasedRollingPolicy 而非 FixedWindowRollingPolicy,大并发下减少重命名竞争。

  4. 磁盘独立:日志盘与业务盘分离,避免 java.io.IOException: No space left on device 把应用拖死。

  5. 监控:

  • 文件句柄数 /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,线上稳得一批。祝排错愉快!

相关推荐
没有bug.的程序员1 天前
Spring Boot 日志管理:从 Logback 深度配置到 ELK 万亿级日志中枢实战
java·spring boot·elk·logback·日志·管理
南朝雨9 天前
Spring Boot Admin日志监控坑点:远程配置的logging.file.name为何生效又失效?
java·spring boot·spring cloud·微服务·logback
麦兜*18 天前
Spring Boot 日志配置 + Logback vs Log4j2 性能对比 + 选型建议
spring boot·log4j·logback
M***Z21019 天前
springboot中配置logback-spring.xml
spring boot·spring·logback
sunnyday042621 天前
深入理解Java日志框架:Logback与Log4j2配置对比分析
java·log4j·logback
JavaEdge.23 天前
Logback 启动错误修复说明
logback
煎饼皮皮侠1 个月前
快速查找应用日志的几个场景
unzip·logback·grep
垚森1 个月前
【问题解决】关于log4j与logback依赖冲突的解决方案
log4j·logback·问题解决·依赖冲突
wL魔法师1 个月前
【日志】Logback 配置问题(no applicable action for [springProfile])
logback