- 在项目上线环境中,需要记录程序运行时产生的各种错误信息、状态信息、调试信息、执行时间记录等日志信息。可以用于查找问题、定位数据等等操作。
- 日志的具体实现可以有log4j和logback等,这里我们使用SLF4J作为日志系统的实现。
- 使用idea工具可以安装lombok插件,并引入maven包:
org.projectlombok lombok1.18.4
- 在需要打印日志的类上增加@Slf4j注解,如果查看编译后的class文件,就会发现注解@Slf4j会编码成下列代码:
public static final Logger log = LoggerFactory.getLogger(TestLog.class);
- 打印日志时使用下列方式打印信息即可:
@Slf4j
public class TestLog {
//public static final Logger log = LoggerFactory.getLogger(TestLog.class);
public static void main (String[] args) {
Map params = new HashMap<>();
params.put("Phones", "13668200646,15222222222,15648523699");
params.put("timestamp", "1231");
params.put("NAME", "张三");
params.put("身份证", "150303195208077885,15030319520807158X,15030319520807908X");
String phone = "15236547789";
log.info(phone);
log.info("测试日志电话:{}", phone);
log.info("测试日志json对象:{}", JSONObject.toJSonString(params));
}
}
------------------
打印结果如下:
15236547789
测试日志电话:15236547789
测试日志json对象:{"Phones":"13668200646,15222222222,15648523699","身份证":"150303195208077885,15030319520807158X,15030319520807908X","timestamp":"1231","NAME":"张三"}
脱敏操作
-
这里可以发现,打印的日志把完整的手机号也打印出来了,如果有一些客户敏感信息,如身份证、手机号、银行卡等等信息,是需要进行脱敏的,
-
特别是如果线上日志是对接了第三方日志系统(如阿里云SLS日志服务等),之前就有用户数据信息没有经过日志脱敏就直接打印输出,导致数据泄漏引发一系列问题 -_-
-
首先需要自定义实现消息脱敏类SensitiveLogDataConverter并继承MessageConverter类,由logback提供的一个日志消息转化超类。代码如下:
public final class SensitiveLogDataConverter extends MessageConverter {
private static Pattern bankCardPattern = Pattern.compile("(D)([3-6]d{3})(d{8,12})(d{4})(D)");
private static Pattern namePattern = Pattern.compile("([^u4e00-u9fa5])([u4e00-u9fa5])([u4e00-u9fa5]{1,3})([^u4e00-u9fa5])");
private final static Pattern PHONE_PATTERN = Pattern.compile("(? list;
String logMsg = event.getFormattedMessage();
if (!(list = validateIdCard(logMsg)).isEmpty()) {
for (String param : list) {
logMsg = logMsg.replaceAll(param, SensitiveInfoUtil.desensitizePhoneOrIdCard(param));
}
}
return logMsg;
} catch (Exception e) {
}
return super.convert(event);
}
private static Set validateIdCard (String param) {
Set set = new HashSet<>();
// 匹配手机号
Matcher phoneMatcher = PHONE_PATTERN.matcher(param);
while (phoneMatcher.find()) {
set.add(phoneMatcher.group());
}
// 匹配身份证
Matcher idCardMatcher = ID_CARD_PATTERN.matcher(param);
while (idCardMatcher.find()) {
set.add(idCardMatcher.group());
}
return set;
}
}
- 然后还需要配置一个自定义日志打印格式文件logback.xml
logback %d{HH:mm:ss.SSS} %contextName [%thread] %-5level %logger{36} - %msg%n UTF-8 ${log.path} ${log.path}.%d{yyyy-MM-dd}.zip %date %level [%thread] %logger{36} [%file : %line] %msg%n UTF-8
- 还是刚才的示例,查看最终的执行效果:
@Slf4j
public class TestLog {
//public static final Logger log = LoggerFactory.getLogger(TestLog.class);
public static void main (String[] args) {
Map params = new HashMap<>();
params.put("Phones", "13668200646,15222222222,15648523699");
params.put("timestamp", "1231");
params.put("NAME", "张三");
params.put("身份证", "150303195208077885,15030319520807158X,15030319520807908X");
String phone = "15236547789";
log.info(phone);
log.info("测试日志电话:{}", phone);
log.info("测试日志json对象:{}", JSONObject.toJSonString(params));
}
}
------------------
打印结果如下:
152****7789
测试日志电话:152****7789
测试日志json对象:{"Phones":"136****0646,152****2222,156****3699","身份证":"150***********7885,150***********158X,150***********908X","timestamp":"1231","NAME":"张三"}
最后
- 虚心学习,共同进步 -_-



