Log Incoming Requests In Spring

How to Log Incoming Requests In Spring

In this post, we will explore as of how to Log Incoming Requests In Spring. We will explore different options to accomplish it along with the build in feature provided by Spring.

 

1. Introduction

Having the ability to log incoming request in a web application is a very common requirement for modern web applications.In this article, we will be covering how to do it using Spring’s logging filter.

 

2. Dependency Management

In order to add required logging dependencies, we can add spring-core, for this article, we will be using Spring Boot which will handle dependency management for us. Checkout Building an Application with Spring Boot to learn about Spring Boot dependency management. We will add Spring Boot dependencies to start our web application.

<dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-web</artifactId>
</dependency>

 

3. Web Controller

In order to log incoming request, we need to have a Spring Controller in place, we will be using a simple controller for our post. Read  Creating a Web Application with Spring Boot to get an understanding of creating a web application using Spring Boot.

@RestController
public class LoggingDemoController {

    @GetMapping("/demo/greeting")
    public String sayHello(){
        return "Hello Stranger !!!";
    }
}

There is nothing special with this controller and it is simply returning "Hello Stranger !!! " to the client.

 

4. Custom Solutions

We will not get into details for this solution, but we can Spring provides interceptors to perform actions before and after web request.You can use HandlerInterceptor to create your custom implementation to log incoming request.

You have to be careful while using such approach as input stream will be marked as consumed the moment it is read for the first time.

We can also use Spring’s ContentCachingRequestWrapper to handle above issue by storing request stream in the cache but this needs a certain amount of work and customization.

 

5. Spring Built-In Request Logging

Spring comes with ready to use a feature which can log your request, all we are required to configure this ready to use solution. Spring comes with AbstractRequestLoggingFilter, that perform logging operations before and after a request is processed.

Before we get into implementation details, this filter requires a subclass to override the beforeRequest(HttpServletRequest, String) and afterRequest(HttpServletRequest, String) methods to perform the actual logging around the request.

Spring provides following 2 implementations for AbstractRequestLoggingFilter

  1. CommonsRequestLoggingFilter
  2. ServletContextRequestLoggingFilter

 

ServletContextRequestLoggingFilter Simple request logging filter that writes the request URI (and optionally the query string) to the ServletContext log.We are going to discuss CommonsRequestLoggingFilter in this post.

 

5.1 CommonsRequestLoggingFilter using Spring Boot

Spring Boot is the new way to create and run your Spring-powered applications, we can enable CommonsRequestLoggingFilter by simply registering it as a bean with our application.

@Bean
public CommonsRequestLoggingFilter requestLoggingFilter() {
    CommonsRequestLoggingFilter loggingFilter = new CommonsRequestLoggingFilter();
    loggingFilter.setIncludeClientInfo(true);
    loggingFilter.setIncludeQueryString(true);
    loggingFilter.setIncludePayload(true);
    loggingFilter.setIncludeHeaders(false);
    return loggingFilter;
}

In addition to above configuration, we need to make sure to set log level as DEBUG for CommonsRequestLoggingFilter either through application.properties or YAML

logging.level.org.springframework.web.filter.CommonsRequestLoggingFilter=DEBUG

Once these configurations are in place, you should be able to see a similar output in the console

2017-10-25 19:52:02.708 DEBUG 70034 --- [io-10070-exec-4] o.s.w.f.CommonsRequestLoggingFilter      : Before request [uri=/demo/greeting;client=0:0:0:0:0:0:0:1]
2017-10-25 19:52:02.791 DEBUG 70034 --- [io-10070-exec-4] o.s.w.f.CommonsRequestLoggingFilter      : After request [uri=/demo/greeting;client=0:0:0:0:0:0:0:1]

And voila, you have your requests are getting logged.

5.2 CommonsRequestLoggingFilter without Spring Boot

If you are not using Spring Boot, You can configure this by using traditional Filter.We have following options to configure this in our traditional web application

  1. Configure this Filter either through xml configuration or Java configuration with default values.
  2. Create a custom filter by extending CommonsRequestLoggingFilter to modify default behaviour.

 

5.2.1 CommonsRequestLoggingFilter using XML

If you want to use CommonsRequestLoggingFilter with no changes, you can simply configure it in your application configuration file as a filer

<filter>
    <filter-name>requestLoggingFilter</filter-name>
    <filter-class>org.springframework.web.filter.CommonsRequestLoggingFilter</filter-class>
    <init-param>
        <param-name>includeClientInfo</param-name>
        <param-value>true</param-value>
    </init-param>
    <init-param>
        <param-name>includePayload</param-name>
        <param-value>true</param-value>
    </init-param>
    <init-param>
        <param-name>includeQueryString</param-name>
        <param-value>true</param-value>
    </init-param>
</filter>
 
5.2.2 CommonsRequestLoggingFilter using Java Web Initializer

If you are not a fan of using XML configuration for your web application, Spring provides a way to configure it using WebApplicationInitializer.Please note that WebApplicationInitializer Interface to be implemented in Servlet 3.0+ environments in order to configure the ServletContext programmatically.

public class MyWebAppInitializer implements WebApplicationInitializer {

    @Override
    public void onStartup(ServletContext container) {
        XmlWebApplicationContext appContext = new XmlWebApplicationContext();
        appContext.setConfigLocation("/WEB-INF/spring/dispatcher-config.xml");

        ServletRegistration.Dynamic dispatcher =
                container.addServlet("dispatcher", new DispatcherServlet(appContext));
        dispatcher.setLoadOnStartup(1);
        dispatcher.addMapping("/");

        container.addFilter("requestLoggingFilter", CommonsRequestLoggingFilter.class)
                .addMappingForServletNames(null, false, "dispatcher");
    }

}
5.2.3 Custom CommonsRequestLoggingFilter

If you want to customize behaviour of CommonsRequestLoggingFilter, you can always create your custom Filter by extending CommonsRequestLoggingFilter

public class CustomeRequestLoggingFilter extends CommonsRequestLoggingFilter {

    // custom code
}

You can use any of the above options to configure your custom Filter.

 

Summary

In this post, we explore as of how to Log Incoming Request in Spring.Spring comes with many hidden features which can always help us to avoid writing custom/duplicate code and CommonsRequestLoggingFilter is one of such hidden gem in Spring.

JavaDevJournal

Hello!! I am Umesh- an engineer by profession and a photographer by passion.I like to build stuff on the web using OSS and love to capture the world through my lens.

Leave a Reply

Be the First to Comment!

Notify of
avatar
wpDiscuz