logback 日志脱敏

发布于:2024-05-14 ⋅ 阅读:(29) ⋅ 点赞:(0)

工具类

CustomLogbackPatternLayoutEncoder.java


import ch.qos.logback.classic.encoder.PatternLayoutEncoder;

public class CustomLogbackPatternLayoutEncoder extends PatternLayoutEncoder {

    /**
     * 正则替换规则
     */
    private LogbackReplaces replaces;

    /**
     * 使用自定义 MyLogbackPatternLayout 格式化输出
     */
    @Override
    public void start() {
        CustomPatternLayout patternLayout = new CustomPatternLayout(replaces);
        patternLayout.setContext(context);
        patternLayout.setPattern(this.getPattern());
        patternLayout.setOutputPatternAsHeader(outputPatternAsHeader);
        patternLayout.start();
        this.layout = patternLayout;
        started = true;
    }


    public LogbackReplaces getReplaces() {
        return replaces;
    }

    public void setReplaces(LogbackReplaces replaces) {
        this.replaces = replaces;
    }
}

CustomPatternLayout.java


import ch.qos.logback.classic.PatternLayout;
import ch.qos.logback.classic.spi.ILoggingEvent;
import lombok.extern.slf4j.Slf4j;

@Slf4j
public class CustomPatternLayout extends PatternLayout {

    /**
     * 正则替换规则
     */
    private final LogbackReplaces replaces;


    public CustomPatternLayout(LogbackReplaces replaces) {
        super();
        this.replaces = replaces;
    }

    /**
     * 格式化日志信息
     *
     * @param event ILoggingEvent
     * @return 日志信息
     */
    @Override
    public String doLayout(ILoggingEvent event) {
        // 占位符填充
        String msg = super.doLayout(event);
        // 脱敏处理
        return this.buildSensitiveMsg(msg);
    }

    /**
     * 根据配置对日志进行脱敏
     *
     * @param msg 消息
     * @return 脱敏后的日志信息
     */
    public String buildSensitiveMsg(String msg) {
        if (this.replaces == null || this.replaces.getReplace() == null || this.replaces.getReplace().isEmpty()) {
            log.error("日志脱敏开启,但未配置脱敏规则,请检查配置后重试");
            return msg;
        }

        String sensitiveMsg = msg;

        for (RegexReplacement replace : this.replaces.getReplace()) {
            // 遍历脱敏正则 & 替换敏感数据
            sensitiveMsg = replace.format(sensitiveMsg);
        }
        return sensitiveMsg;
    }
}

RegexReplacement.java


import java.util.regex.Pattern;

public class RegexReplacement {

    /**
     * 脱敏匹配正则
     */
    private Pattern regex;

    /**
     * 替换正则
     */
    private String replacement;

    /**
     * Perform the replacement.
     *
     * @param msg The String to match against.
     * @return the replacement String.
     */
    public String format(final String msg) {
        return regex.matcher(msg).replaceAll(replacement);
    }

    public Pattern getRegex() {
        return regex;
    }

    public void setRegex(String regex) {
        this.regex = Pattern.compile(regex);
    }

    public String getReplacement() {
        return replacement;
    }

    public void setReplacement(String replacement) {
        this.replacement = replacement;
    }
}

LogbackReplaces.java


import java.util.ArrayList;
import java.util.List;

public class LogbackReplaces {

    /**
     * 脱敏正则列表
     */
    private List<RegexReplacement> replace = new ArrayList<>();

    /**
     * 添加规则(因为replace类型是list,必须指定addReplace方法用以添加多个)
     *
     * @param replacement replacement
     */
    public void addReplace(RegexReplacement replacement) {
        replace.add(replacement);
    }

    public List<RegexReplacement> getReplace() {
        return replace;
    }

    public void setReplace(List<RegexReplacement> replace) {
        this.replace = replace;
    }
}

配置文件logback.xml配置

