Log4j2能否让StrLookup实现每次日志事件都重新计算返回值?
解决Log4j2自定义StrLookup只执行一次的问题
你的问题出在Log4j2对配置占位符的解析策略上:${customLog:simDate}属于配置阶段解析,只会在初始化PatternLayout时执行一次lookup,结果被缓存后复用;而要实现每条日志都重新计算,需要改用运行时渲染阶段执行的%lookup模式指令。
具体修改步骤:
- 调整PatternLayout的模式字符串
把原来的:
"[%level] [%c] [%M] - %msg - ${customLog:simDate}%n"
替换成:
"[%level] [%c] [%M] - %msg - %lookup{customLog:simDate}%n"
- 优化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
相关产品推荐
相关产品推荐

