Java >> Java Tutorial >  >> Tag >> Spring

Anmelden bei Spring Boot Microservices

Die Protokollierung ist ein wichtiger Bestandteil von Unternehmensanwendungen. Die Protokollierung hilft nicht nur bei der Untersuchung eines Problems, sondern auch bei der Erstellung relevanter Metriken. Diese Metriken sind aus geschäftlicher Sicht wichtig. Tatsächlich schreiben Unternehmen Service Level Agreements (SLAs) unter Verwendung dieser Metriken. In diesem Beitrag sprechen wir über die Anmeldung bei Spring Boot-basierten Microservices.

Wenn Sie neu bei Spring Boot und Microservices sind, empfehle ich Ihnen, etwas über Spring Boot und Microservices zu lesen.

Warum protokollieren wir und was protokollieren wir?

Die Anwendungen auf Produktionsebene können jederzeit aus verschiedenen Gründen fehlschlagen. Damit ein Entwickler solche Probleme rechtzeitig untersuchen kann, ist es wichtig, Protokolle verfügbar zu haben. Protokolle sind ein Schlüssel für die Wiederherstellung von Anwendungen.

Die Frage kommt, was loggen wir? Entwickler und Softwarearchitekten investieren genügend Zeit, um zu entscheiden, was protokolliert werden soll. Ebenso wichtig ist es, nicht viele Informationen zu protokollieren. Sie möchten keine wichtigen Informationen verlieren. Offensichtlich sollte man keine PII (Personal Identifiable Information) protokollieren. Ein Paradigma, das Entwickler verwenden können, lautet „Was hilft mir, Probleme im Code zu untersuchen, wenn die Anwendung fehlschlägt?“. Insbesondere wenn eine kritische Geschäftsentscheidung im Code kommentiert werden muss, ist es eine ebenso praktikable Option, diese Entscheidung zu protokollieren.

Gleichzeitig kann man eine zufällig generierte Ablaufverfolgungs-ID in den Protokollen verwenden, um die Anfrage-Antwort zu verfolgen. Der schwierigere Teil besteht darin, diese Idee während der gesamten Lebensdauer der Anwendung beizubehalten.

Protokollierung und Beobachtbarkeit

Microservices kommunizieren mit externen APIs, anderen Microservices. Von nun an ist es wichtig, die Einzelheiten einer solchen Kommunikation zu protokollieren. In ereignisgesteuerten Microservices können Details von Ereignissen protokolliert werden. Mit der Cloud-Infrastruktur ist es einfacher geworden, Details von Microservices zu protokollieren. Cloud-Infrastrukturen wie AWS bieten CloudWatch an, um diese Protokolle zu sammeln und dann den ELK-Stack zu verwenden, um die Protokolle zu überwachen. Observability-Tools wie New Relic, Sumo Logic verbinden sich jedoch mit verschiedenen Cloud-Infrastrukturen. Sie sammeln Protokolle und bieten die Flexibilität, Metriken basierend auf Protokollen anzuzeigen, abzufragen und zu erstellen.

Dementsprechend verfügen Entwickler über genügend Tools, um die Daten von Anwendungen zu protokollieren, um die Rückverfolgbarkeit und das Debugging zu verbessern.

Spring Boot-basierte Microservices anmelden

Schauen wir uns die Protokollierung in einem Spring Boot-basierten Microservice an. Wir werden einen einfachen Microservice erstellen und zeigen, welche Art von Protokollierungskonfiguration wir verwenden können.

Unsere Hauptklasse sieht wie folgt aus:

package com.betterjavacode.loggingdemo;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class LoggingdemoApplication {

	public static void main(String[] args) {
		SpringApplication.run(LoggingdemoApplication.class, args);
	}

}

Im Grunde hat der Microservice im Moment nichts. Unabhängig davon haben wir eine Hauptklasse und wir werden sehen, wie die Protokollierung ins Bild kommt.

Als Teil der Anwendung habe ich eine einzelne Abhängigkeit eingefügt

