DEV Community

DevCorner
DevCorner

Posted on

Logging in Spring Boot: A Comprehensive Guide to Centralized Logging( Using Docker )- PART 2

Introduction

Logging is an essential part of any application. It helps developers debug, monitor, and analyze application behavior. In this blog, we'll explore logging in Spring Boot, covering configuration, best practices, and centralized logging using the ELK stack.

1. Understanding Logging in Spring Boot

Spring Boot uses SLF4J as a facade for different logging frameworks like Logback (default), Log4j2, and Java Util Logging (JUL).

Logging Levels

  • TRACE – Most detailed information, for troubleshooting.
  • DEBUG – Detailed information useful for debugging.
  • INFO – General application information.
  • WARN – Indication of potential issues.
  • ERROR – Serious errors requiring immediate attention.

2. Folder Structure for a Spring Boot Logging Project

Here is the recommended folder structure:

springboot-logging/
│── src/
│   ├── main/
│   │   ├── java/com/example/logging/
│   │   │   ├── controller/
│   │   │   │   ├── LoggingController.java
│   │   │   ├── service/
│   │   │   │   ├── LoggingService.java
│   │   │   ├── LoggingApplication.java
│   │   ├── resources/
│   │   │   ├── application.properties
│   │   │   ├── logback.xml
│── logs/ (Generated log files)
│── docker-compose.yml (For ELK Stack)
│── pom.xml (For Maven Dependencies)
│── README.md
Enter fullscreen mode Exit fullscreen mode

3. Configuring Logging in Spring Boot

Using application.properties or application.yml

# application.properties
logging.level.root=INFO
logging.level.org.springframework=DEBUG
logging.file.name=logs/app.log
logging.file.path=logs
Enter fullscreen mode Exit fullscreen mode
# application.yml
logging:
  level:
    root: INFO
    org.springframework: DEBUG
  file:
    name: logs/app.log
Enter fullscreen mode Exit fullscreen mode

Using logback.xml for Custom Configuration

<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>
Enter fullscreen mode Exit fullscreen mode

4. Implementing Logging in a Spring Boot Application

Injecting Logger in a Spring Boot Service

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

@Service
public class LoggingService {
    private static final Logger logger = LoggerFactory.getLogger(LoggingService.class);

    public void process() {
        logger.info("Processing request...");
        try {
            // Simulated processing
        } catch (Exception e) {
            logger.error("Exception occurred: ", e);
        }
    }
}
Enter fullscreen mode Exit fullscreen mode

Logging in a Controller

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/api")
public class LoggingController {
    private static final Logger logger = LoggerFactory.getLogger(LoggingController.class);

    @GetMapping("/log")
    public String logExample() {
        logger.info("INFO: API hit at /log");
        logger.warn("WARN: Example warning");
        logger.error("ERROR: Example error");
        return "Check the logs for details.";
    }
}
Enter fullscreen mode Exit fullscreen mode

5. Centralized Logging with ELK Stack

Why Centralized Logging?

  • Aggregate logs from multiple services.
  • Real-time monitoring.
  • Improved debugging and analysis.

Setting Up ELK Stack with Docker

Create a docker-compose.yml file:

version: '3'
services:
  elasticsearch:
    image: docker.elastic.co/elasticsearch/elasticsearch:8.0.0
    container_name: elasticsearch
    environment:
      - discovery.type=single-node
    ports:
      - "9200:9200"
    networks:
      - elk

  logstash:
    image: docker.elastic.co/logstash/logstash:8.0.0
    container_name: logstash
    volumes:
      - ./logstash.conf:/usr/share/logstash/pipeline/logstash.conf
    ports:
      - "5000:5000"
    depends_on:
      - elasticsearch
    networks:
      - elk

  kibana:
    image: docker.elastic.co/kibana/kibana:8.0.0
    container_name: kibana
    ports:
      - "5601:5601"
    depends_on:
      - elasticsearch
    networks:
      - elk

networks:
  elk:
    driver: bridge
Enter fullscreen mode Exit fullscreen mode

Logstash Configuration (logstash.conf)

input {
  tcp {
    port => 5000
    codec => json
  }
}
output {
  elasticsearch {
    hosts => ["http://elasticsearch:9200"]
  }
}
Enter fullscreen mode Exit fullscreen mode

Sending Logs to Logstash from Spring Boot

Modify logback.xml:

<appender name="LOGSTASH" class="net.logstash.logback.appender.LogstashTcpSocketAppender">
    <destination>logstash:5000</destination>
    <encoder class="net.logstash.logback.encoder.LogstashEncoder"/>
</appender>

<root level="INFO">
    <appender-ref ref="LOGSTASH"/>
</root>
Enter fullscreen mode Exit fullscreen mode

Viewing Logs in Kibana

  • Start the ELK stack: docker-compose up -d
  • Open Kibana at http://localhost:5601
  • Create an index pattern to visualize logs.

6. Best Practices for Logging

  • Use Structured Logging (JSON format) for better parsing.
  • Avoid Logging Sensitive Information (e.g., passwords, tokens).
  • Use MDC (Mapped Diagnostic Context) for tracking requests across services.

Example: JSON Logging

<encoder class="net.logstash.logback.encoder.LogstashEncoder"/>
Enter fullscreen mode Exit fullscreen mode

7. Conclusion

Logging is crucial for debugging and monitoring applications. Using Spring Boot’s built-in support with centralized logging tools like ELK enhances visibility and troubleshooting.

Would you like a GitHub repository with a working example? 🚀

Top comments (0)