logback-defender实现日志脱敏
Posted justry_deng
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了logback-defender实现日志脱敏相关的知识,希望对你有一定的参考价值。
logback-defender
介绍
logback-defender是一款基于logback实现的无侵入的日志脱敏工具框架,使用此框架,只需要简单的三步。
功能特性
- (默认提供)支持json脱敏器
- (默认提供)支持string脱敏器
- (默认提供)支持正则脱敏器
- 支持自定义脱敏器
- 支持通过插件实现局部自定义脱敏器(即:轻量的自定义脱敏器)
前置依赖
- jdk8+
- logback
- spring-boot
使用步骤
- 引入依赖。
<dependency> <groupId>com.idea-aedi</groupId> <artifactId>logback-defender</artifactId> <version>${version}</version> </dependency>
- 配置application.yml。
提示:这里只给出了最简单的配置示例,更灵活的用法、更多配置示例,详见下方脱敏配置说明。log: defender: enable: true # 启用logback-defender include-logger-prefix: com.ideaaedi.logback # 通过logger所属类的全类名前缀,指定脱敏范围(,多个实用逗号分割) opt: default_json # 指定脱敏器 config-json: strategies: # 指定脱敏策略 com.ideaaedi.logback.defender.strategy.SimpleDefenderStrategy__ACCOUNT_NO: account,accountNo com.ideaaedi.logback.defender.strategy.SimpleDefenderStrategy__EMAIL: email,mail,emailList com.ideaaedi.logback.defender.strategy.SimpleDefenderStrategy__PHONE_NUMBER: phone,mobile,telphone
- 在logback配置文件(如:logback.xml)中,指定使用logback-defender转换器。示例如下:
<?xml version="1.0" encoding="UTF-8"?> <configuration scan="true"> <property name="logFilePositionDir" value="log"/> <property name="logFileName" value="log"/> <!-- 提示一: conversionWord的值对应占位符。 这里即: 对【%msg】代表的内容,使用converterClass进行消息转换。 提示二: conversionRule标签的配置,最好不要太靠下, 否则conversionRule标签可能不会生效。 --> <conversionRule conversionWord="msg" converterClass="com.ideaaedi.logback.defender.core.LogbackCoreConverter"/> <appender name="consoleAppender" class="ch.qos.logback.core.ConsoleAppender"> ...... </appender> ...... </configuration>
脱敏配置说明
json脱敏器
-
全量配置及说明
################################# 说明 ################################# # 1.下述为全量配置示例说明,使用时按需配置即可 # ####################################################################### log: defender: enable: true # 启用脱敏器 debug: true # 开启调试模式,(当脱敏器本身出现异常时,)以便打印错误日志 include-logger-prefix: com.ideaaedi.logback.defender,aaa,bbb,ccc # 通过(logger所属类的全类名)前缀,定位要脱敏的日志 exclude-logger-prefix: TmpApplication,xxx,yyy,zzz # 通过(logger所属类的全类名)前缀,指定不需要脱敏的日志 opt: default_json # 脱敏模型,支持 default_json-基于json脱敏、default_string-基于字符串脱敏、default_regex-基于正则脱敏、custom-自定义脱敏器脱敏 config-json: # 当基于default_json脱敏时,需配置strategies hit-string-value-is-json: true # 当k-v中v本身是字符串,但是长json样时,是否继续对长json样的字符串进行脱敏 strategies: # 指定脱敏类别及该类别下的keys # 指定脱敏类别的方式,方式一[对枚举值]: {实现了DefenderStrategy接口的枚举类全类名}__{枚举item} com.ideaaedi.logback.defender.strategy.SimpleDefenderStrategy__ACCOUNT_NO: account,accountNo com.ideaaedi.logback.defender.strategy.SimpleDefenderStrategy__EMAIL: email,mail,emailList com.ideaaedi.logback.defender.strategy.SimpleDefenderStrategy__PHONE_NUMBER: phone,mobile,telphone # 指定脱敏类别的方式,方式二[对注册到spring中的bean]: {实现了DefenderStrategy并且注册到spring容器中的bean的name} demoDefenderStrategy: name,chineseName,englishName # 短路插件机制:支持对部分日志定制化脱敏 # 注: 比起自定义脱敏器,插件更轻量化 # 注:若日志脱敏走了插件,那么是不会再走脱敏器的(详见AbstractLogbackMessageDefender#desensitize) short-circuit-plugins: pluginOne,pluginTwo #值为 {实现了LogbackMessageDefender并且注册到spring容器中的bean的name}
-
其中,枚举策略实现示例:
public enum SimpleDefenderStrategy implements DefenderStrategy { /** 姓名类脱敏策略 */ NAME("name", 1, 1, '*'), /** 账号类脱敏策略 */ ACCOUNT_NO("accountNo", 2, 2, '*'), /** 邮箱类脱敏策略 */ EMAIL("email", 2, 7, '*'), /** 身份证号类脱敏策略 */ ID_CARD("idCard", 6, 4, '*'), /** 手机号码类脱敏策略 */ PHONE_NUMBER("phoneNumber", 3, 4, '*'), /** 住址类脱敏策略 */ ADDRESS("address", 3, 4, '*'); // 省略... }
-
其中,自定义脱敏策略demoDefenderStrategy的实现示例:
@Component("demoDefenderStrategy") public class DemoDefenderStrategy implements DefenderStrategy{ @Override public String category() { return "name"; } @Override public int retainPrefixCount() { return 1; } @Override public int retainSuffixCount() { return 1; } @Override public char replaceChar() { return '$'; } }
-
其中,插件pluginOne实现示例:
@Component public class PluginOne implements LogbackMessageDefender { public static final String HANDLE_BY_PLUGIN = "PluginOneAbc"; @Override public boolean support(ILoggingEvent event) { return event.getMDCPropertyMap().containsKey(HANDLE_BY_PLUGIN); } @Override public void desensitize(ILoggingEvent event, String message, StringBuilder buffer) { buffer.append("[O_O] ").append(event.getFormattedMessage()).append(" [O_O]"); } }
string脱敏器
- 全量配置及说明
################################# 说明 ################################# # 1.下述为全量配置示例说明,使用时按需配置即可 # ####################################################################### log: defender: enable: true # 启用脱敏器 debug: true # 开启调试模式,(当脱敏器本身出现异常时,)以便打印错误日志 include-logger-prefix: com.ideaaedi.logback.defender,aaa,bbb,ccc # 通过(logger所属类的全类名)前缀,定位要脱敏的日志 exclude-logger-prefix: TmpApplication,xxx,yyy,zzz # 通过(logger所属类的全类名)前缀,指定不需要脱敏的日志 opt: default_string # 脱敏模型,支持 default_json-基于json脱敏、default_string-基于字符串脱敏、default_regex-基于正则脱敏、custom-自定义脱敏器脱敏 config-string: # 当基于default_STRING脱敏时,需配置strategies compat-backslash: true # 是否兼容反斜杠 \\ strategies: # 指定脱敏类别及该类别下的keys # 指定脱敏类别的方式,方式一[对枚举值]: {实现了DefenderStrategy接口的枚举类全类名}__{枚举item} com.ideaaedi.logback.defender.strategy.SimpleDefenderStrategy__ACCOUNT_NO: account,accountNo com.ideaaedi.logback.defender.strategy.SimpleDefenderStrategy__EMAIL: email,mail,emailList com.ideaaedi.logback.defender.strategy.SimpleDefenderStrategy__PHONE_NUMBER: phone,mobile,telphone # 指定脱敏类别的方式,方式二[对注册到spring中的bean]: {实现了DefenderStrategy并且注册到spring容器中的bean的name} demoDefenderStrategy: name,chineseName,englishName # 短路插件机制:支持对部分日志定制化脱敏 # 注: 比起自定义脱敏器,插件更轻量化 # 注:若日志脱敏走了插件,那么是不会再走脱敏器的(详见AbstractLogbackMessageDefender#desensitize) short-circuit-plugins: pluginOne,pluginTwo #值为 {实现了LogbackMessageDefender并且注册到spring容器中的bean的name} key-value-delimiter: COLON,EQUAL,ARROW # 指定key-value之间的连接符 可以从(:、=、->)这三个中选
- 其中,枚举策略实现示例:同json脱敏器中的示例。
- 其中,自定义脱敏策略demoDefenderStrategy的实现示例:同json脱敏器中的示例。
- 其中,插件pluginOne实现示例:同json脱敏器中的示例。
正则脱敏器
-
全量配置及说明
################################# 说明 ################################# # 1.下述为全量配置示例说明,使用时按需配置即可 # ####################################################################### log: defender: enable: true # 启用脱敏器 debug: true # 开启调试模式,(当脱敏器本身出现异常时,)以便打印错误日志 include-logger-prefix: com.ideaaedi.logback.defender,aaa,bbb,ccc # 通过(logger所属类的全类名)前缀,定位要脱敏的日志 exclude-logger-prefix: xxx,yyy,zzz # 通过(logger所属类的全类名)前缀,指定不需要脱敏的日志 opt: default_regex # 脱敏模型,支持 default_json-基于json脱敏、default_string-基于字符串脱敏、default_regex-基于正则脱敏、custom-自定义脱敏器脱敏 config-regex: strategyProvider: demoPatternStrategyProvider #值为 {实现了RegexDefenderStrategyProvider并且注册到spring容器中的bean的name} short-circuit-plugins: pluginOne,pluginTwo #值为 {实现了LogbackMessageDefender并且注册到spring容器中的bean的name}
-
其中,strategyProvider的实现示例:
@Component public class DemoPatternStrategyProvider implements RegexDefenderStrategyProvider { private static final Pattern ACCOUNT_PATTERN = Pattern.compile("account\\\\s*=\\\\s*[a-zA-Z0-9\\u4e00-\\u9fa5!@#$+%^&*(){}|:\\"?.<>/'\\\\\\\\\\\\-_`。;!]*"); private static final Pattern EMAIL_PATTERN = Pattern.compile("mail\\\\s*=\\\\s*[a-zA-Z0-9\\u4e00-\\u9fa5!@#$+%^&*(){}|:\\"?.<>/'\\\\\\\\\\\\-_`。;!]*"); private static final Pattern NAME_PATTERN = Pattern.compile("name\\\\s*=\\\\s*[a-zA-Z0-9\\u4e00-\\u9fa5!@#$+%^&*()|:\\"?.<>/'\\\\\\\\\\\\-_`。;!]*"); @Override public Map<Pattern, DefenderStrategy> provideRegexStrategyMap() { Map<Pattern, DefenderStrategy> map = new HashMap<>(8); map.put(ACCOUNT_PATTERN, SimpleDefenderStrategy.ACCOUNT_NO); map.put(EMAIL_PATTERN, SimpleDefenderStrategy.EMAIL); map.put(NAME_PATTERN, SimpleDefenderStrategy.NAME); return map; } }
自定义脱敏器
-
全量配置及说明
################################# 说明 ################################# # 1.下述为全量配置示例说明,使用时按需配置即可 # ####################################################################### log: defender: enable: true # 启用脱敏器 debug: true # 开启调试模式,(当脱敏器本身出现异常时,)以便打印错误日志 include-logger-prefix: com.ideaaedi.logback.defender,aaa,bbb,ccc # 通过(logger所属类的全类名)前缀,定位要脱敏的日志 exclude-logger-prefix: xxx,yyy,zzz # 通过(logger所属类的全类名)前缀,指定不需要脱敏的日志 opt: custom # 脱敏模型,支持 default_json-基于json脱敏、default_string-基于字符串脱敏、default_regex-基于正则脱敏、custom-自定义脱敏器脱敏 config-custom: bean: myLogbackMessageDefender #值为 {实现了LogbackMessageDefender并且注册到spring容器中的bean的name}
-
其中,bean的实现示例:
@Component public class MyLogbackMessageDefender implements LogbackMessageDefender { @Override public boolean support(ILoggingEvent event) { return true; } @Override public void desensitize(ILoggingEvent event, String message, StringBuilder buffer) { String formattedMessage = event.getFormattedMessage(); List<Character> list = new ArrayList<>(12); char[] chars = formattedMessage.toCharArray(); for (char c : chars) { list.add(c); } Collections.shuffle(list); for (int i = 0; i < list.size(); i++) { chars[i] = list.get(i); } buffer.append(new String(chars)); } }
以上是关于logback-defender实现日志脱敏的主要内容,如果未能解决你的问题,请参考以下文章
java 日志脱敏框架 sensitive-新版本0.0.2-深度拷贝,属性为对象和集合的支持