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

Log4J JsonTemplateLayout日志手机号替换失效问题求助

Log4J 手机号脱敏配置问题解决

问题背景

使用Log4J记录日志时,原配置依赖已弃用的LogStashJsonLayout,为实现手机号脱敏(替换为3********9),切换为JsonTemplateLayout并配置了替换规则,但日志中仍出现明文手机号。

原RollingFile Appender配置:

<RollingFile name="FILE-LOGSTASH"
             fileName="C:\Users\p.bohomaz\IdeaProjects\o2-lcm\log4j-logstash.log"
             filePattern="C:\Users\p.bohomaz\IdeaProjects\o2-lcm\log4j-logstash-%d{yyyy-MM-dd-HH}.log.gz">
    <LogStashJsonLayout/>
    <Policies>
        <TimeBasedTriggeringPolicy interval="1" modulate="true"/>
    </Policies>
</RollingFile>

修改后的配置:

<RollingFile name="FILE-LOGSTASH"
             fileName="C:\Users\p.bohomaz\IdeaProjects\o2-lcm\log4j-logstash.log"
             filePattern="C:\Users\p.bohomaz\IdeaProjects\o2-lcm\log4j-logstash-%d{yyyy-MM-dd-HH}.log.gz">
    <JsonTemplateLayout eventTemplateUri="classpath:EcsLayout.json"/>

    <Policies>
        <TimeBasedTriggeringPolicy interval="1" modulate="true"/>
    </Policies>
</RollingFile>

对应的EcsLayout.json模板:

{
  "@version": "1",
  "@timestamp": {
    "$resolver": "timestamp",
    "pattern": {
      "format": "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'",
      "timeZone": "UTC"
    }
  },
  "logger": {
    "$resolver": "logger",
    "field": "name"
  },
  "priority": {
    "$resolver": "level",
    "field": "name"
  },
  "thread": {
    "$resolver": "thread",
    "field": "name"
  },
  "message": {
    "$resolver": "message",
    "replace": {
      "regex": "(\\d{2})(\\d{7,11})(\\d{2})",
      "replacement": "$1********$3"
    }
  }
}

问题原因

  1. 正则表达式匹配错误:原正则(\\d{2})(\\d{7,11})(\\d{2})匹配2位前缀+7-11位中间+2位后缀,总长度11-15位,不符合国内11位手机号的结构(1位前缀+9位中间+1位后缀),导致无法匹配目标手机号。
  2. 替换规则不符合需求:若目标是将任意手机号替换为固定的3********9,原规则保留前后两位的逻辑与需求不符。

解决方案

方案一:修正JsonTemplateLayout模板实现脱敏

根据需求调整正则和替换规则:

情况1:将所有11位手机号替换为固定字符串3********9

修改模板中的message节点:

"message": {
  "$resolver": "message",
  "replace": {
    "regex": "\\b1[3-9]\\d{9}\\b",
    "replacement": "3********9"
  }
}
  • \\b用于匹配单词边界,避免匹配长数字串中的片段;
  • 1[3-9]\\d{9}精准匹配国内标准11位手机号。

情况2:保留手机号首尾1位,中间8位替换为*(如13812345679→1********9)

修改模板中的message节点:

"message": {
  "$resolver": "message",
  "replace": {
    "regex": "(\\d)(\\d{9})(\\d)",
    "replacement": "$1********$3"
  }
}

方案二:使用Log4J过滤器实现全局脱敏

若手机号可能出现在日志的多个字段(如MDC、参数等),推荐用RewriteAppender配合自定义过滤器:

  1. 自定义脱敏过滤器类:
import org.apache.logging.log4j.core.LogEvent;
import org.apache.logging.log4j.core.appender.rewrite.RewritePolicy;
import org.apache.logging.log4j.core.impl.Log4jLogEvent;
import org.apache.logging.log4j.message.Message;
import org.apache.logging.log4j.message.SimpleMessage;

public class PhoneNumberRewritePolicy implements RewritePolicy {
    private static final String PHONE_REGEX = "\\b1[3-9]\\d{9}\\b";
    private static final String REPLACEMENT = "3********9";

    @Override
    public LogEvent rewrite(LogEvent event) {
        Message originalMessage = event.getMessage();
        String modifiedMessage = originalMessage.getFormattedMessage().replaceAll(PHONE_REGEX, REPLACEMENT);
        Message newMessage = new SimpleMessage(modifiedMessage);
        return new Log4jLogEvent.Builder(event).setMessage(newMessage).build();
    }
}
  1. 修改Log4J配置,添加RewriteAppender:
<Configuration>
    <Appenders>
        <RollingFile name="FILE-LOGSTASH-ORIGINAL"
                     fileName="C:\Users\p.bohomaz\IdeaProjects\o2-lcm\log4j-logstash.log"
                     filePattern="C:\Users\p.bohomaz\IdeaProjects\o2-lcm\log4j-logstash-%d{yyyy-MM-dd-HH}.log.gz">
            <JsonTemplateLayout eventTemplateUri="classpath:EcsLayout.json"/>
            <Policies>
                <TimeBasedTriggeringPolicy interval="1" modulate="true"/>
            </Policies>
        </RollingFile>

        <Rewrite name="REWRITE-PHONE">
            <RewritePolicy class="com.yourpackage.PhoneNumberRewritePolicy"/>
            <AppenderRef ref="FILE-LOGSTASH-ORIGINAL"/>
        </Rewrite>
    </Appenders>

    <Loggers>
        <Root level="info">
            <AppenderRef ref="REWRITE-PHONE"/>
        </Root>
    </Loggers>
</Configuration>

验证注意事项

  • 确保Log4J版本≥2.17.0(JsonTemplateLayout的replace功能需该版本支持);
  • 若日志通过参数化方式生成(如logger.info("手机号: {}", phone)),需确认格式化后的字符串能被正则匹配;
  • 检查日志中手机号的出现位置,若不在message字段,需在模板中对应字段添加替换规则,或使用过滤器实现全局处理。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.19 21:52:03