|
| 1 | +# How to log every Request in SpringBoot |
| 2 | + |
| 3 | +## Prerequesites |
| 4 | + |
| 5 | +Imagine we have an web SpringBoot application containing a [Controller](./src/main/java/com/bvn13/example/springboot/springrequestlogger/controllers/FirstController.java). |
| 6 | +It returns a template [index](/src/main/resources/templates/index.html) containing two links: on [css file](./src/main/resources/static/test.css) and on [js file](./src/main/resources/static/test.js). |
| 7 | + |
| 8 | +So we want to log every request from client while opening `index.html`: |
| 9 | +1. `index.html` |
| 10 | +2. `test.css` |
| 11 | +3. `test.js` |
| 12 | + |
| 13 | +## Enabling logging |
| 14 | + |
| 15 | +We must set up the logging of our classes. Take a look at example of [logback-spring.xml](./src/main/resources/logback-spring.xml). |
| 16 | + |
| 17 | +## Build a Filter |
| 18 | + |
| 19 | +Every Spring Web application have a chain on different filters. Every request flows through this filter chain before getting a controller. |
| 20 | + |
| 21 | +So we can implement a [logging filter](./src/main/java/com/bvn13/example/springboot/springrequestlogger/filters/RequestLoggingFilter.java) and put it into Spring Filter Chain to achieve our goal. |
| 22 | + |
| 23 | +```java |
| 24 | +@Slf4j |
| 25 | +@Component |
| 26 | +public class RequestLoggingFilter extends OncePerRequestFilter { |
| 27 | + @Override |
| 28 | + protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException { |
| 29 | + log.debug( |
| 30 | + String.format("FILTERED URL: %s", request.getRequestURI()) |
| 31 | + ); |
| 32 | + |
| 33 | + //continue filtering |
| 34 | + filterChain.doFilter(request, response); |
| 35 | + } |
| 36 | +} |
| 37 | +``` |
| 38 | + |
| 39 | +Using `@Slf4j` annotation get us to decrease boilerplate code to have a logger in a class. |
| 40 | + |
| 41 | +We must annotate our class with `@Component` annotation to make SpringBoot to instantiate this class as spring bean in Singleton scope. |
| 42 | + |
| 43 | +Our class extends `OncePerRequestFilter` abstract class so every request goes through our filter only once. |
| 44 | + |
| 45 | +And we are able to log anything regarding the request inside `doFilterInternal` method. |
| 46 | + |
| 47 | +### Result |
| 48 | + |
| 49 | +You may run [testControllerLoggingWithFilter](./src/test/java/com/bvn13/example/springboot/springrequestlogger/SpringrequestloggerApplicationTests.java) to see the result |
| 50 | + |
| 51 | +```java |
| 52 | + @Test(expected = HttpClientErrorException.NotFound.class) |
| 53 | + public void testControllerLoggingWithFilter() { |
| 54 | + restTemplate.getForObject("http://localhost:"+port+"/", String.class); |
| 55 | + restTemplate.getForObject("http://localhost:"+port+"/test.js", String.class); |
| 56 | + restTemplate.getForObject("http://localhost:"+port+"/test.css", String.class); |
| 57 | + restTemplate.getForObject("http://localhost:"+port+"/does-not-exist.file", String.class); |
| 58 | + } |
| 59 | +``` |
| 60 | + |
| 61 | + |
| 62 | + |
| 63 | +So our goal is achieved. We can see all files we request and not existing file too. |
| 64 | + |
0 commit comments