如何在Log4j与Log4j2中隐藏日志中的JAR文件名?
当然可以实现隐藏日志里的JAR文件名,你提到的%replace确实是Log4j2里的核心方案,而针对Log4j(1.x)我们也有对应的兼容方案,下面分两种版本、两种配置文件类型来详细说明:
一、Log4j2 配置(兼容.properties和.xml)
Log4j2原生支持%replace转换器,它可以对指定的日志模式片段执行正则替换,刚好用来去掉JAR相关的后缀。
1. Properties配置文件
假设你原本的日志格式模式包含%l(输出完整位置信息,含JAR),修改成:
appender.console.layout.pattern = %d{yyyy-MM-dd HH:mm:ss} %-5level %logger{36} - %msg %replace{%l}{\\s~\\[.*?\\]}{}%n
这里的正则\\s~\\[.*?\\]会匹配并替换掉类似 ~[my-app.jar:1.0.0]的JAR后缀部分。如果你的原始模式里是其他包含JAR的字段(比如%C的扩展显示),可以调整正则来匹配对应的JAR标识。
2. XML配置文件
同样的逻辑,在PatternLayout里使用<Replace>标签或者直接在pattern里嵌入%replace:
<PatternLayout pattern="%d{yyyy-MM-dd HH:mm:ss} %-5level %logger{36} - %msg %replace{%l}{\s~\[.*?\]}{}%n"/>
或者用更清晰的标签式写法(Log4j2支持):
<PatternLayout> <pattern>%d{yyyy-MM-dd HH:mm:ss} %-5level %logger{36} - %msg </pattern> <Replace pattern="\s~\[.*?\]" replacement=""> <Pattern>%l</Pattern> </Replace> <pattern>%n</pattern> </PatternLayout>
二、Log4j 1.x 兼容方案
Log4j 1.x没有内置的%replace转换器,但我们可以通过两种方式实现:
1. 自定义PatternConverter
创建一个自定义转换器来处理位置信息,去掉JAR部分:
import org.apache.log4j.pattern.LoggingEvent; import org.apache.log4j.pattern.PatternConverter; import org.apache.log4j.pattern.PatternParser; public class CleanLocationConverter extends PatternConverter { @Override protected String convert(LoggingEvent event) { String location = event.getLocationInformation().fullInfo; // 移除JAR后缀部分 return location.replaceAll("\\s~\\[.*?\\]", ""); } public static void register() { PatternParser.addConverter("cleanLocation", CleanLocationConverter.class); } }
然后在项目启动时调用CleanLocationConverter.register(),之后在配置文件里用%cleanLocation代替%l:
log4j.appender.console.layout.ConversionPattern = %d{yyyy-MM-dd HH:mm:ss} %-5level %logger{36} - %msg %cleanLocation%n
2. 简化日志模式(无自定义代码)
如果不想写自定义代码,可以避免使用%l,改用%C{1}.%M(%F:%L)来组合位置信息,这样Log4j 1.x不会输出JAR文件名:
log4j.appender.console.layout.ConversionPattern = %d{yyyy-MM-dd HH:mm:ss} %-5level %logger{36} - %msg %C{1}.%M(%F:%L)%n
这个方案的好处是无需额外代码,但输出的位置信息和%l略有不同,不过可以满足隐藏JAR的需求。
三、跨版本兼容的小技巧
如果你的项目需要同时兼容Log4j和Log4j2,可以考虑:
- 对于Log4j2使用
%replace方案,对于Log4j 1.x使用简化模式或自定义转换器 - 统一日志模式的核心部分,只针对位置字段做版本适配
内容的提问来源于stack exchange,提问作者Maximiliano Santa Cruz

