37 Verwendung von Correlation-IDs für Log-Tracing

Um Log-Nachrichten, die zu einem bestimmten Prozess oder Request gehören, leichter nachvollziehen zu können, werden häufig Correlation-IDs verwendet. Eine Correlation-ID ist eine eindeutige Kennung, die einem Request oder einer Session zugeordnet wird und in allen Log-Nachrichten, die während der Bearbeitung dieses Requests generiert werden, mitgeführt wird. Dies erleichtert das Auffinden und Verknüpfen von Log-Nachrichten, die zu einem bestimmten Vorgang gehören, insbesondere in verteilten Systemen oder Microservices-Architekturen.

37.1 Implementierung in Spring Boot

In einer Spring Boot-Anwendung kann die Verwendung von Correlation-IDs durch einen Interceptor oder Filter implementiert werden, der die ID am Anfang eines Requests setzt und sicherstellt, dass sie in allen nachfolgenden Log-Nachrichten erscheint.

37.1.1 Schritte zur Implementierung

  1. Generierung und Zuweisung der Correlation-ID: Zu Beginn eines jeden Requests wird geprüft, ob eine Correlation-ID bereits als Teil des Requests (z.B. im Header) vorhanden ist. Falls nicht, wird eine neue ID generiert. Diese ID wird dann für die Dauer des Requests im Kontext gehalten.

  2. Integration in das Logging-System: Die Correlation-ID wird so in das Logging-System integriert, dass sie automatisch jeder Log-Nachricht hinzugefügt wird.

37.1.2 Beispiel mit einem Servlet-Filter

Ein praktischer Ansatz zur Integration von Correlation-IDs ist die Verwendung eines Servlet-Filters, der jeden eingehenden Request bearbeitet.

import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import org.slf4j.MDC;

public class CorrelationIdFilter implements Filter {

    private static final String CORRELATION_ID_HEADER_NAME = "X-Correlation-ID";
    private static final String CORRELATION_ID_LOG_VAR_NAME = "correlationId";

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
            throws IOException, ServletException {
        if (request instanceof HttpServletRequest) {
            HttpServletRequest httpServletRequest = (HttpServletRequest) request;
            String currentCorrelationId = httpServletRequest.getHeader(CORRELATION_ID_HEADER_NAME);
            if (currentCorrelationId == null) {
                currentCorrelationId = UUID.randomUUID().toString();
            }
            MDC.put(CORRELATION_ID_LOG_VAR_NAME, currentCorrelationId);
        }
        try {
            chain.doFilter(request, response);
        } finally {
            MDC.remove(CORRELATION_ID_LOG_VAR_NAME);
        }
    }
}

In diesem Beispiel wird für jeden Request geprüft, ob eine Correlation-ID vorhanden ist. Ist dies nicht der Fall, wird eine neue generiert und im Mapped Diagnostic Context (MDC) von SLF4J gespeichert. MDC ist ein Mechanismus, der es ermöglicht, kontextspezifische Informationen (wie die Correlation-ID) zu Log-Nachrichten hinzuzufügen, ohne dass diese Informationen explizit an jede Logging-Anweisung übergeben werden müssen.

37.1.3 Logback-Konfiguration

Um die Correlation-ID in Log-Nachrichten einzuschließen, muss die Logback-Konfigurationsdatei (z.B. logback-spring.xml) angepasst werden:

<configuration>
    <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
        <encoder>
            <pattern>%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{36} - %X{correlationId} - %msg%n</pattern>
        </encoder>
    </appender>

    <root level="info">
        <appender-ref ref="STDOUT"/>
    </root>
</configuration>

Das %X{correlationId} im Log-Muster fügt die Correlation-ID aus dem MDC zu jeder Log-Nachricht hinzu.