Micronaut Logging Example
Micronaut is a modern, JVM-based, full-stack framework for building modular, easily testable microservice and serverless applications. Logging is essential in any application for debugging and monitoring, and Micronaut provides flexible logging support out of the box. By default, Micronaut uses SLF4J with Logback as its underlying logging implementation. Let us delve into understanding Micronaut logging examples to better grasp how logging works within the Micronaut framework.
1. What is Micronaut?
Micronaut is a modern, JVM-based, full-stack framework specifically designed for building modular, high-performance microservices, serverless applications, and cloud-native systems. It offers first-class support for Java, Kotlin, and Groovy, making it a flexible choice for JVM developers.
Unlike traditional Java frameworks that rely heavily on runtime reflection and proxies (such as Spring), Micronaut uses compile-time annotation processing for dependency injection, AOP (Aspect-Oriented Programming), and configuration. This unique approach drastically reduces memory usage and startup time, making it ideal for microservices and serverless environments like AWS Lambda or Google Cloud Functions.
Micronaut also integrates seamlessly with GraalVM to enable ahead-of-time (AOT) compilation into native executables, further improving performance and resource efficiency.
Key features of Micronaut include:
- Compile-time dependency injection: No reflection or runtime proxies, leading to better performance and smaller memory footprint.
- Fast startup time and low memory usage: Ideal for microservices and containerized environments.
- Seamless integration with GraalVM: Supports building native images for ultra-fast execution and minimal memory use.
- Reactive and non-blocking: Includes built-in support for reactive programming using RxJava, Project Reactor, etc.
- Built-in HTTP server/client: Lightweight Netty-based web server and declarative HTTP clients with easy configuration.
- Cloud-native readiness: Support for service discovery, distributed tracing, configuration management, and more.
- Modular architecture: Encourages separation of concerns and better maintainability.
2. Logging Configuration
SLF4J (Simple Logging Facade for Java) is a logging facade that serves as a simple abstraction for various logging frameworks such as Logback, Log4j, and java.util.logging. Instead of forcing developers to choose a specific logging implementation at compile time, SLF4J allows them to plug in the desired logging framework at deployment time. This approach promotes flexibility and decouples application code from the underlying logging infrastructure.
Developers write logging statements using the SLF4J API, and the actual logging behavior is determined by the binding (e.g., slf4j-log4j12, slf4j-logback-classic) included in the classpath. SLF4J also supports parameterized logging, which helps improve performance by avoiding unnecessary string concatenation when log messages are not enabled for a specific level.
Overall, SLF4J provides a clean and efficient way to manage logging in Java applications, making it easier to switch or upgrade the logging backend without modifying the application’s core code.
You can configure it using a logback.xml file placed in the src/main/resources directory.
<configuration>
<!-- Console Appender -->
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>[%d{HH:mm:ss}] [%level] [%logger{20}] - %msg%n</pattern>
</encoder>
</appender>
<!-- Set the logging level for your application -->
<root level="TRACE">
<appender-ref ref="STDOUT" />
</root>
<!-- Specific logger for application package -->
<logger name="com.example" level="DEBUG" />
</configuration>
If your root logger level in logback.xml is set to INFO, then only the INFO, WARN, and ERROR messages will appear. To see all logs, including DEBUG and TRACE, configure the level as TRACE.
This makes it easy to control the verbosity of logs per environment — higher verbosity in development and minimal logging in production.
3. Logging Output
But before that, you will need to add the following dependency in the pom.xml.
<dependency> <groupId>ch.qos.logback</groupId> <artifactId>logback-classic</artifactId> </dependency>
This dependency ensures that the SLF4J binding to Logback is available at runtime. Micronaut uses SLF4J as the facade, and without an actual logging implementation like Logback on the classpath, logging calls won’t output anything. Let’s see how to log messages from a simple Micronaut controller.
package com.example;
import io.micronaut.http.annotation.Controller;
import io.micronaut.http.annotation.Get;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@Controller("/hello")
public class HelloController {
private static final Logger LOG = LoggerFactory.getLogger(HelloController.class);
@Get
public String index() {
LOG.trace("Trace log: entering index()");
LOG.debug("Debug log: inside index method");
LOG.info("Info log: responding with Hello World!");
LOG.warn("Warn log: sample warning message");
LOG.error("Error log: sample error message");
return "Hello World!";
}
}
3.1 Code Explanation
This Java code defines a simple HTTP controller using the Micronaut framework. The class HelloController is annotated with @Controller("/hello"), which maps HTTP requests sent to /hello to this controller. It contains a single method index() annotated with @Get, indicating it handles HTTP GET requests. Inside the method, the SLF4J Logger is used to log messages at various levels: trace, debug, info, warn, and error, demonstrating how logging can be used for tracing execution and diagnosing issues. The method concludes by returning the string "Hello World!", which serves as the HTTP response.
3.2 Code Output
You can run the application using the following command: ./mvnw mn:run. Once the application is running, hitting the endpoint curl http://localhost:8080/hello will trigger the code execution and produce the following output:
[12:00:01] [TRACE] [com.example.HelloController] - Trace log: entering index() [12:00:01] [DEBUG] [com.example.HelloController] - Debug log: inside index method [12:00:01] [INFO ] [com.example.HelloController] - Info log: responding with Hello World! [12:00:01] [WARN ] [com.example.HelloController] - Warn log: sample warning message [12:00:01] [ERROR] [com.example.HelloController] - Error log: sample error message
4. Conclusion
Micronaut makes it straightforward to integrate and configure logging using Logback. With minimal setup, you can define logging levels, customize formats, and enable detailed tracing across components. For production environments, you may extend this configuration to include file appenders, rolling logs, and integration with observability tools.



