Logging is a fundamental need of an application. A well-structured log contains a wealth of information about the events happening in an application as well as Application metrics. Logs save a lot of valuable time for developers and Support Team to analyze, debug and resolve an issue easily and quickly.
In this tutorial, we are going to deep-dive into logging Framework, Options, and configurations available in spring boot.
Table of Contents
Spring Boot Default Logging
- One of the main advantages of Spring Boot is that, no additional configuration needed for logging purposes. All the logging framework is avaliable by default.
- It uses apache commons logging for all internal logging.
- If we are using Spring Boot starters in our configuration (which we usually do), then no need to include the logging libraries explicitly. This is because, all the starters (example – web starter) in turn depends on “spring-boot-starter-logging” that automatically downloads the necessary logging libraries.
- By default, Spring boot uses Logback configuration if you use starters in your application.
- You will see how to customize the Logback configuration in the later part of this tutorial.
Default Log output
When you try running the sample application, you can see the output in the following format:
The logs give the following information:
- Date and Time — Millisecond precision.
- Log Level — ERROR, WARN, INFO, DEBUG or TRACE.
- Process ID.
- A — separator to distinguish the start of actual log messages.
- Thread name — Enclosed in square brackets (may be truncated for console output).
- Logger name — This is usually the source class name (often abbreviated).
- The actual log message
Note: Default log level is INFO. It means that only ERROR, WARN, and INFO messages are logged.
Logging Levels
- Spring Boot supports the following log levels:
- TRACE
- DEBUG
- INFO
- WARN
- ERROR
- FATAL
- OFF
Changing Log levels
You can change the log level as per your application need. There are 3 ways to do it:
- Using application.properties
- VM Arguments
- Logging Configuration File
a. Using application.properties
- To change the default log-level for the root logger from INFO to DEBUG, you can do the following change in application.properties:
logging.level.root=DEBUG
“Root logger” logs messages for all classes in application.
- Individual Class level logging is defined in application.properties. For instance, to enable the debug for the Class named com.example.demo.DemoApplication, add the following:
logging.level.
com.example.demo.DemoApplication
= debug
- Package level logging is defined in application.properties. For instance, the below statements shows how to enable DEBUG and ERROR level logging for the “org.springframework.web” and “org.hibernate” packages respectively.
logging.level.<strong>org.springframework.web</strong> = DEBUG</code><br><code>logging.<strong>level.org.hibernate</strong> = ERROR</code><br></pre> <!-- /wp:preformatted --> <!-- wp:heading {"level":4} --> <h4>b. VM Arguments</h4> <!-- /wp:heading --> <!-- wp:paragraph --> <p>Instead of using <em><strong>application.properties</strong></em> file to define the configurations, you can use the VM arguments instead as follows:</p> <!-- /wp:paragraph --> <!-- wp:preformatted --> <pre class="wp-block-preformatted"><code>-Dlogging.level.<strong>org.springframework.web</strong> = DEBUG</code><br><code>-Dlogging.<strong>level.org.hibernate</strong> = ERROR
c. Logback Configuration File
Another way to change the logging levels is by defining through the Logback Configuration file. Sample code fragment is shown below:
<logger name="org.springframework" level="INFO" /> <logger name="com.tutorialcup" level="INFO" />
More details on creating a logback configuration file are explained in the later part of this tutorial.
Color Coded Output
- If your terminal supports ANSI, color output is used to aid readability. You can set spring.output.ansi.enabled to either ALWAYS, NEVER or DETECT.
ALWAYS
– Enable ANSI-colored output.DETECT
– Try to detect whether ANSI coloring capabilities are available.NEVER
– Disable ANSI-colored output.
- By default, these are the colors printed on the console terminal:
- FATAL and ERROR – Red
- WARN – Yellow
- INFO, DEBUG and TRACE – Green
Logging to file
By default, Spring Boot logs the output messages to console.
If you want to output the logs to file, then specify the following properties:
logging.file (or) logging.path property.
logging.file=/Users/vn0mrcb/Documents/output-debug.log
Logging Patterns
Logging patterns define the message format to be printed on the console. For instance, below configurations defines the logging patterns for console and file outputs respectively.
# Logging pattern for the console logging.pattern.console=%d{yyyy-MM-dd HH:mm:ss} - %msg%n # Logging pattern for file logging.pattern.file=%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{36} - %msg%n
Some key notations used in the above message format is given below:
%d-
– Outputs time of occurrence of the event in formats supported by SimpleDateFormat.%msg
–the actual message to log.%n
– Line Break.$-5level
– outputs the logging level of the log message ( For example, ERROR/WARN/INFO/DEBUG etc..)%logger{36}
– outputs the package + class name the log message occurred in. The number inside the brackets represents the maximum length of the package + class name.[%thread]-
Thread where the log message occurred.
Logback Configuration Logging
- As mentioned earlier, Spring Boot uses the Logback as the default Logging framework. The default Logback configuration provided by “spring boot starter logging” is sufficient to get started with the simple project. No need of any additional configurations.
- Also, it is recommended to use the logback configuration file in case of any customization rather than using the equivalent properties in application.properties.
- In order to override the default configurations, you can include the LogBack configuration file in the classpath. Spring Boot automatically loads these any of the following files when present in the classpath and overrides the default configurations:
- logback-spring.xml
- logback.xml
Note : Spring recommends using the -spring variant over the plain ones whenever possible, as described in the official spring documentation.
- Let us create a simple logback-spring.xml which uses different color and logging pattern, with separate specifications for console and file output, and a condition for rolling the logs to avoid generating huge log files:
<?xml version="1.0" encoding="UTF-8"?> <configuration> <property name="LOGS" value="./logs" /> <appender name="Console" class="ch.qos.logback.core.ConsoleAppender"> <layout class="ch.qos.logback.classic.PatternLayout"> <Pattern> %black(%d{ISO8601}) %highlight(%-5level) [%blue(%t)] %yellow(%C{1.}): %msg%n%throwable </Pattern> </layout> </appender> <appender name="RollingFile" class="ch.qos.logback.core.rolling.RollingFileAppender"> <file>${LOGS}/spring-boot.log</file> <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder"> <Pattern>%d %p %C{1.} [%t] %m%n</Pattern> </encoder> <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"> <!-- rollover daily and when the file reaches 10 MegaBytes --> <fileNamePattern>${LOGS}/archived/spring-boot-demo-%d{yyyy-MM-dd}.%i.log </fileNamePattern> <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP"> <maxFileSize>10MB</maxFileSize> </timeBasedFileNamingAndTriggeringPolicy> </rollingPolicy> </appender> <!-- LOG everything at INFO level --> <root level="info"> <appender-ref ref="RollingFile" /> <appender-ref ref="Console" /> </root> <!-- LOG "com.example.demo*" at TRACE level --> <logger name="com.example.demo" level="trace" additivity="false"> <appender-ref ref="RollingFile" /> <appender-ref ref="Console" /> </logger> </configuration>
- Place the above file in the same location as application.properties and add some debug and trace statements (for testing purpose) in the main class of the application:
- Restart the application and notice the console output below:
a. Color scheme of messages changed as per the specification in the logback configuration file.
b. The DEBUG and TRACE messages are printed now as shown below:
c. Logs directory named “logs” and “archive” created under current path and corresponding logs are created as shown below:
d. Rotate and archive the logs once the size of the logs file reached 10 MB.
Using log4j2 instead of Logback
- As Apache commons logging is at the core of the logging framework and Logback is the default implementation provided, switching to other logging libraries is easy.
- Log4j2 is another common logging library used for Logging purposes.
- In order to use log4j2 rather than Logback, we need to exclude Logback from our dependencies and add the log4j2 to the dependencies.
<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>
Place any one of the following configuration files in the classpath
- log4j2-spring.xml
- log4j2.xml
Note: Spring Boot recommends using the -spring variant version of the log4j2 configuration file.
Let us create a simple log4j2-spring.xml that achieves the same functionality as that of logback configuration:
<?xml version="1.0" encoding="UTF-8"?> <Configuration> <Appenders> <Console name="Console" target="SYSTEM_OUT"> <PatternLayout pattern="%style{%d{ISO8601}}{black} %highlight{%-5level }[%style{%t}{bright,blue}] %style{%C{1.}}{bright,yellow}: %msg%n%throwable" /> </Console> <RollingFile name="RollingFile" fileName="./logs/spring-boot-logger-log4j2.log" filePattern="./logs/$${date:yyyy-MM}/spring-boot-logger-log4j2-%d{-dd-MMMM-yyyy}-%i.log.gz"> <PatternLayout> <pattern>%d %p %C{1.} [%t] %m%n</pattern> </PatternLayout> <Policies> <!-- rollover on startup, daily and when the file reaches 10 MegaBytes --> <OnStartupTriggeringPolicy /> <SizeBasedTriggeringPolicy size="10 MB" /> <TimeBasedTriggeringPolicy /> </Policies> </RollingFile> </Appenders> <Loggers> <!-- LOG everything at INFO level --> <Root level="info"> <AppenderRef ref="Console" /> <AppenderRef ref="RollingFile" /> </Root> <!-- LOG "com.example.demo.*" at TRACE level --> <Logger name="com.example.demo" level="trace"></Logger> </Loggers> </Configuration>
Profile Specific Logging
- The <springProfile> tag lets you define the logging configurations with respect to a particular active Spring profile.
<springProfile name="staging"> <!-- configuration to be enabled when the "staging" profile is active --> </springProfile> <springProfile name="dev | staging"> <!-- configuration to be enabled when the "dev" or "staging" profiles are active --> </springProfile> <springProfile name="!production"> <!-- configuration to be enabled when the "production" profile is not active --> </springProfile>
- You can set the active spring profile in application.properties or environment variable. For instance, to make “dev” as an active spring profile :
spring.profiles.active=dev
- As an alternative, you can also start the application with the following VM argument:
-Dspring.profiles.active=dev
Conclusion
In this tutorial, we have seen how to use and customize the logging frameworks in Spring Boot environment.
In the next tutorial, we will see how to internationalize a Spring Boot application.