In the previous article, we have secured the REST API with Spring Security and JSON Web Token (JWT). Now we are gonna add logging support using the Logback logging framework since there is some issue with the Log4j dependencies in the application.
What is Logback?
Logback is a logging framework for Java applications, created as a successor to the popular log4j project.
Configure Logback
Add Dependencies
pom.xml
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.javachinna</groupId>
<artifactId>spring-rest-jwt-demo</artifactId>
<packaging>war</packaging>
<version>0.0.1-SNAPSHOT</version>
<name>spring-rest-jwt-demo Maven Webapp</name>
<url>http://maven.apache.org</url>
<properties>
<java-version>11</java-version>
<spring.version>5.2.3.RELEASE</spring.version>
<hibernate.version>5.4.1.Final</hibernate.version>
<slf4j.version>1.7.25</slf4j.version>
</properties>
<dependencies>
<!-- Spring Web MVC -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>${spring.version}</version>
</dependency>
<!-- Required for converting JSON data to Java object and vice versa -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.9.10.1</version>
</dependency>
<!-- Servlet API -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.0.1</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.2.3</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>jul-to-slf4j</artifactId>
<version>${slf4j.version}</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>log4j-over-slf4j</artifactId>
<version>${slf4j.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-web</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-config</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt</artifactId>
<version>0.9.1</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-orm</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-jpa</artifactId>
<version>2.1.8.RELEASE</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>${hibernate.version}</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.14</version>
<scope>runtime</scope>
</dependency>
</dependencies>
<build>
<finalName>SpringRestJwt</finalName>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.3.2</version>
<configuration>
<source>${java-version}</source>
<target>${java-version}</target>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>3.2.3</version>
<configuration>
<warSourceDirectory>src/main/webapp</warSourceDirectory>
<warName>SpringRestJwt</warName>
</configuration>
</plugin>
</plugins>
</build>
</project>
Configuration Options
We can configure Logback either programmatically or with a configuration script expressed in the XML or Groovy format.
Let us see the configuration process:
- Logback seeks the
logback-test.xml
in the classpath. - If no such file is found, it looks further for the file called
logback.groovy
in the classpath. - If no such file is found, it looks further for the file called
logback.xml
in the classpath. - If none of the above succeeds, Logback starts to use the
BasicConfigurator
, which sets up the framework to redirect the logging output to the console.
We can check this behavior with the following code snippet
LoggerContext lc = (LoggerContext) LoggerFactory.getILoggerFactory();
StatusPrinter.print(lc);
Output
12:30:18,699 |-INFO in ch.qos.logback.classic.LoggerContext[default] - Could NOT find resource [logback-test.xml]
12:30:18,700 |-INFO in ch.qos.logback.classic.LoggerContext[default] - Could NOT find resource [logback.groovy]
12:30:18,701 |-INFO in ch.qos.logback.classic.LoggerContext[default] - Could NOT find resource [logback.xml]
12:30:18,709 |-INFO in ch.qos.logback.classic.BasicConfigurator@2084918d - Setting up default configuration.
Configure with XML
Let us configure Logback with logback.xml
file
logback.xml
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%d{dd-MM-yyyy HH:mm:ss.SSS} [%thread] %-5level %logger{36}.%M - %msg%n</pattern>
</encoder>
</appender>
<root level="debug">
<appender-ref ref="STDOUT" />
</root>
</configuration>
As you can see above, We have set the logging level to debug to enable debug logging.
The available logging levels in Logback are:
- OFF (output no logs)
- ERROR
- WARN
- INFO
- DEBUG
- TRACE
Build Application
Run mvn clean install
command to clean and build the war file
Deploy Application
Deploy the generated war file in a server like tomcat.
Test Application
Generate a JSON Web Token – Create a POST request with URL localhost:8080/authenticate
. The request body should have a valid username and password. In our case username is javachinna and the password is password.
Hit the url http://localhost:8080/SpringRestJwt/greet/Chinna with the generated JWT token
Logs
29-07-2020 20:20:49.084 [http-nio-8080-exec-18] DEBUG o.s.web.servlet.DispatcherServlet.traceDebug - GET "/SpringRestJwt/greet/Chinna", parameters={}
29-07-2020 20:20:49.084 [http-nio-8080-exec-18] DEBUG o.s.w.s.m.m.a.RequestMappingHandlerMapping.getHandler - Mapped to com.javachinna.controller.GreetController#greet(String, ModelMap)
29-07-2020 20:20:49.125 [http-nio-8080-exec-18] INFO c.j.controller.GreetController.greet - Hello!!! Chinna How are You?
29-07-2020 20:20:49.129 [http-nio-8080-exec-18] DEBUG o.s.w.s.m.m.a.RequestResponseBodyMethodProcessor.writeWithMessageConverters - Using 'application/json', given [*/*] and supported [application/json, application/*+json]
29-07-2020 20:20:49.130 [http-nio-8080-exec-18] DEBUG o.s.w.s.m.m.a.RequestResponseBodyMethodProcessor.traceDebug - Writing ["Hello!!! Chinna How are You?"]
29-07-2020 20:20:49.131 [http-nio-8080-exec-18] DEBUG o.s.s.w.h.writers.HstsHeaderWriter.writeHeaders - Not injecting HSTS header since it did not match the requestMatcher org.springframework.security.web.header.writers.HstsHeaderWriter$SecureRequestMatcher@666f054
29-07-2020 20:20:49.132 [http-nio-8080-exec-18] DEBUG o.s.web.servlet.DispatcherServlet.logResult - Completed 200 OK
29-07-2020 20:20:49.133 [http-nio-8080-exec-18] DEBUG o.s.s.w.a.ExceptionTranslationFilter.doFilter - Chain processed normally
29-07-2020 20:20:49.133 [http-nio-8080-exec-18] DEBUG o.s.s.w.c.SecurityContextPersistenceFilter.doFilter - SecurityContextHolder now cleared, as request processing completed
Source code
https://github.com/JavaChinna/spring-rest-logging
References
https://dzone.com/articles/using-logback-with-spring
Conclusion
That’s all folks. In this article, we have added logging support using the Logback framework.
Please share the article with your friends if you like it. Thank you for reading.
Read Next: Spring 5 REST API with Embedded Tomcat without using Spring Boot