Home > front end >  How to exclude a specific property or data type from log request in logbook?
How to exclude a specific property or data type from log request in logbook?

Time:10-18

I have a spring boot project and using logbook library for logging requests and responses. In one of the REST API services, One of the properties data type is byte[], So when the client sends the request, because of that data type it prints a lot of log in the console and that is not what I wanted.

I have seen in the document that you can exclude some path or content type, but not by name or data types.

Here how document suggest for configuration:

Logbook logbook = Logbook.builder()
    .condition(exclude(
        requestTo("/health"),
        requestTo("/admin/**"),
        contentType("application/octet-stream"),
        header("X-Secret", newHashSet("1", "true")::contains)))
    .build();

CodePudding user response:

You can use BodyReplacer(s) as RequestFilter(s) to obfuscate your body content when configuring the Logbook instance.

Binary data

For binary data, i.e. when the HTTP Content-Type is one of the following:

  • application/octet-stream
  • application/pdf
  • audio/*
  • image/*
  • video/*

You can use the BodyReplacers#binary replacer as follows:

Logbook logbook = Logbook.builder()
    .requestFilter(RequestFilters.replaceBody(BodyReplacers.binary())) // which will replace body content with `<binary>` string in all incoming HTTP requests
    .responseFilter(ResponseFilters.replaceBody(BodyReplacers.binary())) // does the same when logging HTTP responses
    // other configuration properties
    .build();

Multipart data

When the HTTP Content-Type is of type:

  • multipart/*

You can use the BodyReplacers#multipart replacer as follows:

Logbook logbook = Logbook.builder()
    .requestFilter(RequestFilters.replaceBody(BodyReplacers.multipart())) // which will replace body content with `<multipart>` string in all incoming HTTP requests
    .responseFilter(ResponseFilters.replaceBody(BodyReplacers.multipart())) // does the same when logging HTTP responses
    // other configuration properties
    .build();

Streamed content data

When the data is a stream of chunks, i.e. the HTTP Content-Type is one of the following types:

  • application/json-seq
  • application/x-json-stream
  • application/stream json
  • text/event-stream

You can use the BodyReplaces#stream replacer as follows:

Logbook logbook = Logbook.builder()
    .requestFilter(RequestFilters.replaceBody(BodyReplacers.stream())) // which will replace body content with `<stream>` string in all incoming HTTP requests
    .responseFilter(ResponseFilters.replaceBody(BodyReplacers.stream())) // does the same when logging HTTP responses
    // other configuration properties
    .build();

CodePudding user response:

The tmarwen answer is good, but I suppose you want to ignore just specific properties or data types and not an HTTP content type. In case that is true, Then you can do as following to ignore specific property by name :

.bodyFilter(jsonPath("$.YourSpecificPropertyName").delete())

Or

.bodyFilter(jsonPath("$.YourSpecificPropertyName").replace("ReplaceMessage"))

Here is a full example from the documentation :

Suppose you have a request like :

{
  "id": 1,
  "name": "Alice",
  "password": "s3cr3t",
  "active": true,
  "address": "Anhalter Straße 17 13, 67278 Bockenheim an der Weinstraße",
  "friends": [
    {
      "id": 2,
      "name": "Bob"
    },
    {
      "id": 3,
      "name": "Charlie"
    }
  ],
  "grades": {
    "Math": 1.0,
    "English": 2.2,
    "Science": 1.9,
    "PE": 4.0
  }
}

By applying these configurations :

Logbook logbook = Logbook.builder()
        .bodyFilter(jsonPath("$.password").delete())
        .bodyFilter(jsonPath("$.active").replace("unknown"))
        .bodyFilter(jsonPath("$.address").replace("X"))
        .bodyFilter(jsonPath("$.name").replace(compile("^(\\w). "), "$1."))
        .bodyFilter(jsonPath("$.friends.*.name").replace(compile("^(\\w). "), "$1."))
        .bodyFilter(jsonPath("$.grades.*").replace(1.0))
        .build();

Turn into :

{
  "id": 1,
  "name": "Alice",
  "active": "unknown",
  "address": "XXX",
  "friends": [
    {
      "id": 2,
      "name": "B."
    },
    {
      "id": 3,
      "name": "C."
    }
  ],
  "grades": {
    "Math": 1.0,
    "English": 1.0,
    "Science": 1.0,
    "PE": 1.0
  }
}
  • Related