implementation 'org.springframework.boot:spring-boot-starter-web'

Diese Abhängigkeit umfasst auch spring-boot-starter-logging . spring-boot-starter-logging ist eine standardmäßige Protokollierungskonfiguration, die Spring Boot anbietet. Wir werden weitere Details prüfen.

Standardprotokollierungskonfiguration

spring-boot-stater-logging Abhängigkeit enthält slf4j als Logging-Fassade mit logback als Protokollierungsframework.

SLF4J ist eine Protokollierungsfassade, die von einer Reihe von Frameworks unterstützt wird. Der Vorteil der Verwendung dieser Fassade besteht darin, dass wir leicht von einem Rahmen zum anderen wechseln können. Logback ist das Standard-Framework in jeder Spring-Boot-Anwendung, aber wir können einfach zu Log4j, Log4J2 oder Java Util Logging wechseln.

spring-boot-starter-logging enthält die erforderlichen Bridges, die Protokolle von anderen Abhängigkeiten übernehmen und sie an das Protokollierungsframework delegieren.

Konfiguration der Logback-Protokollierung

Analog zu dem, was wir als Microservice und der Standardprotokollierung hinzugefügt haben, werden wir sehen, wie wir die Logback-Protokollierungskonfiguration verwenden können. Wenn wir keine Konfiguration bereitstellen, verwendet Spring Boot die Standardkonfiguration für logback . Es fügt die Protokolle mit der Protokollebene als info an die Konsole an . Protokollierungs-Frameworks helfen uns, die Protokolle an verschiedene Ziele wie Konsolen, Dateien, Datenbanken oder sogar Kafka weiterzugeben.

Mit der Konfigurationsdatei (logback-spring.xml ), können wir auch das Nachrichtenmuster festlegen. Wenn Sie log4j2 verwenden möchten statt Logback können Sie diesen Beitrag über Protokollierung und Fehlerbehandlung lesen.

Die folgende Konfigurationsdatei zeigt, wie wir protokollieren:

<configuration>
    <property name="LOGDIRECTORY" value="./logs" />
    <appender name="Console" class="ch.qos.logback.core.ConsoleAppender">
        <layout class="ch.qos.logback.classic.PatternLayout">
            <Pattern>
                %black(%d{ISO8601}) %highlight(%-5level) [%blue(%t)] %yellow(%C{1.}): %msg%n%throwable
            </Pattern>
        </layout>
    </appender>
    <appender name="RollingFile" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <file>${LOGDIRECTORY}/microservice.log</file>
        <encoder
                class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
            <Pattern>%d %p %C{1.} [%t] %m%n</Pattern>
        </encoder>

        <rollingPolicy
                class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <fileNamePattern>${LOGDIRECTORY}/archived/microservice-%d{yyyy-MM-dd}.%i.log
            </fileNamePattern>
            <timeBasedFileNamingAndTriggeringPolicy
                    class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
                <maxFileSize>5MB</maxFileSize>
            </timeBasedFileNamingAndTriggeringPolicy>
        </rollingPolicy>
    </appender>
    <root level="info">
        <appender-ref ref="RollingFile" />
        <appender-ref ref="Console" />
    </root>

    <logger name="com.betterjavacode" level="debug" additivity="false">
        <appender-ref ref="RollingFile" />
        <appender-ref ref="Console" />
    </logger>
</configuration>

Wir werden diese Datei analysieren, um zu verstehen, was jede Zeile in der Konfiguration tut.

Zuerst haben wir eine Eigenschaft LOGDIRECTORY konfiguriert Verweis auf ein physisches Verzeichnis auf dem Computer, in dem Protokolldateien gespeichert werden. Wir verwenden diese Eigenschaft in appender und rollingPolicy .

Verschiedene Protokollierungsoptionen

Anschließend verwenden wir appender von der Logback-Konfiguration, um zu konfigurieren, wo wir unsere Protokolle anhängen möchten. In diesem Fall haben wir für Console konfiguriert und File .

