Logback 1.5.37 发布:升级时别忽略条件配置里的 Janino

2026-07-01 39 预计阅读时间: 1 分钟
来源: oschina.net AI 摘要 Original link

Disclaimer: This article is an AI-assisted summary. Read it together with the original source when precision matters. The summary may omit context, version differences, or edge cases and is not official documentation.

预计阅读时间:8 分钟

Logback 1.5.37 已经发布。对大多数 Java 项目来说,Logback 仍然是“默认但关键”的基础设施:它不直接决定业务功能,却会影响排障效率、运行成本和生产环境的可观测性。这次发布值得注意的一点,是它触及了基于 Janino 对 Java 表达式求值的条件配置处理;如果你的 logback.xml 里使用了条件判断,升级前就不该只跑单元测试了事。

先看 Logback 的三块拼图

Logback 延续了 log4j 1.x 的设计脉络,但并不是简单复刻。它现在主要由三个模块组成:

  • logback-core:底层能力,包括 appender、encoder、rolling policy 等通用日志组件。
  • logback-classic:面向 SLF4J 的常用实现,绝大多数 Spring Boot、普通 Java 服务用到的是它。
  • logback-access:面向访问日志,例如 Web 容器请求日志场景。

日常项目里最常见的依赖组合通常是 slf4j-apilogback-classic。如果你用的是 Spring Boot,很多时候甚至不直接声明 Logback 版本,而是由 Boot 的依赖管理接管。

这次升级为什么要盯住条件配置

摘要里提到的关键点,是“基于 Janino 库对 Java 表达式进行求值的条件配置处理”。这类能力通常用于让日志配置根据环境、系统属性或变量动态变化,例如:开发环境输出彩色控制台日志,生产环境写 JSON 或滚动文件。

问题在于,配置文件里的表达式求值不是普通 XML 解析,它引入了额外的执行语义和依赖边界。升级到 1.5.37 时,建议重点检查这些位置:

  • logback.xmllogback-spring.xml 中是否使用了 <if><then><else> 一类条件配置。
  • 项目是否显式依赖 Janino,或者依赖树中是否间接带入 Janino。
  • CI、测试、预发、生产环境是否使用不同的系统属性触发不同日志路径。
  • 启动日志里是否出现配置解析警告,但被应用启动成功掩盖。

换句话说,这次升级不只是“改个版本号”。如果日志配置有条件分支,应该把配置加载本身当成一个需要验证的行为。

可以这样实践:升级并验证配置加载

下面是一个可以改造到 Maven 项目里的最小示例。版本号可以按你的依赖管理方式调整;如果项目由 Spring Boot 管理版本,优先在 Boot BOM 支持范围内升级。

<!-- pom.xml -->
<dependencies>
  <dependency>
    <groupId>ch.qos.logback</groupId>
    <artifactId>logback-classic</artifactId>
    <version>1.5.37</version>
  </dependency>

  <!-- 如果你的条件配置确实依赖 Janino 表达式,再显式确认该依赖 -->
  <dependency>
    <groupId>org.codehaus.janino</groupId>
    <artifactId>janino</artifactId>
    <version>3.1.12</version>
  </dependency>
</dependencies>

一个带条件分支的 logback.xml 可以这样写。运行前把 LOG_DIR 改成你的本地目录,或用 JVM 参数传入 -Denv=dev / -Denv=prod

<!-- src/main/resources/logback.xml -->
<configuration>
  <property name="LOG_DIR" value="./logs" />

  <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
    <encoder>
      <pattern>%d{HH:mm:ss.SSS} %-5level [%thread] %logger{36} - %msg%n</pattern>
    </encoder>
  </appender>

  <appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
    <file>${LOG_DIR}/app.log</file>
    <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
      <fileNamePattern>${LOG_DIR}/app.%d{yyyy-MM-dd}.log</fileNamePattern>
      <maxHistory>7</maxHistory>
    </rollingPolicy>
    <encoder>
      <pattern>%d{yyyy-MM-dd'T'HH:mm:ss.SSS} %-5level %logger - %msg%n</pattern>
    </encoder>
  </appender>

  <if condition='property("env").equals("prod")'>
    <then>
      <root level="INFO">
        <appender-ref ref="FILE" />
      </root>
    </then>
    <else>
      <root level="DEBUG">
        <appender-ref ref="CONSOLE" />
      </root>
    </else>
  </if>
</configuration>

配一个最小 Java 入口,用来确认配置分支是否按预期生效:

// src/main/java/demo/App.java
package demo;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class App {
  private static final Logger log = LoggerFactory.getLogger(App.class);

  public static void main(String[] args) {
    log.debug("debug message, env={}", System.getProperty("env"));
    log.info("info message, env={}", System.getProperty("env"));
  }
}

可以用下面的命令做两轮验证:

mvn -q dependency:tree | grep -E 'logback|janino|slf4j'
mvn -q -Denv=dev exec:java -Dexec.mainClass=demo.App
mvn -q -Denv=prod exec:java -Dexec.mainClass=demo.App
ls -lah logs || true

你要看的不是“程序是否启动”,而是:开发环境是否打印 DEBUG 到控制台,生产环境是否只把 INFO 写入文件,以及启动阶段有没有 Logback 配置警告。

升级检查清单

升级 Logback 1.5.37 时,建议把检查做得比普通补丁版本更细一点:

  • 锁定依赖树:确认实际运行的是 logback-corelogback-classic 的同一版本,避免传递依赖拉出混合版本。
  • 搜索条件配置:在仓库里查找 <ifcondition=janino,定位所有动态日志分支。
  • 覆盖启动场景:至少跑一遍本地、测试、生产等关键 profile 对应的 JVM 参数或环境变量。
  • 观察启动日志:Logback 配置错误经常在应用真正处理请求之前就出现,别只看接口冒烟结果。
  • 保守处理生产变更:日志系统出问题会直接影响排障,建议先灰度到非核心服务或单个实例。

取舍:动态配置有用,但别让日志文件变成小程序

Logback 的通用架构让它能适配很多场景,这是它长期流行的重要原因。但条件配置越复杂,升级和排障成本也越高。对于简单差异,优先考虑环境变量、profile 分离或部署层注入;只有确实需要表达式判断时,再使用 Janino 相关能力。

这次 1.5.37 发布可以当作一次提醒:日志框架不是“装上就忘”的依赖。它离生产现场很近,升级时既要看版本,也要看配置如何被解释和执行。


相关推荐