Diagnose / Observability
Fehlersituationen treten insbesondere in verteilten Systemen auf und lassen sich nicht vermeiden. Ursache sind beispielsweise eine schlechte Netzwerk-Latenz, eine falsch konfigurierte Firewall oder ähnliches. Zur Analyse dieser Fehlerursachen sind geeignete Werkzeuge notwendig. Ein Werkzeug alleine ist hierbei nicht ausreichend, da die Analysen sehr vielschichtig sein können.
Das folgende Diagramm gibt einen Überblick über die Protokollierungsformen eines Schleupen.CS-Bausteins.
Diagnoseprotokoll
Die technische Fehlerprotokollierung zur Fehleranalyse wird durch den Baustein der Diagnoseprotokollierung bereitgestellt. Das Diagnoseprotokoll enthält dabei zeitbezogene Detailinformationen über den inneren Zustand der Software. Häufig werden hier detaillierte Fehlermeldungstexte hinterlegt, die in dieser Form nicht dem Endanwender präsentiert werden können oder sollen. Einträge im Diagnoseprotokoll werden je nach Bedeutung verschiedenen Stufen zugeordnet und können nach diesen gefiltert werden.
Die verschiedenen Stufen ("Level") der Protokollierung sind:
- Error - Diese Einträge beschreiben einen aus Sicht des Systems endgültig nicht behebbaren Fehler. Beispiel: Es ist eine Ausnahme ... aufgetreten.
- Warning - Diese werden geschrieben, wenn ein vom Idealfall abweichendes aber erwartetes Verhalten auftritt, welches aber durch die Software selbstständig gelöst oder entschieden werden kann. Beispiel: Die Komponente xy kann derzeit keine E-Mails versenden.
- Information - Informationseinträge sollen solche Informationen schreiben, die für den Betrieb der Software relevant sind. Beispiel: Der Dienst xy wurde gestartet.
- Verbose - Dieser Level soll verwendet werden, um Entwicklern die Möglichkeit zu geben, temporär den Ablauf inkl. Details der Applikation in einem Umfeld nachzuvollziehen, in dem kein Debugging zur Verfügung steht. Anderer Begriff: Tracing, wobei ein Tracing des Bausteins noch feingranularer ist (siehe Tracing von Ländern).
Das Diagnoseprotokoll wird üblicherweise von Administratoren und Mitarbeitern des Kundenservice, aber auch von Entwicklern eingesehen, insbesondere um Fehler oder andere außergewöhnliche Programmablaufsituationen im Nachhinein zu analysieren oder zu entdecken.
Technischer Ablauf
Das folgende Diagramm stellt einen Überblick der beteiligten Komponenten der Diagnoseprotokollierung dar.
Die wesentlichen Bausteine sind hierbei
- der Service (oder auch Workflow als Implementierung eines Process Service), der die Protokollierung über einen Endpunkt initiiert - bei Schleupen.CS-Services erfolgt das über einen sogenannten AOP-Interceptor; dieser AOP-Interceptor sendet die Diagnosemeldung ans ETW
- ein ETW-Ringpuffer, der die Diagnosemeldung temporär puffert - dieser dient der Performance-Optimierung und der Drosselung um Überlastung zu vermeiden. Dies ist nur für Extremfälle relevant, da über die Client-seitige Konfiguration stark gefiltert wird.
- ein Diagnoseprotokoll-Windows-Dienst (Schleupen Diagnostic Event Collector Service = LoggingService), der die Nachrichten aus dem Ringpuffer nimmt und diese schlussendlich in der Diagnoseprotokoll-Datenbank (= Logging-DB) ablegt
- dieser Dienst ergänzt die Diagnoseprotokolle um weitere detailliertere Informationen, füllt diese also auf (z.B. den Namen des Systemstrukturelements)
Diagnoseprotokolleinträge enthalten folgende Informationen:
- Protokolltext
- Zeitstempel
- Rechnername
- ausführender Benutzer (des Prozesses aus dem der Eintrag kommt)
- interaktiver Benutzer
- Systemstrukturelement
- Herkunft
- Softwarekomponente/Quelle
- Geschäftsprozessabschnitt-Id
- Geschäftsprozessschritt-Id
- Workflow-Instanz
- Parameter mit Name/Wert
- Meldungskürzel (für spätere Gruppierung)
- Meldungstyp (Meldung, SQL, WF-Trace, WS-Trace usw.)
- „Schweregrad“ (Fehler, Warnung, Info)
Das Diagnoseprotokoll ist in allen Services und Bausteinen in Schleupen.CS einheitlich angeschlossen. Auch Infrastruktur-Komponenten wie die Business-Process-Engine zum Hosting von Workflows, die Presentation-Engine, Service-Bus und viele weitere protokollieren entsprechend in das Diagnoseprotokoll.
Was wohin protokolliert wird, erfolgt über eine Client-seitige NLog-Konfiguration, die im Standard unter C:\ProgramData\Schleupen.CS\PI.Diagnostics liegt. Diese wird zentral über Set-CsDiagnosticsConfiguration
für alle CS-Hosts konfiguriert.
Tracing/Logging in Ländern
In den einzelnen Ländern kann ein Tracing für ein Land per Powershell aktiviert werden. Nach Aktivierung schreibt das Land dann für einen definierten Zeitraum Trace-/Log-Messages in eine entsprechende Datei.
Über die von der Schleupen.CS 3.0 Plattform bereitgestellten Cmdlets (Set-CsDiagnosticsConfiguration
, ...) kann das Logging temporär aktiviert werden.
Was wohin protokolliert wird, erfolgt über eine Client-seitige NLog-Konfiguration, die im Standard unter C:\ProgramData\Schleupen.CS\PI.Diagnostics liegt. Diese wird zentral über Set-CsDiagnosticsConfiguration
für alle CS-Hosts konfiguriert.
Datenänderungsprotokoll
Im Datenänderungsprotokoll werden sämtliche Änderungsvorgänge an Business-Entitäten protokolliert. Hierdurch wird eine zeit- und nutzerbezogene Nachvollziehbarkeit der Datensituation im System gewährleistet. Etwas genauer formuliert, werden mit dem Datenänderungsprotokoll Änderungen an Aggregaten protokolliert werden.
Anmerkung: Eine Business-Entität ist dabei in erster Näherung die Außensicht eines Aggregats. Daher werden diese Begriffe hier etwas ungenau synonym verwendet.
Das Datenänderungsprotokoll beantwortet typsicherweise die Frage „wer hat wann welche Änderungen an einer Business-Entität vorgenommen?“. Dazu werden jeweils alter und neuer Wert von Attributen an Business-Entitäten protokolliert und dargestellt. Das Datenänderungsprotokoll ist typischerweise für Fachnutzer und Wirtschaftsprüfer, die Recherchen über den Verlauf von Datenänderungen durchführen wollen, relevant und somit eine Compliance-Anforderung: Stammdatenänderungsprotokolle sollten sowohl im Einkauf als auch beispielsweise im Energievertrieb sowie im Bereich Personal gepflegt werden. Grundsätzlich geht es darum, zu jedem Zeitpunkt nachvollziehen zu können, welche Änderungen/Anpassungen durch wen durchgeführt wurden und wann Berechtigungen wie vergeben bzw. geändert wurden.
Um das Datenänderungsprotokoll zu nutzen, muss das Repository des entsprechenden Aggregats konfiguriert werden. Für jedes zu protokollierende Aggregat werden zunächst Datenänderungseinträge lokal erstellt und persistiert. Im weiteren Verlauf werden diese in eine Changelog Datenbank mit dem Datenänderungsprotokoll überführt.
Technischer Ablauf
Das folgende Diagramm zeigt grob die Funktionsweise des Datenänderungsprotokolls aus architektonischer Sicht:
Betrachten wir beispielsweise einen Entity Service, der ein Aggregat in seinem Schema persistiert. Gleichzeitig, d.h. in derselben Transaktion, protokolliert das Repository in dasselbe Schema. Dies ist notwendig, um verteilte Transaktionen zu vermeiden. Die Protokollierung der Änderungen wird mithilfe eines sogenannten Assemblers serialisert und als Blob gespeichert. Entsprechend ergibt sich hieraus, dass das Datenänderungsprotokoll in jeder fachlichen Datenbank eines Systemstrukturelements der Systemstruktur persistiert wird, auf der die Services des Bausteins (Land / GP-Komponente) per Serviceimplementierungsgruppe registriert sind und somit zur Laufzeit operieren.
Der Job Schleupen.CS.PI.AIF.ChangeLog.CollectChangeLogEventsActivityService verarbeitet dann diese Datenänderungen auf diesem Systemstrukturelement: Die Datenänderungseinträge werden regelmäßig in eine menschenlesbare Form konvertiert und in die Datenänderungsprotokoll-DB persistiert. Diese Changelog DB fungiert als Suchdatenbank, auf der die Suche der Benutzeroberflächen im Portal operiert.
Der ausgelieferte Ausführungsplan dieses Jobs ist: einmal pro Minute.
Der hierbei implementierte Service ist ein Beispiel eines Query Services, der die Datenänderungsprotokolle für alle Systemstrukturelemente aggregiert.
Ein weiterer Job lagert ältere Änderungsprotokolleinträge aus und überführt diese in eine Archivdatenbank.
Das Datenänderungsprotokoll hat einen Bezug zur Geschäftsprozessprotokollierung, so dass übergreifende Analysen einfacher möglich werden. Die Geschäftsprozessprotokollierung wird im Folgenden erläutert.
Geschäftsprozessprotokollierung
Das Geschäftsprozessprotokoll protokolliert alle Schritte eines ausgeführten Geschäftsprozesses bestehend aus Dialogabläufen, Workflows, Aufgaben, Jobs, Services usw. Damit kann der (tatsächliche) Ablauf von Geschäftsprozess(-Abschnitten) Schritt-für-Schritt zur Laufzeit und im Nachhinein nachvollzogen werden. Dies dient vor allem zu Diagnosezwecken, kann aber auch für Analysen verwendet werden.
Fachliche Abläufe und andere fachliche Protokollierungen gehören in das Geschäftsprozessprotokoll. Das Geschäftsprozessprotokoll kann in Geschäftsprozesskomponenten, also in der Orchestrierungsebene an Workflows und Benutzeroberflächen einfach angebunden werden.
Das folgende Diagramm zeigt schematisch den Aufbau des Geschäftsprozessprotokolls in Beziehung zu den wichtigsten protokollierenden Bausteinen:
Hieran ist ersichtlich, dass ein Geschäftsprozess in Geschäftsprozessabschnitte unterteilt ist, die wiederum aus Dialogabläufen, Workflows und Aufgaben bestehen.
Das Geschäftsprozessprotokoll kann insbesondere in folgenden Bausteinen angeschlossen werden:
- Workflow - Deklaration in Eigenschaften von BPMN-Diagrammen
- Dialog-Abläufen - Deklaration in Eigenschaften von BPMN-Diagrammen
- Service - programmatischer Anschluss per Schleupen.CS-Bibliothek
Das Geschäftsprozessprotokoll enthält detaillierte Ablaufinformationen zu einzelnen Workflow-Instanzen.
Die Einträge des Geschäftsprozessprotokolls werden wie in folgendem Diagramm dargestellt verarbeitet, so dass diese schlussendlich in die GP-Protocol-DB geschrieben werden. Dieses betrachten wir im Folgenden genauer.
Technischer Ablauf
Betrachten wir zudem den UI-Kontext: hier wird zur Protokollierung über einen Broker-Service in eine Queue geschrieben, aus der der durch den Business Event Dispatcher aufgerufene Service Schleupen.CS.PI.BPE.BusinessProcesses.Protocol.WriteProtocolActivityService_3.1 liest, der die Rohdaten unmittelbar temporär in eine Protokolldatenbank schreibt. Da hier nur wenige Daten geschrieben werden, ist der synchrone Aufruf über den Broker-Service zum einqueuen derzeit akzeptabel.
Die Protokolldatenbank ist die Infrastruktur-DB, die in der Systemstruktur unter dem Knoten System hängt.
Ähnlich ist der Anschluss aus dem Workflow-Kontext umgesetzt. Hier sind die Anforderungen hinsichtlich Resilienz höher, da Hintergrundverarbeitungsprozesse möglichst stabil sein müssen. Der Anschluss des Geschäftsprozessprotokolls erfolgt hier asynchron direkt per Messaging, so dass auf höhere Lastspitzen viel besser und dynamischer reagiert werden kann. Details hierzu: siehe Resilienz.
Der programmatische Anschluss in Services erfolgt mithilfe einer Schleupen.CS-Bibliothek. Diese fügt die Nachricht einer Queue im Message-Bus unter Zuhilfenahme einer Transactional-Outbox hinzu. Auch hier werden die Daten zunächst temporär gespeichert.
Anschließend nimmt der Windows-Dienst namens Schleupen Business Process Protocol Writer Service die temporären Einträge entgegen, bereitet diese in menschenlesbarer Form auf und schreibt diese in die Geschäftsprozessprotokolldatenbank.
Die Geschäftsprozessprotokolldatenbank ist ebenfalls die Infrastruktur-DB, die in der Systemstruktur unter dem Knoten System hängt.
Die Benutzeroberflächen zur Beauskunftung des Geschäftsprozessprotokolls greifen auf diese Geschäftsprotokolldatenbank zu.
Technisches Monitoring
Mithilfe des technischen Monitorings von Schleupen.CS 3.0 ist es für Benutzer möglich, Kennzahlen über den Betriebszustand einzusehen. Dies gilt insbesondere für schwer einsehbare Daten oder für im Cluster anfallende Informationen wie z.B. CPU-Auslastung, RAM-Nutzung, Rate der Aufrufe je Service, die durchschnittliche Aufrufdauer je Service, die Rate der abgeschlossenen Workflows oder ausstehende Job-Ausführungen. Diese Metriken können über ein zentrales Dashboard eingesehen werden, das über das Portal aufrufbar ist.
Technisch gesehen wird der sogenannte Elastic Stack verwendet, der die Daten über sogenannte Beats lokal auf einem Rechner sammelt und in einen Index gibt (Elasticsearch). Die Repräsentation und Such-Funktionalität für Benutzer wird über Kibana umgesetzt.
Das folgende Diagramm verdeutlicht, wie Windows-Dienste, die sogenannten Beats, die Daten der einzelnen Metriken auf den verschiedenen Hosts einsammeln und diese zum Server mit der Deploymentrolle MonitoringServer senden.
Telemetrie
Aus Sicht von Schleupen.CS 3.0 ist es auch sinnvoll, die verschiedenen Schleupen-Systeme egal ob on premise oder in der Schleupen.Cloud zu monitoren. Hierzu können diese Systeme derart eingerichtet werden, dass Diagnosedaten in ein zentrales Schleupen-System transportiert werden.
Die eigentliche Übertragung der Daten erfolgt täglich per FTPS durch den sogenannten Schleupen.CS Monitoring Sender, der ein Executable ist und als Windows-Aufgabe zyklisch ausgeführt wird.
Der Schleupen.CS Monitoring Receiver ist ebenfalls ein Executable und wird durch eine Windows-Aufgabe ausgeführt.
Die folgende Abbildung zeigt die Übertragung der Messwerte schematisch.
Distributed-Tracing
Reicht das Diagnoseprotokoll und das technische Monitoring zur Analyse von Fehlern und Fehlerzuständen in einem verteilten System nicht aus, kommt das sogenannte Distributed-Tracing zum Einsatz. Das technische Monitoring zeigt u.a. lediglich welche Prozesse bzw. Services ungewöhnlich langsam sind und wann ungewöhnlich viel Last entsteht (die sich über isolierte Tests auf Prozesse eingrenzen lässt), reicht aber nicht aus um zu verstehen, warum das so ist. So kann man zum Beispiel beim Distributed-Tracing SELECT N+1-Probleme auf Service-Ebene erkennen.
Mit dem Distributed-Tracing können Aufrufketten Service-übergreifend nachvollzogen und somit Zusammenhänge erkannt werden. Dabei werden 'Traces' quer durch das gesamte System aufgezeichnet, wobei die einzelnen Abschnitte (die sogenannten „Spans“) eine Baumstruktur mit zeitlichem Zusammenhang bilden.
Die folgende Abbildung zeigt einen Trace samt Spans.
Hieran ist gut ersichtlich, wie diese hierarchisch aufgebaut sind und welcher Service welchen Service in Kette aufruft.
Synchrone Aufrufketten sind wie in Resilienz beschrieben kritisch!
Der Anschluss des Distributed-Tracing erfolgt wie unten in der Abbildung ersichtlich über AOP-Interceptoren sowohl eingangs- als ausgangsseitig bei einem Microservice. Diese Interceptoren zeichnen die Spans. Der Anschluss in Workflows ist analog angebunden.
Die Protokollierung erfolgt dann in eine konfigurierte Jaeger-Instanz und kann über ein Jaeger-UI eingesehen werden.