1

出于记录目的,我一直在从事的项目中使用了toString()杰克逊的方法,而不是使用方法。writeValueAsString(object)

LOGGER.info(mapper.writeValueAsString(object));

现在,我需要在日志中屏蔽密码和信用卡号等敏感信息。如果toString()正在使用,我可以从toString()方法中删除那些敏感数据。但就我而言,我找不到这样简单而正确的方法来解决我的问题。我无法改变整个使用的东西toString()

我读到,通过使用%replace方法,我可以使用预定义的模式替换不需要登录的数据。但是所有需要屏蔽的敏感数据都不会遵循单一模式。

我尝试通过拦截日志事件,查找特定信息并屏蔽它们(使用实现的类LogEventFactory)。尽管它是一个可行的解决方案,但我认为这不是一个好的解决方案,因为每次都在大字符串中查找数据是有代价的。

有没有什么我还没有遇到的方法来解决我的问题?方法%replace是要走的路吗?如果是这样,怎么做?

4

1 回答 1

0

我认为有三种方法可以解决你们都提到的问题。最有效的方法是防止将敏感数据记录到记录器中,这需要你做很多工作。

而第二种方式是修改Appender。通过扩展 log4j Appender,您可以修改 LogEvent。

最后一种方法是修改 PatternLayout。这是一个例子

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);
    }
}
于 2018-12-21T06:27:54.910 回答