Logback 1.6.1 已经发布。Logback 延续了 log4j 1.x 的发展脉络,并通过模块化架构覆盖普通 Java 应用、SLF4J 日志实现以及 HTTP 访问日志等场景。本次更新涉及 TimeBasedRollingPolicy 在设置 file 选项时的行为,因此,使用按时间滚动日志的服务值得优先检查配置并完成回归测试。
由于现有摘要没有给出该项变更的完整描述,本文不推断具体修复细节,而是围绕受影响配置给出一套可直接运行的验证方法。
三个模块分别解决什么问题
Logback 由三个主要模块组成:
logback-core:提供 Appender、Layout、滚动策略等基础能力,其他模块建立在它之上。logback-classic:实现 SLF4J API,也是普通 Java、Spring 等应用最常使用的模块。logback-access:面向 HTTP 访问日志,通常需要与支持它的 Servlet 容器或服务器集成。
业务项目一般不需要分别声明 core 和 classic。直接依赖 logback-classic 时,构建工具会传递引入相应的核心模块。不要同时放入多个 SLF4J 日志实现,否则可能出现 provider 冲突或实际加载的实现与预期不符。
为什么要关注 file 与滚动策略的组合
使用 RollingFileAppender 时,以下两个配置承担不同职责:
<file>指定当前正在写入的活动日志文件,例如logs/app.log。<fileNamePattern>指定归档文件的命名方式,例如logs/archive/app.2025-01-01.log。
不少生产配置希望活动文件名保持不变,便于日志采集器持续读取,同时每天把旧日志移动到归档目录。典型配置如下:
<file>logs/app.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>logs/archive/app.%d{yyyy-MM-dd}.log</fileNamePattern>
</rollingPolicy>
这恰好属于“设置了 file 选项并使用 TimeBasedRollingPolicy”的组合。升级后应重点验证:
- 应用启动后是否继续写入固定的活动文件。
- 到达时间边界后,旧文件是否按
fileNamePattern归档。 - 重启应用后是否错误覆盖、遗漏或重复归档文件。
- 日志采集器是否仍然跟踪正确的文件或 inode。
- 多实例是否误写同一路径;容器环境中挂载目录是否可写。
搭建一个可运行的滚动日志验证项目
下面的示例假设使用 JDK 11 或更高版本,并通过 Maven 运行。请根据项目实际 Java 基线以及 SLF4J 依赖关系确认兼容性。
创建目录:
mkdir -p logback-161-demo/src/main/java/com/example
mkdir -p logback-161-demo/src/main/resources
cd logback-161-demo
创建 pom.xml:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.example</groupId>
<artifactId>logback-161-demo</artifactId>
<version>1.0.0</version>
<properties>
<maven.compiler.release>11</maven.compiler.release>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.6.1</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<version>3.5.0</version>
<configuration>
<mainClass>com.example.App</mainClass>
</configuration>
</plugin>
</plugins>
</build>
</project>
创建 src/main/resources/logback.xml。为了便于测试,这里按分钟滚动;生产环境通常可以改为 %d{yyyy-MM-dd} 按天归档:
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<statusListener class="ch.qos.logback.core.status.OnConsoleStatusListener"/>
<appender name="ROLLING" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>logs/app.log</file>
<append>true</append>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>logs/archive/app.%d{yyyy-MM-dd_HH-mm}.log</fileNamePattern>
<maxHistory>5</maxHistory>
</rollingPolicy>
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} %-5level [%thread] %logger{36} - %msg%n</pattern>
</encoder>
</appender>
<root level="INFO">
<appender-ref ref="ROLLING"/>
</root>
</configuration>
创建 src/main/java/com/example/App.java:
package com.example;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public final class App {
private static final Logger log = LoggerFactory.getLogger(App.class);
public static void main(String[] args) throws InterruptedException {
for (int i = 1; i <= 150; i++) {
log.info("rolling-policy verification, sequence={}", i);
Thread.sleep(1000);
}
}
}
运行并观察文件变化:
mvn clean compile exec:java
在另一个终端中执行:
find logs -type f -maxdepth 2 -print | sort
tail -f logs/app.log
程序跨越分钟边界后,预期可以继续看到 logs/app.log 作为活动文件,并在 logs/archive/ 下看到带时间戳的归档文件。这个例子用于验证滚动行为,不代表生产环境应该按分钟切割日志。
如果想观察 Logback 的内部决策,可保留示例中的 OnConsoleStatusListener。它会输出配置解析、Appender 启动及文件相关错误。完成排查后可以移除,以免增加控制台噪声。
升级时不要只看“应用能启动”
日志组件的回归测试需要覆盖时间边界,而不只是启动阶段。可以按下面的顺序推进:
- 在测试环境保留旧版本生成的一组日志文件,然后升级到 1.6.1 并重启应用。
- 临时把滚动周期缩短到分钟级,确认活动文件与归档文件的转换过程。
- 检查应用用户对活动目录和归档目录是否都拥有写权限。
- 确认磁盘清理策略符合预期,尤其是
maxHistory、外部清理任务与采集器之间的配合。 - 检查依赖树,排除多个 Logback 版本或多个 SLF4J provider 同时存在的情况。
Maven 项目可以用下面的命令检查相关依赖:
mvn dependency:tree \
-Dincludes=ch.qos.logback:*,org.slf4j:*
采用建议
如果项目没有使用文件滚动,也可以按常规补丁版本流程评估 1.6.1;如果配置中同时出现 RollingFileAppender、TimeBasedRollingPolicy 和 <file>,则应把真实配置复制到预发布环境进行验证。
上线前至少确认四件事:活动日志持续写入、归档命名正确、重启不会破坏已有文件、日志采集链路没有中断。日志框架通常位于故障诊断链路的最底层,升级本身并不复杂,但一旦滚动或采集失效,问题往往要到真正需要日志时才会暴露。