<?xml version="1.0" encoding="UTF-8"?>
<configuration scan="true" scanPeriod="6000">
    <!--输出到控制台-->
    <appender name="console" class="ch.qos.logback.core.ConsoleAppender">
        <encoder class="CustomLogbackPatternLayoutEncoder类路径">
            <Pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%t][%p][%c][%M][%L]-> [%m]%n</Pattern>
            <!-- 脱敏规则列表 -->
            <replaces>
                <!-- 脱敏规则 -->
                <replace>
                    <!-- 邮箱,保留@前的前1后1 -->
                    <regex>
                        <![CDATA[
							(\w+)([-+.]\w+)@(\w+([-.]\w+)).(\w+([-.]\w+)*)
							]]>
                    </regex>
                    <replacement>$1****@$3.$4</replacement>
                </replace>

                <replace>
                    <!-- 11位的手机号:保留前3后4 -->
                    <regex>
                        <![CDATA[(1)([3-9])(\d)(\d{4})(\d{4})]]>
                    </regex>
                    <replacement>$1$2$3****$5</replacement>
                </replace>

                <replace>
                    <!-- 固定电话: XXXX-XXXXXXXX或XXX-XXXXXXXX,保留区号+前2后2 -->
                    <regex>
                        <![CDATA[([\d]{3,4}-)(\d{2})(\d{4})(\d{2})]]>
                    </regex>
                    <replacement>$1$2****$4</replacement>
                </replace>

                <replace>
                    <!-- security自带测试密码-->
                    <regex>
                        <![CDATA[.*(Using generated security).*]]>
                    </regex>
                    <replacement></replacement>
                </replace>

                <replace>
                    <!--ip -->
                    <regex>
                        <![CDATA[(?<![0-9])(?:(?:[0-1]?[0-9]{1,2}|2[0-4][0-9]|25[0-5])\.){3}(?:[0-1]?[0-9]{1,2}|2[0-4][0-9]|25[0-5])(?![0-9])]]>
                    </regex>
                    <replacement>***</replacement>
                </replace>
            </replaces>
        </encoder>
    </appender>

    <!-- 按照每天生成日志文件 -->
    <appender name="file" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
            <FileNamePattern>
                ${user.home}/logs/admin/app.%d{yyyy-MM-dd}-%i.log
            </FileNamePattern>
            <MaxHistory>15</MaxHistory>
            <!--日志文件最大的大小-->
            <MaxFileSize>100MB</MaxFileSize>
            <totalSizeCap>5GB</totalSizeCap>
        </rollingPolicy>


        <encoder class="CustomLogbackPatternLayoutEncoder类路径">
            <!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度%msg:日志消息,%n是换行符-->
            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>
            <replaces>
                <replace>
                    <!-- 邮箱,保留@前的前1后1 -->
                    <regex>
                        <![CDATA[
							(\w+)([-+.]\w+)@(\w+([-.]\w+)).(\w+([-.]\w+)*)
							]]>
                    </regex>
                    <replacement>$1****@$3.$4</replacement>
                </replace>

                <replace>
                    <!-- 11位的手机号:保留前3后4 -->
                    <regex>
                        <![CDATA[(1)([3-9])(\d)(\d{4})(\d{4})]]>
                    </regex>
                    <replacement>$1$2$3****$5</replacement>
                </replace>

                <replace>
                    <!-- 固定电话: XXXX-XXXXXXXX或XXX-XXXXXXXX,保留区号+前2后2 -->
                    <regex>
                        <![CDATA[([\d]{3,4}-)(\d{2})(\d{4})(\d{2})]]>
                    </regex>
                    <replacement>$1$2****$4</replacement>
                </replace>

                <replace>
                    <!-- security自带测试密码-->
                    <regex>
                        <![CDATA[.*(Using generated security).*]]>
                    </regex>
                    <replacement></replacement>
                </replace>

                <replace>
                    <!--ip -->
                    <regex>
                        <![CDATA[(?<![0-9])(?:(?:[0-1]?[0-9]{1,2}|2[0-4][0-9]|25[0-5])\.){3}(?:[0-1]?[0-9]{1,2}|2[0-4][0-9]|25[0-5])(?![0-9])]]>
                    </regex>
                    <replacement>***</replacement>
                </replace>
            </replaces>
        </encoder>
    </appender>


    <!--log4jdbc -->
    <logger name="org.apache.ibatis" level="debug"/>
    <logger name="java.sql" level="debug"/>

    <root level="info">
        <appender-ref ref="console"/>
        <appender-ref ref="file"/>
    </root>

</configuration>


网站公告

今日签到

点亮在社区的每一天
去签到