Fünf Möglichkeiten, die Qualität der Protokolle von Programmierern zu verbessern
In letzter Zeit sind eine Vielzahl neuer Tools aufgetaucht, die Programmierern das Verständnis von Protokollen erleichtern sollen, darunter Open-Source-Projekte wie Scribe und Logstash sowie Prepaid-Tools wie Splunk und Hosting-Dienste wie SumoLogic und PaperTrail. Gemeinsam ist diesen Tools, dass sie Protokolldaten bereinigen und aus einer großen Menge an Protokollen einige wertvollere Dateien extrahieren.
Fünf Tipps zur Verbesserung der Protokollqualität
Bei einer Sache können diese Tools jedoch nicht weiterhelfen, da sie vollständig auf den von Ihnen tatsächlich eingegebenen Protokolldaten basieren und wissen, wie die Qualität und Quantität der Daten sichergestellt werden muss der Benutzer. Daher kann es in kritischen Momenten schwierig werden, wenn Sie Code auf der Grundlage unvollständiger oder fehlender Protokolle debuggen müssen.
Um das Risiko zu verringern, dass dies passiert, sind hier fünf Tipps, die Sie beim Journaling beachten sollten:
1. Hallo, mein (Thread-)Name ist
Als Ringo ist das Thread-Namensattribut eines der wichtigsten unterschätzte Methoden in Java. Der Grund dafür ist, dass Thread-Namen meist beschreibenden Charakter haben. Allerdings stellt sich auch hier das Problem ein, ähnlich wie bei den Menschen selbst, ihnen bei der Benennung von Namen meist eine bestimmte Bedeutung zu geben. In Multithread-Protokollen spielt auch der Thread-Name eine Schlüsselrolle. Normalerweise protokollieren die meisten Protokollierungsframeworks den Namen des aktuell aufgerufenen Threads. Leider sehen wir normalerweise Namen wie http-nio-8080-exec-3, die einfach vom Thread-Pool oder Container zugewiesen werden.
Aus irgendeinem Grund haben wir dieses Missverständnis schon mehr als einmal gehört – Thread-Namen sind unveränderlich. Im Protokoll hingegen spielt der Thread-Name eine grundlegende Rolle und Sie sollten auf die korrekte Verwendung achten. Kombinieren Sie es beispielsweise mit einem bestimmten Kontext, etwa dem Namen des Servlets, einem aufgabenbezogenen Kontext oder einem dynamischen Kontext, etwa einer Benutzer- oder Nachrichten-ID.
In diesem Fall sollte die Codeschnittstelle wie folgt aussehen:
Thread.currentThread().setName(ProcessTask.class.getName() ": " message.getID);
Die erweiterte Version wird sein in die aktuellen Thread-lokalen Variablen für Threads geladen, den Protokoll-Appender konfiguriert und ihn automatisch zu Protokolleinträgen hinzugefügt.
Dies ist nützlich, wenn mehrere Threads in das Serverprotokoll schreiben, Sie sich aber auf einen einzelnen Thread konzentrieren müssen. Wenn Sie in einer verteilten/SOA-Umgebung arbeiten, können Sie sogar die einzigartigen Vorteile erkennen.
2. Verteilte Identifikatoren
In SOA oder einer nachrichtengesteuerten Architektur erstreckt sich die Aufgabenausführung wahrscheinlich über mehrere Maschinen. Bei der Bewältigung von Ausfällen in dieser Umgebung ist die Verbindung der relevanten Maschinen und deren Status von entscheidender Bedeutung für das Verständnis der Situation. Die meisten Protokollanalysatoren gruppieren diese Protokollnachrichten so, dass sie Teil der eigentlichen Protokollnachricht sein können, vorausgesetzt, Sie geben ihnen eine eindeutige Kennung.
Aus gestalterischer Sicht bedeutet dies, dass jeder eingehende Vorgang vom Eintritt in das System bis zum Abschluss des Vorgangs eine eigene eindeutige ID haben sollte. Beachten Sie, dass eine dauerhafte Kennung wie eine Benutzer-ID möglicherweise kein guter Container ist. Während der Protokollierung einer Protokolldatei kann ein Benutzer mehrere Aktionen ausführen, was die Isolierung eines bestimmten Flusses erschwert. UUIDs könnten eine gute Wahl sein. Sein Wert kann in den eigentlichen Thread-Namen oder als lokaler Speicher für den TLS-Thread geladen werden.
3. Verwenden Sie keine Textlaufwerke und protokollieren Sie keine Schleifen.
Oftmals werden Sie feststellen, dass ein Codeabschnitt in einer engen Schleife ausgeführt wird und entsprechende Protokollierungsvorgänge ausführt. Die Grundannahme ist, dass der Code nur begrenzt oft ausgeführt werden kann.
Läuft wahrscheinlich sehr gut. Wenn der Code jedoch unerwartete Eingaben erhält, wird die Schleife möglicherweise nicht unterbrochen. In diesem Fall haben Sie es nicht nur mit einer Endlosschleife zu tun (obwohl das schon schlimm genug ist), sondern Sie haben es mit Code zu tun, der unendlich viele Daten auf die Festplatte oder das Netzwerk schreibt.
In einem eigenständigen Szenario kann es zum Absturz eines Servers kommen, während in einem verteilten Szenario der gesamte Cluster betroffen ist. Loggen Sie sich also nach Möglichkeit nicht in einer engen Schleife ein. Dies gilt insbesondere beim Erkennen von Fehlern.
Das folgende Beispiel zeichnet eine Ausnahme in einer while-Schleife auf:
void read() {
while (hasNext()) {
try {
readData(
} Catch {); Ausnahme e) {
// das wird nicht empfohlen
logger.error(“error reading data“, e);
}
}
}
if readData löst eine Ausnahme aus auftritt und der hasNext-Rückgabewert wahr ist, werden hier unbegrenzt Protokolldaten geschrieben. Um dies zu beheben, stellen Sie sicher, dass nichts davon protokolliert wird:
void read() {
intExceptionsThrown = 0;
while (hasNext()) {
try {
readData( );
} Catch {Exception e) {
if (ExceptionsThrown < THRESHOLD) {
logger.error("error reading data", e); else {
// Jetzt wird der Fehler das System nicht ersticken.
}
}
}
}
Eine andere Möglichkeit besteht darin, den Protokolldatensatz aus der Schleife zu entfernen und zu speichern 1/Das letzte Ausnahmeobjekt und an anderer Stelle protokolliert.
4. Nicht gefangene Handler
Westeros hat die letzte Verteidigungsmauer und Sie haben Thread.uncaughtExceptionHandler. Versuchen Sie also, sie so oft wie möglich zu nutzen. Ohne die Installation dieser Handler erhalten Sie wenig wertvollen Kontext, wenn eine Ausnahme ausgelöst wird, und Sie haben keine Kontrolle darüber, wo Sie sie protokolliert haben, bevor sie endet.
Beachten Sie, dass Sie selbst in einem nicht abgefangenen Ausnahmehandler, bei dem es scheinbar keine Möglichkeit gibt, auf Variablen im (beendeten) Thread zuzugreifen, immer noch einen Verweis auf das eigentliche Thread-Objekt erhalten können. Wenn Sie bei Schritt 1 bleiben, erhalten Sie immer noch einen aussagekräftigen thread.getName()-Wert zum Protokollieren.
5. Externe Aufrufe erfassen
Immer wenn eine externe API aufgerufen wird, erhöht sich die Wahrscheinlichkeit einer JVM-Ausnahme erheblich. Dazu gehören Webdienste, HTTP, DB, Dateisystem, Betriebssystem und alle anderen JNI-Aufrufe. Nehmen Sie jeden Anruf ernst, denn es kann jederzeit explodieren. „Es ist sehr wahrscheinlich, dass es am selben Punkt passiert.“
Meistens ist die Ursache für einen externen API-Fehler eine unerwartete Eingabe, und deren Aufzeichnung im Protokoll ist der Schlüssel zur Behebung des Codes.
An dieser Stelle können Sie entscheiden, den Fehler nicht zu protokollieren und einfach eine Ausnahme auszulösen. Erfassen Sie in diesem Fall einfach die relevanten Parameter des Aufrufs und analysieren Sie sie in Informationen zu Ausnahmefehlern.
Stellen Sie einfach sicher, dass die Ausnahme bei einem Stapelaufruf einer höheren Ebene abgefangen und protokolliert wird.
Erhalten Sie die Original-PHP-Video-Tutorial-CD/„Essential PHP in Detail“ von LAMP Brothers kostenlos. Für weitere Informationen wenden Sie sich bitte an den offiziellen Website-Kundendienst:
http://www.lampbrother.net
[Brothers IT-Ausbildung] Lernen Sie PHP, Linux, HTML5, UI, Android und andere Video-Tutorials (Video mit Kursnotizen)!
Tutorial zum Herunterladen von Netzwerkfestplatten: http://pan.baidu.com/s/1mg8ANMg
Das Obige stellt fünf Möglichkeiten zur Verbesserung der Qualität von Programmierprotokollen vor, einschließlich inhaltlicher Aspekte. Ich hoffe, dass es für Freunde hilfreich ist, die sich für PHP-Tutorials interessieren.