Implementing Logging

1. Understanding Spring Boot Logging Defaults (Logback)

Aspect Default
Framework SLF4J + Logback
Pattern %d %5p [%t] %c{1.} : %m%n
Output Console only
Bridges JCL, JUL, Log4j → SLF4J

2. Configuring Log Levels

Example: Log level per package

logging:
  level:
    root: INFO
    com.example: DEBUG
    org.hibernate.SQL: DEBUG
    org.hibernate.type.descriptor.sql.BasicBinder: TRACE
    org.springframework.security: DEBUG
Level Use
ERROR Failures requiring attention
WARN Anomalies, recoverable issues
INFO Lifecycle, key business events
DEBUG Diagnostic detail
TRACE Very fine-grained

3. Using SLF4J Logger Interface

Example: SLF4J parameterised logging

private static final Logger log = LoggerFactory.getLogger(OrderService.class);
log.info("Order placed id={} total={}", order.getId(), order.getTotal());
log.error("DB failure for order {}", id, ex); // exception last
if (log.isDebugEnabled()) log.debug("Heavy: {}", expensive());

4. Logging with Different Levels

Method When
log.error(msg, ex) Caught critical exception
log.warn(msg) Retry triggered, deprecated path
log.info(msg) Service started, request handled
log.debug(msg) Method entry/exit, payloads (no PII)

5. Configuring Logback XML

Example: Logback JSON encoder for production

<configuration>
  <include resource="org/springframework/boot/logging/logback/defaults.xml"/>
  <springProperty name="appName" source="spring.application.name"/>
  <appender name="JSON" class="ch.qos.logback.core.ConsoleAppender">
    <encoder class="net.logstash.logback.encoder.LogstashEncoder"/>
  </appender>
  <springProfile name="prod">
    <root level="INFO"><appender-ref ref="JSON"/></root>
  </springProfile>
</configuration>

6. Using Log4j2 as Alternative

Example: Switch logging to Log4j2

<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>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-log4j2</artifactId>
</dependency>

7. Logging to Files

Example: Log to file with rolling pattern

logging:
  file:
    name: /var/log/app.log
    path: /var/log
  pattern:
    file: "%d{ISO8601} %-5level [%thread] %logger{36} - %msg%n"

8. Configuring Log Rotation and Archiving

Property Use
logging.logback.rollingpolicy.max-file-size 10MB
logging.logback.rollingpolicy.max-history 30 (days)
logging.logback.rollingpolicy.total-size-cap 1GB
logging.logback.rollingpolicy.file-name-pattern app-%d{yyyy-MM-dd}.%i.log.gz

9. Using MDC for Contextual Logging

Example: Propagate trace ID with MDC filter

public class TraceFilter extends OncePerRequestFilter {
  @Override protected void doFilterInternal(HttpServletRequest req, HttpServletResponse res, FilterChain chain)
      throws IOException, ServletException {
    String tid = Optional.ofNullable(req.getHeader("X-Trace-Id")).orElse(UUID.randomUUID().toString());
    MDC.put("traceId", tid);
    try { chain.doFilter(req, res); }
    finally { MDC.clear(); }
  }
}
// pattern: %X{traceId}

10. Logging HTTP Requests and Responses

Tool Description
CommonsRequestLoggingFilter Built-in filter
logging.level.org.springframework.web=DEBUG Built-in MVC trace
Custom HandlerInterceptor Per-route logging
WebFilter (WebFlux) Reactive equivalent

11. Integrating with ELK Stack

ELK Pipeline

App → JSON logs → Logstash/Filebeat → Elasticsearch → Kibana
Component Role
Logstash/Filebeat Ship logs
Elasticsearch Index + search
Kibana Visualize

12. Using Structured Logging

Example: Logstash encoder dependency

<dependency>
  <groupId>net.logstash.logback</groupId>
  <artifactId>logstash-logback-encoder</artifactId>
  <version>7.4</version>
</dependency>

Example: Structured key-value log entry

log.atInfo()
   .setMessage("Order placed")
   .addKeyValue("orderId", id)
   .addKeyValue("total", total)
   .log();
Note: Spring Boot 3.4+ supports built-in structured logging via logging.structured.format.console=ecs|logstash|gelf.