Dieses Handbuch soll Ihnen grundlegende Erkenntnisse und Vorgehensweisen vermitteln, damit Sie Ihre Dienste effektiver überwachen und Fehler beheben können.
Bei der Anwendungsentwicklung wird die Protokollierung häufig übersehen, ist aber ein entscheidender Bestandteil beim Aufbau eines robusten und beobachtbaren Systems. Richtige Protokollierungspraktiken können die Sichtbarkeit Ihrer Anwendung verbessern, Ihr Verständnis ihrer Funktionsweise vertiefen und die allgemeine Anwendungsintegrität verbessern.
Die Einbindung von Standardprotokollierungsmechanismen an den Einstiegspunkten Ihrer Anwendung ist äußerst nützlich. Diese automatische Protokollierung kann wichtige Interaktionen erfassen und möglicherweise die Argumente des Einstiegspunkts enthalten. Dabei ist jedoch äußerste Vorsicht geboten, da die Protokollierung vertraulicher Informationen wie Passwörter Datenschutz- und Sicherheitsrisiken bergen kann.
Jede wichtige Aktion Ihrer Anwendung muss einen Protokolleintrag erzeugen, insbesondere solche Aktionen, die ihren Status ändern. Dieser umfassende Protokollierungsansatz ist der Schlüssel zur schnellen Identifizierung und Behebung auftretender Probleme und bietet einen transparenten Einblick in den Zustand und die Funktionalität Ihrer Anwendung. Eine solche sorgfältige Protokollierung gewährleistet eine einfachere Diagnose und Wartung.
Die Verwendung geeigneter Protokollebenen ist für die Verwaltung und Interpretation der enormen Datenmengen, die von Ihrer Anwendung generiert werden, von entscheidender Bedeutung. Durch die Kategorisierung von Protokollen nach Schweregrad und Relevanz stellen Sie sicher, dass kritische Probleme umgehend identifiziert und behoben werden, während weniger dringende Informationen zugänglich bleiben, ohne Ihre Überwachungsbemühungen zu überfordern.
Nachfolgend finden Sie eine Richtlinie zur effektiven Verwendung von Protokollebenen:
Ebene | Beschreibung & Beispiele | Akzeptierte Nutzung | Nicht akzeptiert |
---|---|---|---|
| Schwerwiegende Ereignisse, die den Systembetrieb stoppen, z. B. verlorene Datenbankverbindung | Kritische Systemfehler | Nicht kritische Fehler, wie fehlgeschlagene Benutzeranmeldeversuche |
| Es liegt ein Problem vor, aber das System kann die Ausführung fortsetzen und den angeforderten Vorgang abschließen | Mögliche Probleme, die zu Problemen führen | Routinemäßige Statusänderungen |
| Einblicke in normale Anwendungsfunktionen, wie das Anlegen von Benutzerkonten oder das Schreiben von Daten | Statusänderungen | Nur-Lese-Operationen ohne Änderungen |
| Detaillierte Diagnoseinformationen, wie z. B. Prozessstart/-ende | Das Protokollieren von Prozessschritten verändert den Systemzustand nicht | Routinemäßige Zustandsänderungen oder hochfrequente Operationen |
| Die detaillierteste Ebene, einschließlich Methodenein- und -ausgängen | Den Ablauf und die Details eines Prozesses verstehen | Protokollierung vertraulicher Informationen |
Wenn Sie Aktionen in Ihrer Anwendung protokollieren, ist die Angabe der IDs der direkt beteiligten Entitäten entscheidend, um Protokollinformationen mit Datenbankdaten zu verknüpfen. Ein hierarchischer Ansatz hilft Ihnen dabei, schnell alle Protokolle zu finden, die mit einem bestimmten Teil Ihrer Anwendung verbunden sind, indem Elemente mit ihren übergeordneten Gruppen oder Kategorien verknüpft werden.
Anstatt beispielsweise nur die ID eines Chats zu protokollieren, wenn eine Nachricht nicht gesendet werden kann, sollten Sie auch die IDs des Chatrooms und des Unternehmens protokollieren, zu dem er gehört. Auf diese Weise erhalten Sie mehr Kontext und können die umfassenderen Auswirkungen des Problems erkennen.
Failed to send the message - chat=$roomId, chatRoomId=chatRoomId, company=$companyId
Nachfolgend sehen Sie ein Beispiel, wie Produktionsprotokolle bei Verwendung des hierarchischen Ansatzes aussehen könnten:
Durch die Standardisierung der Protokollformate in allen Teams können Sie Ihre Protokolle viel einfacher lesen und verstehen. Hier sind einige standardisierte Präfixe, die Sie berücksichtigen sollten:
Das Trennen von Variablennamen und -werten vom Hauptteil der Protokollmeldungen bietet mehrere Vorteile:
Log message - valueName=value
Nachfolgend finden Sie Beispiele für gut strukturierte Protokolleinträge, die den besprochenen Best Practices entsprechen:
2023-10-05 14:32:01 [INFO] Successful login attempt - userId=24543, teamId=1321312 2023-10-05 14:33:17 [WARN] Failed login attempt - userId=536435, teamId=1321312
Diese Beispiele zeigen:
Nachfolgend sehen Sie ein Beispiel dafür, wie Produktionsprotokolle bei Verwendung der vorgeschlagenen Vorgehensweisen aussehen könnten:
Um Protokolle effektiv einer bestimmten Benutzeraktion zuzuordnen, ist es wichtig, eine traceId
oder auch correlationId
in Ihre Protokolle aufzunehmen. Die ID sollte in allen Protokollen, die von der durch diesen Einstiegspunkt ausgelösten Logik generiert werden, konsistent bleiben und eine klare Ansicht der Ereignisabfolge bieten.
Während einige Überwachungsdienste wie Datadog standardmäßig eine Protokollgruppierung bereitstellen, kann diese auch manuell implementiert werden. In einer Kotlin-Anwendung mit Spring können Sie mithilfe eines HandlerInterceptor eine Trace-ID für REST-Anfragen implementieren.
@Component class TraceIdInterceptor : HandlerInterceptor { companion object { private const val TRACE_ID = "traceId" } override fun preHandle(request: HttpServletRequest, response: HttpServletResponse, handler: Any): Boolean { val traceId = UUID.randomUUID().toString() MDC.put(TRACE_ID, traceId) return true } override fun afterCompletion(request: HttpServletRequest, response: HttpServletResponse, handler: Any, ex: Exception?) { MDC.remove(TRACE_ID) } }
Dieser Interceptor generiert für jede Anforderung eine eindeutige traceId
, fügt sie zu Beginn der Anforderung zum MDC hinzu und entfernt sie nach Abschluss der Anforderung.
Durch die Implementierung einer solchen Protokollaggregation können Sie Protokolle ähnlich wie im folgenden Beispiel filtern
In vielen Systemen können Entitäten entweder UUID
oder Long
IDs als primäre Kennungen verwenden, während einige Systeme beide ID-Typen für unterschiedliche Zwecke verwenden. Um eine fundierte Entscheidung treffen zu können, ist es wichtig, die Auswirkungen der einzelnen Typen für Protokollierungszwecke zu verstehen.
Hier ist eine Aufschlüsselung der zu berücksichtigenden Dinge:
Lesbarkeit: Long
IDs sind leichter zu lesen und deutlich kürzer, insbesondere wenn sie nicht am oberen Ende des Long
Bereichs liegen.
Eindeutiger Wert: UUID
IDs sorgen für Eindeutigkeit im gesamten System, sodass Sie mithilfe einer ID nach Protokollen suchen können, ohne dass es zu ID-Kollisionen kommt. Kollisionen bedeuten hier, dass die Möglichkeit besteht, dass zwei Entitäten aus nicht miteinander verbundenen DB-Tabellen dieselbe Long
ID haben.
Systembeschränkungen : In Systemen, die lange Primärschlüssel als Entitäts-IDs verwenden, ist das Hinzufügen einer zufälligen UUID
ID normalerweise unkompliziert. In einem verteilten System mit UUID
Entitäts-IDs kann es schwierig oder kostspielig sein, Long
IDs speziell für die Protokollierung zu haben.
Vorhandene Protokolle: Konsistenz in der Art der in Protokollen verwendeten IDs ist entscheidend, zumindest pro Entität. Wenn das System bereits Protokolle für einige Entitäten erstellt und Sie nicht vorhaben, alle zu ändern, ist es besser, bei dem Typ zu bleiben, der bereits zur Identifizierung der Entität verwendet wird. Während einer Übergangsphase kann das Protokollieren beider IDs in Betracht gezogen werden, aber die dauerhafte Verwendung mehrerer IDs führt zu unnötiger Unordnung in den Protokollen.
Richtige Protokollierungspraktiken sind für eine effektive Servicebeobachtung unerlässlich. Durch die Integration umfassender Protokollierung, geeigneter Protokollebenen, Ablaufverfolgungs-IDs und standardisierter Protokollformate können Sie Ihre Fähigkeit zur Überwachung und Fehlerbehebung Ihrer Anwendungen erheblich verbessern. Diese Praktiken verbessern die Klarheit und Konsistenz Ihrer Protokolle und erleichtern so die schnelle Diagnose und Lösung von Problemen.
Vielen Dank, dass Sie sich die Zeit genommen haben, diesen Beitrag zu lesen!