In this article, We will learn aboutΒ Β Spring BootΒ Logging feature.
If you have not read my introduction article of Spring Boot, I would request you to take a look β Β Spring Boot Tutorial.
Spring Boot is very easy to use framework and it has a lot of features. Logging in Spring Boot is very easily configurable and very flexible.
With very simple configurations, Spring Boot provides support for various Logging providers.
In this article, we will take a look at various logging configurations and options supported by Spring boot.
Let’s get started :
Default Zero Configuration Logging
spring-boot-starter-logging artifact/dependency determines the Spring Boot active enabled logging.
As Spring Boot has feature of Auto Configuration, It becomes very easy to use any supported Logging providers, as we can enable it by adding configurations.
Some Logging Providers are mentioned below :
- Java Util
- Logging
- Log4J2
- Logback
Spring Boot does provide the default logging feature. So even if we do not provide any configuration for the logging then also we will be able to see the logs in the console.
Default Logging in Spring Boot uses the Logback provider.
The internal logging of Spring boot is written with Apache Commons Logging and it is the one and only mandatory dependency.
This dependency was required to be downloaded manually till the Spring Boot version 1.x but since 2.x, this dependency is automatically downloaded transitively.
When I say transitivity, I mean spring-boot-starter-web depends on spring-boot-starter-logging dependency and it pulls in spring-jcl for us.
Spring boot auto-configuration feature provides us the default logging using Logback provider.
Addition of log statements
In Spring Boot, we need to use below mentioned libraries to add the log statements in our application code :
org.slf4j.Logger
org.slf4j.LoggerFactory
Β .
These libraries are available in SLF4J.
These libraries provides lots of useful methods for logging .
import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication public class MainApp { private static final Logger LOGGER = LoggerFactory.getLogger(MainApp.class); public static void main(String[] args) { SpringApplication.run(MainApp.class, args); LOGGER.info("Testing Logging in console"); } }
Output in Console :Β
2019-09-26 11:12:23.154 INFO 3421 --- [main] com.techblogstation.examples.MainApp: Testing Logging in console
Logging Levels
Logback supports various options or we can say levels of Logging :
- ERROR
- WARN
- DEBUG
- INFO
- TRACE
If we do not set any level then default level is set as INFO, which means that DEBUG and TRACE messages are not visible.
We need to set the level of Logging as per our requirement in the application.properties file of our Spring Boot Application.
Additionally, we can pass the arguments as -debug or -trace in order to enable these Logging levels
In the application.properties file, below code is needed :
debug=true
If enabling through Command line, then below command needs to be executed :
$ java -jar target/my-application-0.0.1-SNAPSHOT.jar --trace
Logging level can also be set as different for different packages. We can set it in either application.properties file or through cmd.
In application.properties :
logging.level.org.springframework=ERROR
logging.level.com.techblogstation=TRACE
In console :
-Dlogging.level.org.springframework=ERROR
-Dlogging.level.com.techblogstation=TRACE
Suppose If the log level for a package is defined multiple times with different log levels.
In this case , the lowest level will be used for the package.
TRACE
Β is lowest andΒERROR
Β is highest.
Log Format
In Spring, The default log statement formatting is mentioned inΒ defaults.xmlΒ file.
defaults.xml of Spring :Β
<?xml version="1.0" encoding="UTF-8"?> <!-- Default logback configuration provided for import --> <included> <conversionRule conversionWord="clr" converterClass="org.springframework.boot.logging.logback.ColorConverter" /> <conversionRule conversionWord="wex" converterClass="org.springframework.boot.logging.logback.WhitespaceThrowableProxyConverter" /> <conversionRule conversionWord="wEx" converterClass="org.springframework.boot.logging.logback.ExtendedWhitespaceThrowableProxyConverter" /> <property name="CONSOLE_LOG_PATTERN" value="${CONSOLE_LOG_PATTERN:-%clr(%d{${LOG_DATEFORMAT_PATTERN:-yyyy-MM-dd HH:mm:ss.SSS}}){faint} %clr(${LOG_LEVEL_PATTERN:-%5p}) %clr(${PID:- }){magenta} %clr(---){faint} %clr([%15.15t]){faint} %clr(%-40.40logger{39}){cyan} %clr(:){faint} %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}}"/> <property name="FILE_LOG_PATTERN" value="${FILE_LOG_PATTERN:-%d{${LOG_DATEFORMAT_PATTERN:-yyyy-MM-dd HH:mm:ss.SSS}} ${LOG_LEVEL_PATTERN:-%5p} ${PID:- } --- [%t] %-40.40logger{39} : %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}}"/> <logger name="org.apache.catalina.startup.DigesterFactory" level="ERROR"/> <logger name="org.apache.catalina.util.LifecycleBase" level="ERROR"/> <logger name="org.apache.coyote.http11.Http11NioProtocol" level="WARN"/> <logger name="org.apache.sshd.common.util.SecurityUtils" level="WARN"/> <logger name="org.apache.tomcat.util.net.NioSelectorPool" level="WARN"/> <logger name="org.eclipse.jetty.util.component.AbstractLifeCycle" level="ERROR"/> <logger name="org.hibernate.validator.internal.util.Version" level="WARN"/> </included>
This defaults.xml outputs the logs in below format (consider the same order as below list has) :
- Date and Time
- Log Level: the levels of Logs :Β
ERROR
,ΒWARN
,ΒINFO
,ΒDEBUG
, orΒTRACE
. - Process ID.
- AΒ Β separatorΒ
---
to be pasted in the start of each log message. - Thread name:Β It is enclosed in the square brackets (Sometimes trimmed).
- Logger name: It is usually the name of source class.
- The actual log message.
We canΒ customize the log format for our Spring Boot Application usingΒ logging.pattern.console
Β andΒ logging.pattern.file
Β properties.
application.properties # Logging patternΒ
for
Βthe console
logging.pattern.console= %d{yyyy-MM-dd HH:mm:ss} - %logger{
36
} - %msg%n
# Logging patternΒ
for
Βfile
logging.pattern.file= %d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{
36
} - %msg%
Logging to file
Spring Boot print logs in console by default but we can enable the logging for file as well.
A simple propertyΒ logging.fileΒ orΒ logging.path is used to enabling of Logging to file.
If we are usingΒ logging.path property then it will automatically create the spring.log file in the specified package.
application.properties # Logging to a temp folder logging.file=c:/temp/application.log #logging.path=/my-techblog/ # Pattern for file Logging logging.pattern.file= %d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{36} - %msg%
Logback Logging
For most of the Spring Boot application, default Logging is considered as good but when we are dealing with large projects or applications then we might require more control over Logging.
So Our application requires that it has a dedicated Logging configuration.
As we already know, Spring Boot uses the Logback so we can customize its behavior by :
- Adding logback.xml in classpath
- Define the customization over the file
<?xml version="1.0" encoding="UTF-8"?> <configuration> <property name="LOG_LOCATION" value="c:/temp" /> <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender"> <encoder> <pattern>%d{yyyy-MM-dd HH:mm:ss} - %logger{36} - %msg%n</pattern> </encoder> </appender> <appender name="FILE" class="ch.qos.logback.core.FileAppender"> <File>{LOG_LOCATION}/mylog.log</File> <encoder> <pattern>%d{yyyy-MM-dd HH:mm:ss} - %logger{36} - %msg%n</pattern> </encoder> <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"> <fileNamePattern>${LOG_LOCATION}/archived/mylog-%d{yyyy-MM-dd}.%i.log </fileNamePattern> <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP"> <maxFileSize>10MB</maxFileSize> </timeBasedFileNamingAndTriggeringPolicy> </rollingPolicy> </appender> <root level="INFO"> <appender-ref ref="CONSOLE"/> <appender-ref ref="FILE"/> </root> <!-- Properties for Application logs --> <logger name="com.techblogstation" level="trace" additivity="false"> <appender-ref ref="RollingFile" /> <appender-ref ref="Console" /> </logger> </configuration>
Log4j2 Logging
To be able to use the Logging ofΒ Log4j2 provider, below steps are required :
Exclude the logback and include log4j2
As we are aware that Spring Boot uses logback as its default Logging provider so In order to use another Logging provider or framework, we need to exclude the logback provider from our Spring Boot Application.
- Exclude the logback from the classpath of Application.
- Include theΒ spring-boot-starter-log4j2Β in classpath of Application.
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> <exclusions> <exclusion> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-logging</artifactId> </exclusion> </exclusions> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-log4j2</artifactId> </dependency>
Addition of log4j2 configuration file
Now, we are required to add log4j2 specific configuration file in our application’s classpath.Β This should typically reside in the resources folder.
We can name the file as any of the following:
- log4j2.xml
- log4j2-spring.xml
If we have named the file as something else then we can define the name of the file inΒ logging.fileΒ property in ourΒ application.propertiesΒ file.
<?xml version="1.0" encoding="UTF-8"?> <Configuration status="WARN" monitorInterval="30"> <Properties> <Property name="LOG_PATTERN">%d{yyyy-MM-dd'T'HH:mm:ss.SSSZ} %p %m%n</Property> <Property name="APP_LOG_ROOT">c:/temp</Property> </Properties> <Appenders> <Console name="console" target="SYSTEM_OUT"> <PatternLayout pattern="${LOG_PATTERN}" /> </Console> <RollingFile name="file" fileName="${APP_LOG_ROOT}/SpringBoot2App/application.log" filePattern="${APP_LOG_ROOT}/SpringBoot2App/application-%d{yyyy-MM-dd}-%i.log"> <PatternLayout pattern="${LOG_PATTERN}" /> <Policies> <SizeBasedTriggeringPolicy size="19500KB" /> </Policies> <DefaultRolloverStrategy max="1" /> </RollingFile> </Appenders> <Loggers> <Root level="info"> <AppenderRef ref="console" /> <AppenderRef ref="file" /> </Root> </Loggers> </Configuration>
With or without Slf4j
It is recommended that your application uses SLF4J logger classes.
If you are using SLF4J logger classes which areΒ org.slf4j.Logger andΒ org.slf4j.LoggerFactoryΒ then there is no requirement to change anything in the application code and all log statements will continue printing.
But, If you are targeting to use only the log4j2 specific classes thenΒ org.apache.logging.log4j.Logger
Β andΒ org.apache.logging.log4j.LogManager
is used.
See below :
SLF4J logger classes import org.slf4j.Logger; import org.slf4j.LoggerFactory; @SpringBootApplication public class MainApp { private static final Logger LOGGER = LoggerFactory.getLogger(MainApp.class); public static void main(String[] args) { SpringApplication.run(MainApp.class, args); LOGGER.info("Simple logging"); } }
LOG4J2 logger classes import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; @SpringBootApplication public class MainApp { private static Logger LOGGER = LogManager.getLogger(MainApp.class); public static void main(String[] args) { SpringApplication.run(MainApp.class, args); LOGGER.info("Simple logging..."); } }
Conclusion
Thatβs all folks! In this article,Β we have learnt all about the Logging in Spring Boot, Different Logging Providers for Spring Boot and How to Configure different Logging providers, levels and many other options.