Logback is the successor of the popular logging framework log4j. Logback is an excellent choice for enterprise applications since it’s fast, simple yet powerful. Common Logging will be automatically included when we use any of the Spring Boot Starter dependencies since they internally include spring-boot-starter-logging. In this Spring Boot Logging – Logback example, we will learn how to configure Logback in Spring Boot with SLF4J (Simple Logging Facade for Java). SLF4J acts as the facade for various logging framework such as Logback, log4j etc.
Folder Structure:
- Create a Maven project (maven-archetype-quickstart) “SpringBootLogback” and create a package for our source files “com.javainterviewpoint” under src/main/java
- Now add the following dependency in the 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/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.javainteriviewpoint</groupId> <artifactId>SpringBootLogback</artifactId> <version>0.0.1-SNAPSHOT</version> <packaging>jar</packaging> <name>SpringBootLogback</name> <url>http://maven.apache.org</url> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> </properties> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>1.5.1.RELEASE</version> </parent> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter</artifactId> <!-- <exclusions> <exclusion> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-logging</artifactId> </exclusion> </exclusions> --> </dependency> <dependency> <groupId>ch.qos.logback</groupId> <artifactId>logback-classic</artifactId> </dependency> <dependency> <groupId>org.slf4j</groupId> <artifactId>jul-to-slf4j</artifactId> </dependency> </dependencies> </project>
- Create the Java classes App.java under com.javainterviewpoint folder.
- Create logback.xml file under src/main/resources directory.
Spring Boot Logging – Logback
Dependency Tree
[INFO] ------------------------------------------------------------------------ [INFO] Building SpringBootLogback 0.0.1-SNAPSHOT [INFO] ------------------------------------------------------------------------ [INFO] [INFO] --- maven-dependency-plugin:2.10:tree (default-cli) @ SpringBootLogback --- [INFO] com.javainteriviewpoint:SpringBootLogback:jar:0.0.1-SNAPSHOT [INFO] +- org.springframework.boot:spring-boot-starter:jar:1.5.1.RELEASE:compile [INFO] | +- org.springframework.boot:spring-boot:jar:1.5.1.RELEASE:compile [INFO] | | \- org.springframework:spring-context:jar:4.3.6.RELEASE:compile [INFO] | | +- org.springframework:spring-aop:jar:4.3.6.RELEASE:compile [INFO] | | +- org.springframework:spring-beans:jar:4.3.6.RELEASE:compile [INFO] | | \- org.springframework:spring-expression:jar:4.3.6.RELEASE:compile [INFO] | +- org.springframework.boot:spring-boot-autoconfigure:jar:1.5.1.RELEASE:compile [INFO] | +- org.springframework.boot:spring-boot-starter-logging:jar:1.5.1.RELEASE:compile [INFO] | | +- org.slf4j:jcl-over-slf4j:jar:1.7.22:compile [INFO] | | \- org.slf4j:log4j-over-slf4j:jar:1.7.22:compile [INFO] | +- org.springframework:spring-core:jar:4.3.6.RELEASE:compile [INFO] | \- org.yaml:snakeyaml:jar:1.17:runtime [INFO] +- ch.qos.logback:logback-classic:jar:1.1.9:compile [INFO] | +- ch.qos.logback:logback-core:jar:1.1.9:compile [INFO] | \- org.slf4j:slf4j-api:jar:1.7.22:compile [INFO] \- org.slf4j:jul-to-slf4j:jar:1.7.22:compile
Spring Boot Logback Configuration – logback.xml
Spring Boot automatically configures Logback the moment it finds a file named logback.xml in the classpath. Create logback.xml file under src/main/resources folder
<?xml version="1.0" encoding="UTF-8"?> <configuration> <appender name="ConsoleAppender" class="ch.qos.logback.core.ConsoleAppender"> <encoder> <pattern> %d{MM:dd HH:mm:ss.SSS} [%t] [%level] [%logger{36}] - %msg%n </pattern> </encoder> </appender> <appender name="FileAppender" class="ch.qos.logback.core.FileAppender"> <file>c:/JIP/Application_properties.log</file> <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder"> <Pattern> %d{MM:dd HH:mm:ss.SSS} [%t] [%level] [%logger{36}] - %msg%n </Pattern> </encoder> </appender> <!-- Logging custom package --> <logger name="com.javainterviewpoint" level="info" additivity="false"> <appender-ref ref="ConsoleAppender"></appender-ref> <appender-ref ref="FileAppender"></appender-ref> </logger> <!-- Logging spring boot package --> <logger name="org.springframework.boot" level="info" additivity="false"> <appender-ref ref="ConsoleAppender"></appender-ref> <appender-ref ref="FileAppender"></appender-ref> </logger> <root level="info"> <appender-ref ref="ConsoleAppender"></appender-ref> </root> </configuration>
- In the above configuration, we have defined two appenders ConsoleAppender, FileAppender. The <appender> tag needs the mandatory attributes name and class.
- name – This attribute specifies the name of the appender which can be referred by the logger.
- class – This attribute specifies the fully qualified name of the appender class (ch.qos.logback.core.ConsoleAppender for ConsoleAppender)
- <encoder> tag specifies the pattern by which the log message has to be written
- The message which will be logged will adhere to notion specified in the <pattern> tag, We have used the pattern “%d{MM:dd HH:mm:ss.SSS} [%t] [%level] [%logger{36}] – %msg%n “
- %d – Represents the time of the log message occurred in the SimpleDateFormat.
- %t – Represents the name of the thread
- %level – Represents the logging level of the log message (TRACE, DEBUG, INFO, WARN, ERROR)
- %logger{36} – Represents the full path of the class name (including package)
- %msg – Represents the actual log message.
- We have configured the application specific logging and root logging to use the ConsoleAppender, FileAppender using <logger> and <root> tags.
App.java
package com.javainterviewpoint; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.boot.ApplicationArguments; import org.springframework.boot.ApplicationRunner; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication public class App implements ApplicationRunner { private static Logger logger = LoggerFactory.getLogger(App.class); public static void main(String[] args) { SpringApplication.run(App.class, args); } @Override public void run(ApplicationArguments applicationArguments) throws Exception { logger.debug("Debugging log"); logger.info("Info log"); logger.warn("Warning log"); logger.error("Error log"); } }
The App class main() method is the triggering point of our application, it in-turn calls Spring Boot’s SpringApplication class run() method which bootstrap our App application. We need to pass our App.class as an argument to our run() method. We have printed some logging statements.
Output:
Run the spring boot application using “mvn spring-boot:run”
. ____ _ __ _ _ /\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \ ( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \ \\/ ___)| |_)| | | | | || (_| | ) ) ) ) ' |____| .__|_| |_|_| |_\__, | / / / / =========|_|==============|___/=/_/_/_/ :: Spring Boot :: (v1.5.1.RELEASE) 02:09 11:55:10.780 [main] [INFO] [com.javainterviewpoint.App] - Starting App on DA56CZ8VD02 with PID 9448 (C:\JIP\sts-3.8.4.RELEASE\Workspace\SpringBootLogback\target\classes started by xbbl47m in C:\JIP\sts-3.8.4.RELEASE\Workspace\SpringBootLogback) 02:09 11:55:10.782 [main] [INFO] [com.javainterviewpoint.App] - No active profile set, falling back to default profiles: default 02:09 11:55:10.822 [main] [INFO] [o.s.c.a.AnnotationConfigApplicationContext] - Refreshing org.springframework.context.annotation.AnnotationConfigApplicationContext@a4102b8: startup date [Fri Feb 09 11:55:10 IST 2018]; root of context hierarchy 02:09 11:55:11.239 [main] [INFO] [o.s.j.e.a.AnnotationMBeanExporter] - Registering beans for JMX exposure on startup 02:09 11:55:11.250 [main] [INFO] [com.javainterviewpoint.App] - Info log 02:09 11:55:11.250 [main] [WARN] [com.javainterviewpoint.App] - Warning log 02:09 11:55:11.250 [main] [ERROR] [com.javainterviewpoint.App] - Error log 02:09 11:55:11.251 [main] [INFO] [com.javainterviewpoint.App] - Started App in 0.671 seconds (JVM running for 1.258) 02:09 11:55:11.252 [Thread-2] [INFO] [o.s.c.a.AnnotationConfigApplicationContext] - Closing org.springframework.context.annotation.AnnotationConfigApplicationContext@a4102b8: startup date [Fri Feb 09 11:55:10 IST 2018]; root of context hierarchy 02:09 11:55:11.254 [Thread-2] [INFO] [o.s.j.e.a.AnnotationMBeanExporter] - Unregistering JMX-exposed beans on shutdown
Spring Boot Rolling File Appender – Logback
Whenever we need a new log file to be created whenever the file reaches a certain threshold size, then we can go for RollingFile Appender, in order to add a RollingFileAppender add the below code in the logback.xml
<appender name="RollingAppender" class="ch.qos.logback.core.rolling.RollingFileAppender"> <file>c:/JIP/ApplicationRolling.log</file> <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder"> <Pattern>%d{MM:dd HH:mm:ss.SSS} [%t] [%level] [%logger{36}] - %msg%n</Pattern> </encoder> <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"> <fileNamePattern>c:/JIP/archived/ApplicationRolling_%d{dd-MM-yyyy}.log</fileNamePattern> <maxHistory>10</maxHistory> <totalSizeCap>10KB</totalSizeCap> </rollingPolicy> </appender>
- <file> tag defines the name of the file where the logs will be written
- <encoder> tag defines the pattern by which the log message has to be written
- <rollingPolicy> tag defines the TimeBasedRollingPolicy
- <maxHistory> tag defines the number of older files which will be kept in the archive before deleting the older files.
- <totalSizeCap> tag defines the total size of the archived files.
Spring Profile based Logging – logback-spring.xml
Whenever we want to have different logging configuration for different environments (profiles), like in Development region we need to have both ConsoleAppender and FileAppender, whereas for the Production region we need to have only ConsoleAppender then we can use <springProfile>
Create logback-spring.xml under src/main/resources folder
<?xml version="1.0" encoding="UTF-8"?> <configuration> <appender name="ConsoleAppender" class="ch.qos.logback.core.ConsoleAppender"> <encoder> <pattern> %d{MM:dd HH:mm:ss.SSS} [%t] [%level] [%logger{36}] - %msg%n </pattern> </encoder> </appender> <appender name="FileAppender" class="ch.qos.logback.core.FileAppender"> <file>c:/JIP/Applicaton_Profile.log</file> <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder"> <Pattern> %d{MM:dd HH:mm:ss.SSS} [%t] [%level] [%logger{36}] - %msg%n </Pattern> </encoder> </appender> <springProfile name="dev"> <root level="debug"> <appender-ref ref="ConsoleAppender" /> <appender-ref ref="FileAppender" /> </root> </springProfile> <springProfile name="prod"> <root level="info"> <appender-ref ref="ConsoleAppender" /> </root> </springProfile> </configuration>
when profile selected is dev
We need to make an entry in the application.properties
spring.profiles.active=dev
Output:
02:14 14:34:34.482 [main] [DEBUG] [o.s.c.e.PropertySourcesPropertyResolver] - Found key 'spring.liveBeansView.mbeanDomain' in [systemProperties] with type [String] 02:14 14:34:34.484 [main] [DEBUG] [o.s.b.f.s.DefaultListableBeanFactory] - Returning cached instance of singleton bean 'app' 02:14 14:34:34.485 [main] [DEBUG] [com.javainteriviewpoint.App] - Debugging log 02:14 14:34:34.485 [main] [INFO] [com.javainteriviewpoint.App] - Info log 02:14 14:34:34.485 [main] [WARN] [com.javainteriviewpoint.App] - Warning log 02:14 14:34:34.485 [main] [ERROR] [com.javainteriviewpoint.App] - Error log 02:14 14:34:34.486 [main] [DEBUG] [o.s.b.f.s.DefaultListableBeanFactory] - Returning cached instance of singleton bean 'springApplicationAdminRegistrar' 02:14 14:34:34.486 [main] [INFO] [com.javainteriviewpoint.App] - Started App in 0.843 seconds (JVM running for 1.327) 02:14 14:34:34.488 [Thread-2] [INFO] [o.s.c.a.AnnotationConfigApplicationContext] - Closing org.springframework.context.annotation.AnnotationConfigApplicationContext@60dcc9fe: startup date [Wed Feb 14 14:34:33 IST 2018]; root of context hierarchy 02:14 14:34:34.488 [Thread-2] [DEBUG] [o.s.c.e.PropertySourcesPropertyResolver] - Found key 'spring.liveBeansView.mbeanDomain' in [systemProperties] with type [String] 02:14 14:34:34.489 [Thread-2] [DEBUG] [o.s.b.f.s.DefaultListableBeanFactory] - Returning cached instance of singleton bean 'lifecycleProcessor' 02:14 14:34:34.489 [Thread-2] [DEBUG] [o.s.b.f.s.DefaultListableBeanFactory] - Destroying singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@368f2016: defining beans [org.springframework.context.annotation.internalConfigurationAnnotationProcessor,org.springframework.context.annotation.internalAutowiredAnnotationProcessor,org.springframework.context.annotation.internalRequiredAnnotationProcessor,org.springframework.context.annotation.internalCommonAnnotationProcessor,org.springframework.context.event.internalEventListenerProcessor,org.springframework.context.event.internalEventListenerFactory,app,org.springframework.boot.autoconfigure.internalCachingMetadataReaderFactory,org.springframework.boot.autoconfigure.AutoConfigurationPackages,org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration,org.springframework.boot.autoconfigure.condition.BeanTypeRegistry,propertySourcesPlaceholderConfigurer,org.springframework.boot.autoconfigure.jmx.JmxAutoConfiguration,mbeanExporter,objectNamingStrategy,mbeanServer,org.springframework.boot.autoconfigure.admin.SpringApplicationAdminJmxAutoConfiguration,springApplicationAdminRegistrar,org.springframework.boot.autoconfigure.context.ConfigurationPropertiesAutoConfiguration,org.springframework.boot.context.properties.ConfigurationPropertiesBindingPostProcessor,org.springframework.boot.context.properties.ConfigurationPropertiesBindingPostProcessor.store,org.springframework.boot.autoconfigure.info.ProjectInfoAutoConfiguration,spring.info-org.springframework.boot.autoconfigure.info.ProjectInfoProperties,org.springframework.boot.autoconfigure.web.WebClientAutoConfiguration]; root of factory hierarchy 02:14 14:34:34.489 [Thread-2] [DEBUG] [o.s.b.f.s.DisposableBeanAdapter] - Invoking destroy() on bean with name 'springApplicationAdminRegistrar' 02:14 14:34:34.489 [Thread-2] [DEBUG] [o.s.b.f.s.DisposableBeanAdapter] - Invoking destroy() on bean with name 'mbeanExporter' 02:14 14:34:34.489 [Thread-2] [INFO] [o.s.j.e.a.AnnotationMBeanExporter] - Unregistering JMX-exposed beans on shutdown 02:14 14:34:34.489 [Thread-2] [DEBUG] [o.s.b.f.s.DisposableBeanAdapter] - Invoking destroy() on bean with name 'org.springframework.boot.context.properties.ConfigurationPropertiesBindingPostProcessor' 02:14 14:34:34.490 [Thread-2] [DEBUG] [o.s.b.f.s.DefaultListableBeanFactory] - Retrieved dependent beans for bean 'org.springframework.boot.autoconfigure.internalCachingMetadataReaderFactory': [org.springframework.context.annotation.internalConfigurationAnnotationProcessor]
when profile selected is prod
spring.profiles.active=prod
02:14 15:20:20.905 [main] [INFO] [com.javainteriviewpoint.App] - Starting App on DA56CZ8VD02 with PID 6040 (C:\JIP\sts-3.8.4.RELEASE\Workspace\SpringBootLogback\target\classes started by xbbl47m in C:\JIP\sts-3.8.4.RELEASE\Workspace\SpringBootLogback) 02:14 15:20:20.906 [main] [INFO] [com.javainteriviewpoint.App] - The following profiles are active: prod 02:14 15:20:20.951 [main] [INFO] [o.s.c.a.AnnotationConfigApplicationContext] - Refreshing org.springframework.context.annotation.AnnotationConfigApplicationContext@2fd6b6c7: startup date [Wed Feb 14 15:20:20 IST 2018]; root of context hierarchy 02:14 15:20:21.375 [main] [INFO] [o.s.j.e.a.AnnotationMBeanExporter] - Registering beans for JMX exposure on startup 02:14 15:20:21.401 [main] [INFO] [com.javainteriviewpoint.App] - Info log 02:14 15:20:21.401 [main] [WARN] [com.javainteriviewpoint.App] - Warning log 02:14 15:20:21.401 [main] [ERROR] [com.javainteriviewpoint.App] - Error log 02:14 15:20:21.404 [main] [INFO] [com.javainteriviewpoint.App] - Started App in 0.791 seconds (JVM running for 1.291) 02:14 15:20:21.407 [Thread-2] [INFO] [o.s.c.a.AnnotationConfigApplicationContext] - Closing org.springframework.context.annotation.AnnotationConfigApplicationContext@2fd6b6c7: startup date [Wed Feb 14 15:20:20 IST 2018]; root of context hierarchy 02:14 15:20:21.410 [Thread-2] [INFO] [o.s.j.e.a.AnnotationMBeanExporter] - Unregistering JMX-exposed beans on shutdown
Leave a Reply