Home | RU | EN

Кастомный логгер фреймворка для IDE

Добавляем кастомный логгер, чтобы было удобно читать запросы-ответы и визуально отделять заголовки, тело метода и т.д. А не использовать дефолтные .addFilters(List.of( new RequestLoggingFilter(), new ResponseLoggingFilter()));

Реализация

В пакет common/loggers добавь класс CustomLoggingFilter со следующим содержимым:

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("ResponseBody:");
        System.out.println(response.getBody().asPrettyString());
        System.out.println("------------------------------");
        System.out.println();
        System.out.println();

        return response;
    }
}

Примеры использования

Далее его уже можно использовать в requestSpecification как фильтр:

1. В RequestSpecBuilder

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

2. В методе given()

given()
        .baseUri("https://restful-booker.herokuapp.com")
        .contentType(ContentType.JSON)
        .filters(List.of(new CustomLoggingFilter()))
        .body()
        // ... остальная часть запроса

Преимущества

Необходимые зависимости

Убедитесь, что у вас есть следующие зависимости в 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>

Результат

В результате чего лог в IDE будет выглядеть не так (дефолтное логирование) и так (с CustomLoggingFilter):

Дефолтное логирование

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"
    }
}
------------------------------

Разумеется можно попросить AI добавить доп элементы в логирование типа Cookies и так далее и сделать лог под себя