出于日志记录的目的,不是使用toString()
方法,杰克逊的writeValueAsString(object)
方法已用于我一直在为之工作的项目中。
LOGGER.info(mapper.writeValueAsString(object));
现在,我要求屏蔽日志中的密码和信用卡号等敏感信息。如果正在使用toString()
,我可以从toString()
方法中删除这些敏感数据。但就我而言,我找不到解决问题的简单而正确的方法。我不会改变整个事情以使用toString()
。
我通过使用%replace
方法阅读,我可以使用预定义的模式替换我不需要登录的数据。但是,所有需要屏蔽的敏感数据都不会遵循单一模式。
我尝试拦截日志事件,查找特定信息并屏蔽它们(使用实现LogEventFactory
的类)。即使它是一个可行的解决方案,我也不认为这是一个很好的解决方案,因为每次查找大字符串的数据都会花费很多。
我还有什么方法可以解决我的问题吗?采用%replace
的方法是可行的吗?如果是这样,怎么样?
答案 0 :(得分:0)
我认为您可以通过三种方法来解决您的问题。最有效的方法是防止将对日志敏感的数据发送到记录器,这需要您做大量的工作。
第二种方法是修改Appender。通过扩展log4j Appenders,可以修改LogEvent。
最后一种方法是修改PatternLayout。这是example。
public class CardNumberFilteringLayout extends PatternLayout {
private static final String MASK = "$1++++++++++++";
private static final Pattern PATTERN = Pattern.compile("([0-9]{4})([0-9]{9,15})");
@Override
public String format(LoggingEvent event) {
if (event.getMessage() instanceof String) {
String message = event.getRenderedMessage();
Matcher matcher = PATTERN.matcher(message);
if (matcher.find()) {
String maskedMessage = matcher.replaceAll(MASK);
@SuppressWarnings({ "ThrowableResultOfMethodCallIgnored" })
Throwable throwable = event.getThrowableInformation() != null ?
event.getThrowableInformation().getThrowable() : null;
LoggingEvent maskedEvent = new LoggingEvent(event.fqnOfCategoryClass,
Logger.getLogger(event.getLoggerName()), event.timeStamp,
event.getLevel(), maskedMessage, throwable);
return super.format(maskedEvent);
}
}
return super.format(event);
}
}