Log request and responses of REST APIs in SpringBoot

Ankitha Gowda
3 min readApr 16, 2022

--

Photo by Scott Graham on Unsplash

Today we will see a way to log requests and responses of APIs without inserting logger messages in each controller method of a SpringBoot application. This helps to reduce the overhead of adding logs manually and helps to achieve a cleaner code.

To enable logging, we need to catch each request before its corresponding controller is called, get all required details and print them. Similarly, once the API response is ready, catch all the details to print and send back a response to the client.

We need to implement WebMvcConfigurer and override addInterceptors method by adding interceptors to InterceptorRegistry.

  1. To log API requests:

As you might know, HTTP methods GET, DELETE and sometimes PUT methods will not have a payload in API requests. For such cases we need to implement HandlerInterceptor and override preHandle method as below:

For APIs requests with payload, we need to extend RequestBodyAdviceAdapter providing the implementation for abstract methods and afterBodyRead() as below:

2. To log API responses:

ResponseBodyAdvice allows customizing the response after the execution of an @ResponseBody or a ResponseEntity controller method but before the body is written with an HttpMessageConverter. So we can implement this interface to get a hold of the response of each APIs as below:

Note: Both RequestBodyAdvice and ResponseBodyAdvice implementations are annotated with @ControllerAdviceso that they wil be auto-detected by RequestMappingHandlerAdapter or ExceptionHandlerExceptionResolver

In all the above classes, we will be getting the request or responses of APIs. To log them in the required format we could have a service taking requests, responses and body as inputs:

Implementation:

For all API calls, the logs will be printed as below:

2022-04-16 09:22:31.591  INFO 5348 --- [nio-8080-exec-1] LoggingServiceImpl                       : log Request: REQUEST method = [GET] path = [/students] 
2022-04-16 09:22:31.687 INFO 5348 --- [nio-8080-exec-1] LoggingServiceImpl : logResponse: RESPONSE method = [GET] responseBody = [[]]
2022-04-16 09:22:45.120 INFO 5348 --- [nio-8080-exec-3] LoggingServiceImpl : log Request: REQUEST method = [POST] path = [/students] body = [Student{Id=null, studentName='Vinay', studentAge='26', address='Bangalore'}]
Student:Student{Id=null, studentName='Vinay', studentAge='26', address='Bangalore'}
2022-04-16 09:22:45.168 INFO 5348 --- [nio-8080-exec-3] LoggingServiceImpl : logResponse: RESPONSE method = [POST] responseBody = [Student{Id=1, studentName='Vinay', studentAge='26', address='Bangalore'}]
2022-04-16 09:22:59.012 INFO 5348 --- [nio-8080-exec-4] LoggingServiceImpl : log Request: REQUEST method = [GET] path = [/students]
2022-04-16 09:22:59.035 INFO 5348 --- [nio-8080-exec-4] LoggingServiceImpl : logResponse: RESPONSE method = [GET] responseBody = [[Student{Id=1, studentName='Vinay', studentAge='26', address='Bangalore'}]]
2022-04-16 09:23:08.618 INFO 5348 --- [nio-8080-exec-5] LoggingServiceImpl : log Request: REQUEST method = [PUT] path = [/students] parameters = [{Address=Mumbai, Id=1}]
2022-04-16 09:23:08.659 INFO 5348 --- [nio-8080-exec-5] LoggingServiceImpl : logResponse: RESPONSE method = [PUT] responseBody = [Student{Id=1, studentName='Vinay', studentAge='26', address='Mumbai'}]
2022-04-16 09:23:20.051 INFO 5348 --- [nio-8080-exec-6] LoggingServiceImpl : log Request: REQUEST method = [DELETE] path = [/students] parameters = [{Id=1}]
2022-04-16 09:23:20.074 INFO 5348 --- [nio-8080-exec-6] LoggingServiceImpl : logResponse: RESPONSE method = [DELETE] responseBody = [null]

The complete code can be found on Github here. For the above functionality, you just need its custom.models package.

Thank you for reading. Happy exploring!!!

--

--