Logging is an essential part of any application as it provides insight into the internal operations and helps track down issues. Spring Boot, a powerful framework for building Java applications, comes with an excellent logging system by default. However, sometimes developers need to tweak the logging configuration to suit the application’s needs. This article will explore how to configure logging in Spring Boot, test log severity, and adjust log levels dynamically using the LoggingSystem
class, along with practical examples.
Introduction to Spring Boot Logging
Spring Boot uses the SLF4J (Simple Logging Facade for Java) as an abstraction layer and supports several logging frameworks, such as Logback, Log4J2, and Java Util Logging. By default, Spring Boot uses Logback as its default logging implementation, but it also provides the flexibility to switch to other frameworks.
Out of the box, Spring Boot provides basic logging capabilities with different log levels like ERROR, WARN, INFO, DEBUG, and TRACE. These log levels represent the severity of the logs:
- ERROR: For serious errors that may cause the application to abort.
- WARN: For situations that are not errors but might require attention.
- INFO: For informational messages that highlight the progress of the application.
- DEBUG: For lower-level information useful for debugging.
- TRACE: For very detailed logs, usually of interest only when diagnosing specific problems.
While these default settings are sufficient for many applications, there are scenarios where you need to customize log formats, target specific loggers, or dynamically adjust log levels.
Configuring Logging in Spring Boot
Spring Boot provides several ways to configure logging. The configuration can be done either through application.properties or application.yml files or through more advanced techniques, such as programmatically altering log levels using the LoggingSystem
class.
Configuring Logging in application.properties
The simplest way to configure logging in Spring Boot is through the application.properties
file. Below are some common configurations:
# Set the root logging level to INFO
logging.level.root=INFO
# Set logging level for specific package or classlogging.level.com.example.myapp=DEBUG
# Set a custom logging filelogging.file.name=app-logs.log
# Set a rolling policy for log fileslogging.file.max-size=10MB
logging.file.max-history=30
These configurations allow you to control the logging level and set file output for your logs. For instance, setting logging.level.root=INFO
ensures that all logs at the INFO level and above (INFO, WARN, ERROR) are captured, while debug and trace logs are ignored. You can also specify different logging levels for specific packages or classes as shown in the second property.
Configuring Logging in application.yml
If you prefer to use YAML format for configuration, the equivalent settings are as follows:
logging:
level:
root: INFO
com.example.myapp: DEBUG
file:
name: app-logs.log
max-size: 10MB
max-history: 30
Testing Log Severity
Once you’ve configured your logging settings, it’s important to test the severity levels. This is where you can log messages at various severity levels and verify whether the application logs behave as expected. Here’s an example using SLF4J in a Spring Boot application:
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
public class LogTestController {
private static final Logger logger = LoggerFactory.getLogger(LogTestController.class);
public String logTest() {
logger.error(“This is an ERROR level message”);
logger.warn(“This is a WARN level message”);
logger.info(“This is an INFO level message”);
logger.debug(“This is a DEBUG level message”);
logger.trace(“This is a TRACE level message”);
return “Logs generated successfully”;}
}
In this example, the logTest
method logs messages at all severity levels (ERROR, WARN, INFO, DEBUG, TRACE). The application.properties
or application.yml
settings determine which of these messages actually appear in the logs. If the root level is set to INFO
, only INFO, WARN, and ERROR messages will be logged, while DEBUG and TRACE will be ignored.
Adjusting Log Levels Dynamically Using the LoggingSystem
Class
Sometimes, you may need to change the log levels dynamically during runtime without restarting the application. This can be particularly useful for production environments when you want to temporarily increase the logging verbosity to troubleshoot an issue.
Spring Boot provides the LoggingSystem
class for this purpose, allowing developers to programmatically adjust log levels.
Changing Log Levels Programmatically
You can inject LoggingSystem
into any Spring-managed bean and use it to adjust log levels at runtime. Below is an example of how to change the logging level dynamically:
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.logging.LoggingSystem;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
public class LogLevelController {
private LoggingSystem loggingSystem;
public String setLogLevel( { String loggerName, String level)
loggingSystem.setLogLevel(loggerName, LogLevel.valueOf(level.toUpperCase()));
return “Log level for “ + loggerName + ” set to “ + level;
}
}
In this example, the setLogLevel
method allows you to change the log level of a specific logger by passing the logger name and desired log level via HTTP parameters. For instance, you can call this endpoint using curl:
curl -X POST "http://localhost:8080/set-log-level?loggerName=com.example.myapp&level=DEBUG"
This command will set the logging level for the com.example.myapp
package to DEBUG at runtime without restarting the application.
Getting the Current Log Level
If you want to check the current log level for a logger, you can implement a method to retrieve it:
import org.springframework.boot.logging.LogLevel;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
public class LogLevelQueryController {
private LoggingSystem loggingSystem;
public LogLevel getLogLevel( { String loggerName)
return loggingSystem.getLoggerConfiguration(loggerName).getEffectiveLevel();
}
}
This allows you to check the effective log level for any logger by making an HTTP GET request to /get-log-level?loggerName=com.example.myapp
.
Advanced Logging Features in Spring Boot
Using External Configuration Files
Spring Boot allows for externalized logging configuration, where you can use an external file to define your logging setup. For example, if you want to use a custom Logback configuration, you can place a logback-spring.xml
file in the src/main/resources
directory. Here’s a simple example:
<configuration>
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss} %-5level %logger{36} - %msg%n</pattern>
</encoder>
</appender>
<root level=“INFO”><appender-ref ref=“CONSOLE” />
</root>
</configuration>
This configuration customizes the log output format and sets the root log level to INFO. You can customize it further with different appenders, loggers, and rolling policies.
Conditional Logging with Profiles
In Spring Boot, you can define logging configurations for different profiles. For instance, you might want more verbose logging in your dev
profile and less logging in prod
. Here’s how you can set that up:
# application-dev.properties
logging.level.root=DEBUG
# application-prod.propertieslogging.level.root=ERROR
When running the application with the dev
profile, you’ll get DEBUG logs, while in the prod
profile, only ERROR logs will appear.
Conclusion
Logging is a critical component of any Spring Boot application, providing visibility into the internal workings and helping diagnose issues effectively. Spring Boot offers a highly flexible logging system, with default support for Logback, and makes it easy to customize log levels, formats, and output targets.
We explored several ways to configure logging, from simple property-based configurations to programmatically adjusting log levels using the LoggingSystem
class. We also covered how to test log severity and dynamically change log settings at runtime.
With these tools, you can fine-tune the logging in your Spring Boot application to meet the specific needs of your development, testing, and production environments, ensuring that your logs are both informative and manageable.
By mastering Spring Boot logging, you not only improve the maintainability of your application but also significantly enhance your ability to troubleshoot and optimize it in real-time.