在序列化期间省略特定Gson序列化程序的字段

时间:2016-11-18 13:49:31

标签: log4j gson logstash slf4j log4j2

我在Spring Boot 1.4.2上有一个无状态REST API构建。我想将所有API调用记录到elk中。还需要记录请求和响应数据(标头,参数,有效负载)。我不想以1:1的方式记录它们 - 我想过滤掉敏感数据等。

我做了一个截取我的@RestController方法调用的方面。我为this文章后面应该记录的方法参数(我在@RequestBody注释的有效负载上使用它)创建了自定义注释,它让我可以访问我的数据传输对象@Around建议。我不关心他们的类型 - 我想调用logger.debug(logObject)并将此日志发送到logstash。

据我所知,日志消息应该作为JSON发送,并在Log4j2 appender中设置JSONLayout以缓解logstash端的内容。所以我将logObject序列化为JSON日志消息,但在此过程中,这只是序列化,我想过滤掉敏感数据。我无法使用transient,因为我的控制器依赖于相同的字段。

我可以以某种方式创建一个@IgnoreForLogging注释,只能由我在日志记录建议中使用的自定义Gson序列化程序检测到,并且在标准Spring的基础结构中会被忽略吗?我登录logstash的方法是否正确(我试图第一次设置它)?

1 个答案:

答案 0 :(得分:1)

我无法相信我在文档中错过了它。 Here是链接

我的自定义注释:

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface IgnoreForLogging {
}

序列化对象的策略:

public class LoggingExclusionStrategy implements ExclusionStrategy {
    @Override
    public boolean shouldSkipField(FieldAttributes fieldAttributes) {
        return fieldAttributes.getAnnotation(IgnoreForLogging.class) != null;
    }

    @Override
    public boolean shouldSkipClass(Class<?> aClass) {
        return false;
    }
}

在方面类中序列化日志消息:

Gson gson = new GsonBuilder()
            .setExclusionStrategies(new LoggingExclusionStrategy())
            .create();
String json = gson.toJson(logObject);

这样Spring在内部使用了不知道@IgnoreForLogging的默认序列化程序,我可以在其他地方利用我的注释。