Wir bauen eine neue App und möchten strukturierte Protokollierung einbinden. Mein ideales Setup wäre so etwas wie Serilog
für unseren C # -Code und Bunyan
für unseren JS. Diese würden in fluentd
eine beliebige Anzahl von Dingen einfließen und könnten dann herausgehen, dachte ich anfangs elasticsearch + kibana
. Wir haben bereits eine MySQL-Datenbank, daher bin ich kurzfristig mehr daran interessiert, dass Serilog + Bunyan-Setup und die Entwickler es verwenden, und wir können uns bei MySQL anmelden, während wir uns etwas mehr Zeit nehmen, um fließend und den Rest zu erledigen.
Einer unserer erfahreneren Programmierer würde es jedoch vorziehen, einfach Folgendes zu tun: select-Anweisungen für MySQL log.debug("Disk quota {0} exceeded by user {1}", quota, user);
verwenden log4net
und dann ausführen:SELECT text FROM logs WHERE text LIKE "Disk quota";
Welcher Ansatz ist jedoch besser und / oder welche Aspekte müssen bei der Auswahl des Protokollierungssystems berücksichtigt werden?
quelle
Antworten:
Der strukturierte Ansatz bringt zwei grundlegende Fortschritte mit sich, die mit Textprotokollen nicht ohne (manchmal extremen) zusätzlichen Aufwand emuliert werden können.
Ereignistypen
Wenn Sie mit log4net zwei Ereignisse schreiben, wie:
Diese erzeugen ähnlichen Text:
Bei der maschinellen Verarbeitung handelt es sich jedoch nur um zwei Zeilen mit unterschiedlichem Text.
Möglicherweise möchten Sie alle "Datenträgerkontingent überschritten" -Ereignisse finden, aber der vereinfachte Fall der Suche nach Ereignissen
like 'Disk quota%'
wird fallen, sobald ein anderes Ereignis eintritt, das wie folgt aussieht:Die Textprotokollierung wirft die Informationen weg, die wir ursprünglich über die Quelle des Ereignisses haben, und diese müssen rekonstruiert werden, wenn die Protokolle in der Regel mit immer ausgefeilteren Übereinstimmungsausdrücken gelesen werden.
Im Gegensatz dazu, wenn Sie die folgenden zwei Serilog- Ereignisse schreiben :
Diese erzeugen eine ähnliche Textausgabe wie die log4net-Version, hinter den Kulissen wird die
"Disk quota {Quota} exceeded by user {Username}"
Nachrichtenvorlage jedoch von beiden Ereignissen übertragen.Mit einer geeigneten Senke können Sie später Abfragen schreiben
where MessageTemplate = 'Disk quota {Quota} exceeded by user {Username}'
und genau die Ereignisse abrufen, bei denen das Datenträgerkontingent überschritten wurde.Es ist nicht immer bequem , die gesamte Nachrichtenvorlage mit jedem Protokollereignis zu speichern, so dass einige Senken hash die Nachrichtenvorlage in einen numerischen
EventType
Wert (zB0x1234abcd
), oder können Sie eine enricher in die Protokollierungs Pipeline in den dies selbst zu tun .Es ist subtiler als der nächste Unterschied, aber bei großen Log-Volumes enorm leistungsfähig.
Strukturierte Daten
Unter Berücksichtigung der beiden Ereignisse zur Speicherplatznutzung ist es möglicherweise einfach genug, Textprotokolle zu verwenden, um nach einem bestimmten Benutzer mit abzufragen
like 'Disk quota' and like 'DTI-Matt'
.Die Produktionsdiagnose ist jedoch nicht immer so einfach. Stellen Sie sich vor, es ist notwendig, Ereignisse zu finden, bei denen das Festplattenkontingent unter 125 MB lag?
Mit Serilog ist dies in den meisten Spülbecken mit einer Variante von:
Die Erstellung einer solchen Abfrage aus einem regulären Ausdruck ist möglich, wird jedoch schnell müde und ist in der Regel ein Maß für den letzten Ausweg.
Fügen Sie nun einen Ereignistyp hinzu:
Hier sehen Sie, wie diese Funktionen auf einfache Weise kombiniert werden, damit das Debuggen in der Produktion mit Protokollen als erstklassige Entwicklungsaktivität empfunden wird.
Ein weiterer Vorteil, der vielleicht nicht so einfach zu verhindern ist, aber nachdem das Debuggen in der Produktion aus dem Land der Regex-Hacker herausgenommen wurde, beginnen die Entwickler, Protokolle viel mehr zu bewerten und beim Schreiben mehr Sorgfalt und Überlegung walten zu lassen. Bessere Protokolle -> Anwendungen mit besserer Qualität -> Rundum mehr Glück.
quelle
Wenn Sie Protokolle zur Verarbeitung sammeln, sei es zum Parsen in einer Datenbank und / oder zum späteren Durchsuchen der verarbeiteten Protokolle, wird durch die Verwendung der strukturierten Protokollierung ein Teil der Verarbeitung einfacher / effizienter. Der Parser kann die bekannte Struktur ( z. B. JSON, XML, ASN.1, was auch immer) ausnutzen und Zustandsmaschinen zum Parsen verwenden, im Gegensatz zu regulären Ausdrücken (deren Kompilierung und Ausführung rechenintensiv (relativ) sein kann). Das Parsen von Freiform-Text, wie er von Ihrem Kollegen vorgeschlagen wurde, verlässt sich in der Regel auf reguläre Ausdrücke und darauf , dass sich dieser Text nicht ändert . Dies kann das Parsen von Freiformtext sehr anfällig machen ( dh das Parsen ist eng an den genauen Text im Code gekoppelt).
Betrachten Sie auch den Such- / Nachschlagefall, zB :
LIKE
Bedingungen erfordern Vergleiche mit jedemtext
Zeilenwert; Auch dies ist relativ rechenintensiv, insbesondere wenn Platzhalter verwendet werden:Bei der strukturierten Protokollierung sieht Ihre festplattenfehlerbezogene Protokollmeldung in JSON möglicherweise folgendermaßen aus:
Die Felder dieser Art von Struktur können sehr einfach zB SQL-Tabellenspaltennamen zugeordnet werden, was wiederum bedeutet, dass die Suche spezifischer / granularer sein kann:
Sie können Indizes für die Spalten platzieren, deren Werte voraussichtlich häufig durchsucht werden, sofern Sie
LIKE
für diese Spaltenwerte keine Klauseln verwenden . Je mehr Sie Ihre Protokollnachricht in bestimmte Kategorien unterteilen können, desto gezielter können Sie nachschlagen. Zum Beispiel, zusätzlich zu demerror_type
Feld / der Spalte im obigen Beispiel, könnten Sie auch sein"error_category": "disk", "error_type": "quota"
oder etwas Ähnliches machen.Je mehr Struktur , die Sie in Ihren Log - Meldungen haben, desto mehr Ihre Analyse / Suchsysteme (wie zum Beispiel
fluentd
,elasticsearch
,kibana
) können die Vorteile dieser Struktur, und ihre Aufgaben mit größerer Geschwindigkeit und weniger CPU / Speicher.Hoffe das hilft!
quelle
Sie werden von der strukturierten Protokollierung nicht viel profitieren, wenn Ihre App einige hundert Protokollnachrichten pro Tag erstellt. Sie werden es definitiv tun, wenn Sie einige hundert Protokollnachrichten pro Sekunde haben, die von vielen verschiedenen bereitgestellten Apps stammen.
Im Zusammenhang damit eignet sich das Setup, bei dem Protokollnachrichten im ELK-Stapel abgelegt werden, auch für die Skalierung, bei der die Protokollierung in SQL zu einem Engpass wird.
Ich habe das Setup von "Basic Logging and Searching" mit SQL
select .. like
und Regexps gesehen, die an ihre Grenzen gestoßen sind, wo sie auseinanderfallen - es gibt falsche Positive, Auslassungen, schrecklichen Filtercode mit bekannten Fehlern, die schwer zu pflegen sind und die niemand anfassen möchte. neue Protokollnachrichten, die nicht den Annahmen des Filters entsprechen, zögern, Protokollanweisungen im Code zu berühren, damit sie keine Berichte beschädigen usw.Es entstehen verschiedene Softwarepakete, um dieses Problem besser zu lösen. Es gibt Serilog, ich habe gehört, dass das NLog-Team sich das ansieht , und wir haben
StructuredLogging.Json
für Nlog geschrieben , und ich sehe auch, dass die neuen ASP.Net-Kernprotokollierungsabstraktionen "es Protokollierungsanbietern ermöglichen, ... strukturierte Protokollierung zu implementieren".Ein Beispiel mit StructuredLogging. Sie melden sich bei einem NLog-Logger wie folgt an:
Diese strukturierten Daten gehen an Kibana. Der Wert
1234
wird imOrderId
Feld des Protokolleintrags gespeichert . Sie können dann mit der kibana-Abfragesyntax nach z. B. allen Protokolleinträgen suchen, bei denen@LogType:nlog AND Level:Error AND OrderId:1234
.Message
undOrderId
sind jetzt nur noch Felder, die nach Bedarf nach genauen oder ungenauen Übereinstimmungen durchsucht oder nach Anzahl aggregiert werden können. Das ist leistungsstark und flexibel.Aus den Best Practices von StructuredLogging :
quelle