Für ConsoleAppnder verwenden wir ein Nachrichtenmuster, das ein Datum und eine Uhrzeit in schwarzer Farbe, eine Protokollebene in blau und ein Paket in gelber Farbe enthält. Die Protokollnachricht hat die Standardfarbe.

Für RollingFileAppender , haben wir eine Zeile, die angibt, wie der Dateiname lautet und wo er gespeichert wird. In diesem Fall melden wir uns in microservice.log an in LOGDIRECTORY . Die nächste Zeile gibt das Muster für die Protokollnachricht an.

  • %d – DatumUhrzeit
  • %p – Muster auf Protokollebene
  • %C – Klassenname
  • %t – Gewinde
  • %m – Nachricht
  • %n – Zeilentrenner

Danach definieren wir RollingPolicy . Wir möchten sicherstellen, dass wir die Informationen nicht in einer einzigen Datei protokollieren, die immer größer wird. Wir stoßen das Ausrollen der Logdatei ab einer Dateigröße von 5 MB an und speichern die alte Datei im Archivverzeichnis unter dem Namen microservice-date-number.log .

Weiter geht es mit der Protokollebene im nächsten Abschnitt.

Protokollebene konfigurieren

Der letzte Teil der Konfigurationsdatei gibt die Protokollebene an. Auf der Stammebene protokollieren wir alles unter INFO eben. Grundsätzlich protokolliert unsere Anwendung alle Nachrichten, die mit INFO geschrieben sind Log-Level im Code.

Aber die nächste Konfiguration ermöglicht es uns, die Protokollebene am Paket festzulegen. Im Paket beginnend mit com.betterjavacode , protokollieren Sie alle Nachrichten, die auf DEBUG sind Stufe.

Ausführen der Spring Boot-Anwendung

Wie das aussehen wird, sehen wir uns jetzt in unserem Demo-Microservice an.

Ich habe eine einfache RestController in meiner Anwendung, die company abruft Informationen wie folgt:

 package com.betterjavacode.loggingdemo.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;

import java.util.ArrayList;
import java.util.List;

@RestController
@RequestMapping("/v1/companies")
public class CompanyController
{
    private static final Logger LOGGER = LoggerFactory.getLogger(CompanyController.class);
    @GetMapping
    public List getAllCompanies()
    {
        LOGGER.debug("Getting all companies");

        List result = new ArrayList<>();

        result.add("Google");
        result.add("Alphabet");
        result.add("SpaceX");

        LOGGER.debug("Got all companies - ", result);

        return result;
    }
}

Führen Sie nun unsere Anwendung aus und greifen Sie auf die API http://localhost:8080/v1/companies/ zu , erhalten wir die Liste der Unternehmen, können uns aber auch wie folgt auf der Konsole anmelden:

Die Protokolldatei sieht wie folgt aus:


