You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Log4j2能否让StrLookup实现每次日志事件都重新计算返回值?

解决Log4j2自定义StrLookup只执行一次的问题

你的问题出在Log4j2对配置占位符的解析策略上:${customLog:simDate}属于配置阶段解析,只会在初始化PatternLayout时执行一次lookup,结果被缓存后复用;而要实现每条日志都重新计算,需要改用运行时渲染阶段执行的%lookup模式指令。

具体修改步骤:

  1. 调整PatternLayout的模式字符串
    把原来的:
"[%level] [%c] [%M] - %msg - ${customLog:simDate}%n"

替换成:

"[%level] [%c] [%M] - %msg - %lookup{customLog:simDate}%n"
  1. 优化lookup方法(可选)
    直接在带LogEvent参数的重载方法中处理动态逻辑,避免依赖无参方法:
@Override
public String lookup(LogEvent event, String key) {
    double d = Math.random();
    System.out.println(d);
    return switch (key) {
        case "simDate" -> String.valueOf(d);
        default -> "<Lookup key not found>";
    };
}

// 配置阶段调用时返回默认值,因为我们只在运行时用%lookup触发
@Override
public String lookup(String key) {
    return "<Lookup key not found>";
}

修改后的效果

运行代码后,三条日志会各自触发一次lookup方法,输出不同的随机数:

[INFO] [org.example.Main] [main] - Hello World! - 0.123456789
[WARN] [org.example.Main] [main] - Hello World! - 0.987654321
[ERROR] [org.example.Main] [main] - Hello World! - 0.567890123

原理说明

  • ${xxx}:Log4j2加载配置文件时解析,结果缓存到配置对象中,后续所有日志复用该缓存值。
  • %lookup{xxx}:属于PatternLayout的格式化指令,在每条日志事件渲染时执行lookup逻辑,因此每次都会重新计算值,适配动态内容(比如模拟进度、实时变量值等场景)。

内容的提问来源于stack exchange,提问作者Sebastian Felix

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.17 00:58:11