Home | RU | EN

Custom Framework Logger for IDE

Adding a custom logger to make it convenient to read requests-responses and visually separate headers, method body, etc. Instead of using default .addFilters(List.of( new RequestLoggingFilter(), new ResponseLoggingFilter()));

Implementation

Add the CustomLoggingFilter class to the common/loggers package with the following content:

public class CustomLoggingFilter implements Filter {

    private final ObjectWriter prettyPrinter = new ObjectMapper().writerWithDefaultPrettyPrinter();

    @Override
    public Response filter(FilterableRequestSpecification requestSpec,
                           FilterableResponseSpecification responseSpec,
                           FilterContext ctx) {

        System.out.println("---------- REQUEST >>>>>>>>>>");
        System.out.println(requestSpec.getMethod() + " " + requestSpec.getURI());
        System.out.println();

        System.out.println("Request Headers:");
        requestSpec.getHeaders().forEach(header ->
                System.out.println(header.getName() + ": " + header.getValue())
        );

        if (requestSpec.getBody() != null) {
            System.out.println();
            System.out.println("Request Body:");
            try {
                String prettyBody = prettyPrinter.writeValueAsString(
                        new ObjectMapper().readTree(requestSpec.getBody().toString()));
                System.out.println(prettyBody);
            } catch (Exception e) {
                System.out.println("Raw body (could not format as JSON):\n" + requestSpec.getBody());
            }
        }


        Response response = ctx.next(requestSpec, responseSpec);

        System.out.println();
        System.out.println("<<<<<<<<<< RESPONSE ----------");
        System.out.println("Status Code: " + response.getStatusCode());
        System.out.println();

        System.out.println("Response Headers:");
        Headers responseHeaders = response.getHeaders();
        responseHeaders.forEach(header ->
                System.out.println(header.getName() + ": " + header.getValue())
        );
        System.out.println();
        System.out.println("Response Body:");
        System.out.println(response.getBody().asPrettyString());
        System.out.println("------------------------------");
        System.out.println();
        System.out.println();

        return response;
    }
}

Usage Examples

Then you can use it in requestSpecification as a filter:

1. In RequestSpecBuilder

private static RequestSpecBuilder defaultRequestSpecBuilder() {
    return new RequestSpecBuilder()
            .setBaseUri(Config.getProperty("apiBaseUrl"))
            .setContentType(ContentType.JSON)
            .setAccept(ContentType.JSON)
            .addFilters(List.of(new CustomLoggingFilter())); 
}

2. In given() method

given()
        .baseUri("https://restful-booker.herokuapp.com")
        .contentType(ContentType.JSON)
        .filters(List.of(new CustomLoggingFilter()))
        .body()
        // ... rest of the request

Benefits

Required Dependencies

Make sure you have the following dependencies in your pom.xml:

<dependency>
    <groupId>io.rest-assured</groupId>
    <artifactId>rest-assured</artifactId>
    <version>5.3.2</version>
</dependency>

<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-databind</artifactId>
    <version>2.15.2</version>
</dependency>

Result

As a result, the log in IDE will look not like this (default logging) and like this (with CustomLoggingFilter):

Default Logging

Request method:	POST
Request URI:	https://restful-booker.herokuapp.com/booking
Proxy:			<none>
Request params:	<none>
Query params:	<none>
Form params:	<none>
Path params:	<none>
Headers:		Accept=*/*
			Content-Type=application/json
Cookies:		<none>
Multiparts:		<none>
Body:
{
    "firstname": "Vasya",
    "lastname": "Pupkin",
    "totalprice": 1000,
    "depositpaid": true,
    "bookingdates": {
        "checkin": "2023-01-01",
        "checkout": "2024-01-01"
    },
    "additionalneeds": "Breakfast"
}
HTTP/1.1 200 OK
Content-Length: 201
Content-Type: application/json; charset=utf-8
Date: Tue, 14 Oct 2025 19:57:39 GMT
Etag: W/"c9-MmRgxFHC82j44Z0wVuen81mDM4g"
Nel: {"report_to":"heroku-nel"...}
Report-To: {"group":"heroku-nel"...}
Reporting-Endpoints: heroku-nel="https://nel.heroku.com/..."
Server: Heroku
Via: 1.1 heroku-router
X-Powered-By: Express

{
    "bookingid": 3709,
    "booking": {
        "firstname": "Vasya",
        "lastname": "Pupkin",
        "totalprice": 1000,
        "depositpaid": true,
        "bookingdates": {
            "checkin": "2023-01-01",
            "checkout": "2024-01-01"
        },
        "additionalneeds": "Breakfast"
    }
}

CustomLoggingFilter

---------- REQUEST >>>>>>>>>>
POST https://restful-booker.herokuapp.com/booking

Request Headers:
Accept: */*
Content-Type: application/json

Request Body:
{
  "firstname" : "Vasya",
  "lastname" : "Pupkin",
  "totalprice" : 1000,
  "depositpaid" : true,
  "bookingdates" : {
    "checkin" : "2023-01-01",
    "checkout" : "2024-01-01"
  },
  "additionalneeds" : "Breakfast"
}

<<<<<<<< RESPONSE ----------
Status Code: 200

Response Headers:
Content-Length: 201
Content-Type: application/json; charset=utf-8
Date: Tue, 14 Oct 2025 20:04:35 GMT
Etag: W/"c9-FuOr6xR9Pvkbr3f8jfaOmAWNlz4"
Nel: {"report_to":"heroku-nel"...}
Report-To: {"group":"heroku-nel"...}
Reporting-Endpoints: heroku-nel="https://nel.heroku.com/..."
Server: Heroku
Via: 1.1 heroku-router
X-Powered-By: Express

Response Body:
{
    "bookingid": 1846,
    "booking": {
        "firstname": "Vasya",
        "lastname": "Pupkin",
        "totalprice": 1000,
        "depositpaid": true,
        "bookingdates": {
            "checkin": "2023-01-01",
            "checkout": "2024-01-01"
        },
        "additionalneeds": "Breakfast"
    }
}
------------------------------

Of course, you can ask AI to add additional elements to logging like Cookies and so on and customize the log for yourself