工具类
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>