2021-12-04 18:20:32,221 INFO org.springframework.boot.StartupInfoLogger [main] Starting LoggingdemoApplication using Java 1.8.0_212 on YMALI2019 with PID 3560
2021-12-04 18:20:32,223 DEBUG org.springframework.boot.StartupInfoLogger [main] Running with Spring Boot v2.6.0, Spring v5.3.13
2021-12-04 18:20:32,224 INFO org.springframework.boot.SpringApplication [main] No active profile set, falling back to default profiles: default
2021-12-04 18:20:33,789 INFO org.springframework.boot.web.embedded.tomcat.TomcatWebServer [main] Tomcat initialized with port(s): 8080 (http)
2021-12-04 18:20:33,798 INFO org.apache.juli.logging.DirectJDKLog [main] Initializing ProtocolHandler ["http-nio-8080"]
2021-12-04 18:20:33,799 INFO org.apache.juli.logging.DirectJDKLog [main] Starting service [Tomcat]
2021-12-04 18:20:33,799 INFO org.apache.juli.logging.DirectJDKLog [main] Starting Servlet engine: [Apache Tomcat/9.0.55]
2021-12-04 18:20:33,875 INFO org.apache.juli.logging.DirectJDKLog [main] Initializing Spring embedded WebApplicationContext
2021-12-04 18:20:33,875 INFO org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext [main] Root WebApplicationContext: initialization completed in 1580 ms
2021-12-04 18:20:34,212 INFO org.apache.juli.logging.DirectJDKLog [main] Starting ProtocolHandler ["http-nio-8080"]
2021-12-04 18:20:34,230 INFO org.springframework.boot.web.embedded.tomcat.TomcatWebServer [main] Tomcat started on port(s): 8080 (http) with context path ''
2021-12-04 18:20:34,239 INFO org.springframework.boot.StartupInfoLogger [main] Started LoggingdemoApplication in 2.564 seconds (JVM running for 3.039)
2021-12-04 18:20:34,242 INFO com.betterjavacode.loggingdemo.LoggingdemoApplication [main] After starting the application.........
2021-12-04 18:20:39,526 INFO org.apache.juli.logging.DirectJDKLog [http-nio-8080-exec-1] Initializing Spring DispatcherServlet 'dispatcherServlet'
2021-12-04 18:20:39,526 INFO org.springframework.web.servlet.FrameworkServlet [http-nio-8080-exec-1] Initializing Servlet 'dispatcherServlet'
2021-12-04 18:20:39,527 INFO org.springframework.web.servlet.FrameworkServlet [http-nio-8080-exec-1] Completed initialization in 0 ms
2021-12-04 18:20:39,551 DEBUG com.betterjavacode.loggingdemo.controller.CompanyController [http-nio-8080-exec-1] Getting all companies
2021-12-04 18:20:39,551 DEBUG com.betterjavacode.loggingdemo.controller.CompanyController [http-nio-8080-exec-1] Got all companies - [Google, Alphabet, SpaceX]

Nachverfolgung der Anfragen

Zuvor habe ich erklärt, warum wir loggen. Wenn es mehrere Microservices gibt und jeder Microservice mit anderen und externen APIs kommuniziert, ist es wichtig, eine Möglichkeit zu haben, die Anforderung nachzuverfolgen. Eine Möglichkeit besteht darin, ein Muster in logback-spring.xml zu konfigurieren .

Eine andere Möglichkeit ist die Verwendung von Filter und MDC (Mapping Diagnostic Context). Grundsätzlich wird jede an die API eingehende Anfrage durch Filter abgefangen. In Filter können Sie der MDC-Karte eine eindeutige ID hinzufügen. Verwenden Sie das Protokollierungsmuster, das den Schlüssel aus der MDC-Zuordnung verwendet. Auf diese Weise enthält Ihre Anfrage Tracking-Informationen. Denken Sie daran, den Kontext von MDC zu löschen, sobald Ihre API auf den Client geantwortet hat.

Protokolle für die Überwachung konfigurieren

In der Unternehmenswelt besteht eine Möglichkeit zum Konfigurieren von Protokollen darin, die Protokolle in Dateien zu speichern und diese Dateien an einem zentralen Ort auf einem Cloud-Server zu speichern. AWS bietet eine einfachere Flexibilität, um diese Informationen in Cloud Watch aus Speicher S3 abzurufen, und dann kann man Tools wie Kibana und Elastic Search zum Überwachen der Protokolle und Metriken verwenden.

Schlussfolgerung

In diesem Beitrag haben wir detailliert beschrieben, wie die Protokollierung in Spring Boot-basierten Microservices verwendet wird. Wir haben auch über Logback gesprochen Konfiguration, die man verwenden kann, während man das Logback-Framework in der Spring Boot-Anwendung verwendet.

Die meisten dieser Praktiken sind Standard und stellen bei richtiger Befolgung die Fehlerbehebung und Überwachung von Anwendungen in einer Produktionsumgebung sicher.


Java-Tag