Node.js Protokollierungshandbuch


Die erste Aufgabe, mit der Entwickler am häufigsten konfrontiert sind, wenn sie mit der Programmierung in JavaScript beginnen, ist das Protokollieren von Ereignissen im Konsolenprotokoll mithilfe der Methode console.log . Auf der Suche nach Informationen zum Debuggen von JavaScript-Code finden Sie Hunderte von Blog-Artikeln sowie Anweisungen zu StackOverflow, in denen Sie aufgefordert werden, Daten über die console.log Methode „einfach“ an die Konsole console.log . Dies ist eine so übliche Praxis, dass ich Regeln für die Codequalitätskontrolle einführen musste, z. B. no-console , um keine zufälligen Protokolleinträge im Produktionscode zu hinterlassen. Was aber, wenn Sie eine Veranstaltung speziell registrieren müssen, um zusätzliche Informationen bereitzustellen?

Dieser Artikel beschreibt verschiedene Situationen, in denen Sie Protokolle verwalten müssen. Es zeigt den Unterschied zwischen den Methoden console.log und console.error in Node.js und zeigt, wie die Protokollierungsfunktion an Bibliotheken übergeben wird, ohne die Benutzerkonsole zu überlasten.



Theoretische Grundlagen der Arbeit mit Node.js.


Die Methoden console.log und console.error können sowohl im Browser als auch in Node.js verwendet werden. Bei der Verwendung von Node.js ist jedoch eines zu beachten. Wenn Sie den folgenden Code in Node.js mit einer Datei namens index.js ,



und führen Sie es dann im Terminal mit dem node index.js . Die Ergebnisse der Befehlsausführung befinden sich übereinander:



Trotz der Tatsache, dass sie ähnlich erscheinen, verarbeitet das System sie unterschiedlich. Wenn Sie sich den Abschnitt über den console in der Node.js-Dokumentation console.log , stellt sich heraus, dass console.log das Ergebnis über stdout und console.error über stderr druckt.

Jeder Prozess kann standardmäßig mit drei Streams ( stream ) arbeiten: stdin , stdout und stderr . Der stdin Stream verarbeitet Eingaben für einen Prozess, z. B. Tastenklicks oder umgeleitete Ausgaben (mehr dazu weiter unten). Der Standard-Standardausgabestream dient zur Ausgabe von Anwendungsdaten. Schließlich ist der Standard- stderr Fehlerstrom so ausgelegt, dass Fehlermeldungen angezeigt werden. Wenn Sie herausfinden stderr , wofür stderr und wann Sie es verwenden sollen, lesen Sie diesen Artikel .

Kurz gesagt, es kann verwendet werden, um die Operatoren Umleitung ( > ) und Pipeline ( | ) zu verwenden, um mit Fehlern und Diagnoseinformationen getrennt von den tatsächlichen Ergebnissen der Anwendung zu arbeiten. Wenn Sie mit dem Operator > die Ausgabe des Befehlsergebnisses in eine Datei umleiten können, können Sie mit dem Operator 2> die Ausgabe des stderr Fehlerstroms in eine Datei umleiten. Dieser Befehl sendet beispielsweise Hello an die Datei hello.log und Bye bye an die Datei error.log .





Wann muss ich Ereignisse in das Protokoll schreiben?


Nachdem wir die technischen Aspekte der Protokollierung überprüft haben, gehen wir zu verschiedenen Szenarien über, in denen Sie Ereignisse registrieren müssen. In der Regel fallen diese Szenarien in eine von mehreren Kategorien:


Dieser Artikel beschreibt nur die letzten drei Szenarien, die auf Node.js basieren.

Protokollierung für Serveranwendungen


Es gibt mehrere Gründe für die Protokollierung von Ereignissen, die auf dem Server auftreten. Wenn Sie beispielsweise eingehende Anforderungen protokollieren, können Sie Statistiken darüber abrufen, wie oft Benutzer auf 404-Fehler stoßen, was der Grund dafür sein könnte oder welche User-Agent Clientanwendung verwendet wird. Sie können auch den Zeitpunkt und die Ursache des Fehlers ermitteln.

Um mit dem in diesem Teil des Artikels angegebenen Material zu experimentieren, müssen Sie einen neuen Katalog für das Projekt erstellen. Erstellen index.js im Projektverzeichnis index.js für den zu verwendenden Code und führen Sie die folgenden Befehle aus, um das Projekt zu starten und express installieren:



Wir haben einen Server mit Middleware eingerichtet, der jede Anforderung in der Konsole mithilfe der console.log Methode console.log . Wir index.js die folgenden Zeilen in die Datei index.js :



Dies verwendet console.log('%O', req) , um das gesamte Objekt im Protokoll zu protokollieren. Aus Sicht der internen Struktur verwendet die Methode util.forma t, das neben %O auch andere Platzhalter unterstützt. Informationen dazu finden Sie in der Dokumentation zu Node.js.

Wenn Sie den node index.js ausführen, um den Server zu starten und zu localhost : 3000 zu wechseln, zeigt die Konsole viele unnötige Informationen an:



Wenn Sie stattdessen console.log('%s', req) , um das Objekt nicht vollständig anzuzeigen, erhalten Sie nicht viele Informationen:



Sie können Ihre eigene Protokollierungsfunktion schreiben, die nur die erforderlichen Daten ausgibt. Zunächst müssen Sie jedoch entscheiden, welche Informationen benötigt werden. Trotz der Tatsache, dass der Fokus normalerweise auf dem Inhalt der Nachricht liegt, ist es in der Realität häufig erforderlich, zusätzliche Informationen zu erhalten, darunter:

  • Zeitstempel - um zu wissen, wann Ereignisse aufgetreten sind;
  • Computer- / Servername - wenn ein verteiltes System ausgeführt wird;
  • Prozesskennung - wenn mehrere pm2 ausgeführt werden, z. B. pm2 ;
  • Nachricht - eine tatsächliche Nachricht mit einigen Inhalten;
  • Stack-Trace - wenn ein Fehler protokolliert wird;
  • zusätzliche Variablen / Informationen.

Da in jedem Fall alles in die Streams stdout und stderr ausgegeben wird, muss ein Journal auf verschiedenen Ebenen geführt und Journaleinträge je nach Ebene konfiguriert und gefiltert werden.

Dies kann erreicht werden, indem Sie Zugriff auf verschiedene Teile des process und mehrere Codezeilen in JavaScript schreiben. Node.js ist jedoch insofern bemerkenswert, als es bereits über ein npm Ökosystem und mehrere Bibliotheken verfügt, die für diese Zwecke verwendet werden können. Dazu gehören:

  • pino ;
  • winston ;
  • brüllen ;
  • bunyan (diese Bibliothek wurde seit zwei Jahren nicht mehr aktualisiert).

Pino wird oft bevorzugt, weil es schnell ist und ein eigenes Ökosystem hat. Mal sehen, wie pino bei der Protokollierung helfen kann. Ein weiterer Vorteil dieser Bibliothek ist das express-pino-logger Paket, mit dem Sie Anforderungen registrieren können.

Installieren Sie pino und express-pino-logger :



Danach aktualisieren wir die Datei index.js , um den Ereignisprotokollierer und die Middleware zu verwenden:



In diesem Fragment haben wir eine Instanz des Ereignisprotokollierers für pino und an express-pino-logger , um eine neue plattformübergreifende Ereignisprotokollierungssoftware zu erstellen, mit der Sie app.use aufrufen app.use . Außerdem wurde console.log bei logger.info durch logger.info und logger.debug zur Route hinzugefügt, um verschiedene Ebenen des Protokolls anzuzeigen.

Wenn Sie den Server durch wiederholtes Ausführen von node index.js , erhalten Sie an der Ausgabe ein anderes Ergebnis, bei dem jede Zeile / Zeile im JSON-Format ausgegeben wird. Gehen Sie erneut zu localhost : 3000, um eine weitere neue Zeile im JSON-Format anzuzeigen.



Unter den Daten im JSON-Format finden Sie die zuvor genannten Informationen, z. B. einen Zeitstempel. Beachten Sie auch, dass die Meldung logger.debug nicht angezeigt wurde. Um es sichtbar zu machen, müssen Sie die Standardprotokollstufe ändern. Nach dem Erstellen einer Instanz der Logger-Ereignisregistrierung wurde der Wert process.env.LOG_LEVEL festgelegt. Dies bedeutet, dass Sie den Wert ändern oder den Standardinfowert akzeptieren können. LOG_LEVEL=debug node index.js Ausführen von LOG_LEVEL=debug node index.js ändern wir die Protokollstufe.

Zuvor muss das Problem des Ausgabeformats gelöst werden, das derzeit für die Wahrnehmung nicht sehr praktisch ist. Dieser Schritt ist beabsichtigt. Gemäß der pino Philosophie ist es aus Leistungsgründen erforderlich, die Verarbeitung von Journaleinträgen in einen separaten Prozess zu übertragen und die Ausgabe (unter Verwendung des Operators | ) zu übergeben. Der Prozess umfasst das Übersetzen der Ausgabe in ein für die menschliche Wahrnehmung geeigneteres Format oder das Hochladen in die Cloud. Diese Aufgabe wird von Transferwerkzeugen ausgeführt, die als transports . Lesen Sie in der Dokumentation zum transports Toolkit nach, warum pino Fehler nicht über stderr ausgegeben werden.

Verwenden Sie das pino-pretty Tool, um eine besser lesbare Version des Magazins anzuzeigen. Im Terminal ausführen:



Alle Protokolleinträge werden mit dem | zur Verfügung von pino-pretty , wodurch die Ausgabe "gelöscht" wird, die nur wichtige Informationen enthält, die in verschiedenen Farben angezeigt werden. Wenn Sie localhost : 3000 erneut abfragen, sollte eine debug Debugging-Meldung angezeigt werden.



Um Journaleinträge besser lesbar zu machen oder zu konvertieren, gibt es viele Übertragungswerkzeuge. Sie können sogar mit Emojis mit pino-colada angezeigt werden. Diese Tools sind nützlich für die lokale Entwicklung. Wenn der Server in Produktion ist, müssen Sie möglicherweise Protokolldaten mit einem anderen Tool übertragen , zur weiteren Verarbeitung mit > auf die Festplatte schreiben oder zwei Vorgänge gleichzeitig mit einem bestimmten Befehl ausführen, z. B. tee .

Das Dokument behandelt auch das Drehen von Protokolldateien, das Filtern und Schreiben von Protokolldaten in andere Dateien.

Bibliotheksjournal


Indem Sie nach Möglichkeiten suchen, die Protokollierung für Serveranwendungen effizient zu organisieren, können Sie dieselbe Technologie für Ihre eigenen Bibliotheken verwenden.

Das Problem ist, dass Sie im Fall der Bibliothek möglicherweise ein Protokoll für Debugging-Zwecke führen müssen, ohne die Client-Anwendung zu laden. Im Gegenteil, der Client sollte in der Lage sein, das Protokoll zu aktivieren, wenn ein Debugging erforderlich ist. Standardmäßig sollte die Bibliothek keine Ausgabe aufzeichnen, wodurch der Benutzer dieses Recht erhält.

Ein gutes Beispiel hierfür ist das express Framework. Viele Prozesse finden in der internen Struktur des express Frameworks statt, was das Interesse wecken kann, es während des Debuggens von Anwendungen eingehender zu untersuchen. In der Dokumentation zum express Framework heißt es, dass Sie DEBUG=express:* am Anfang des Befehls wie folgt hinzufügen können:



Wenn Sie diesen Befehl auf eine vorhandene Anwendung anwenden, werden viele zusätzliche Ausgaben angezeigt, die beim Debuggen hilfreich sind:



Diese Informationen können nur angezeigt werden, wenn das Debug-Protokoll aktiviert ist. debug gibt es ein debug Paket. Es kann verwendet werden, um Nachrichten in den "Namespace" zu schreiben. Wenn der Bibliotheksbenutzer diesen Namespace oder einen Platzhalter, der mit ihm übereinstimmt, in seine DEBUG Umgebungsvariable einfügt , werden die Nachrichten angezeigt. Zuerst müssen Sie die debug Bibliothek installieren:



Erstellen Sie eine neue Datei mit dem Namen random-id.j s, die die Bibliothek simuliert, und random-id.j den folgenden Code ein:



Als Ergebnis wird ein neuer debug Ereignisprotokollierer mit dem mylib:randomid , in dem dann zwei Nachrichten registriert werden. Wir verwenden es in index.js aus dem vorherigen Abschnitt:



Wenn Sie den Server erneut starten und diesmal DEBUG=mylib:randomid node index.js , werden die Debug-Protokolleinträge für unsere "Bibliothek" angezeigt:



Wenn Bibliotheksbenutzer Debug-Informationen in pino Protokolleinträge pino möchten, können sie eine vom Befehl pino-debug erstellte Bibliothek namens pino-debug , um diese Einträge korrekt zu formatieren.

Installieren Sie die Bibliothek:



Vor der ersten Verwendung von debug muss pino-debug initialisiert werden. Der einfachste Weg, dies zu tun, besteht darin, die Flags -r oder --require zu verwenden, um ein Modul anzufordern, bevor das Skript ausgeführt wird. Wir starten den Server mit dem Befehl neu (vorausgesetzt, pino-colada installiert):



Infolgedessen werden die Debug-Protokolleinträge der Bibliothek auf dieselbe Weise wie im Anwendungsprotokoll angezeigt:



Ausgabe der Befehlszeilenschnittstelle (CLI)


Der letzte Fall, den dieser Artikel behandelt, ist die Protokollierung für die Befehlszeilenschnittstelle. Vorzugsweise wird das Protokoll, das Ereignisse im Zusammenhang mit der Programmlogik aufzeichnet, vom Protokoll zum Registrieren von Befehlszeilenschnittstellendaten getrennt gehalten. Um Ereignisse im Zusammenhang mit der Programmlogik aufzuzeichnen, müssen Sie eine bestimmte Bibliothek verwenden, z. B. debug . In diesem Fall können Sie die Programmlogik über die Befehlszeilenschnittstelle wiederverwenden, ohne auf ein Szenario beschränkt zu sein.

Durch Erstellen einer Befehlszeilenschnittstelle mit Node.js können Sie verschiedene Farben, Blöcke mit variablen Werten oder Formatierungswerkzeuge hinzufügen, um der Benutzeroberfläche ein optisch ansprechendes Aussehen zu verleihen. Sie müssen jedoch mehrere Szenarien berücksichtigen.

Einer von ihnen zufolge kann die Schnittstelle im Kontext eines kontinuierlichen Integrationssystems (CI) verwendet werden. In diesem Fall ist es besser, auf die Farbformatierung und die visuell überlastete Darstellung der Ergebnisse zu verzichten. Bei einigen kontinuierlichen Integrationssystemen ist das CI Flag gesetzt. Mit dem is-ci Paket, das mehrere solcher Systeme unterstützt, können Sie überprüfen, ob Sie sich in einem kontinuierlichen Integrationssystem befinden.

Einige Bibliotheken, wie z. B. chalk , definieren kontinuierliche Integrationssysteme und überschreiben die Ausgabe von farbigem Text an die Konsole. Mal sehen, wie es funktioniert.

Installieren Sie chalk mit dem install chalk npm install chalk cli.js und erstellen Sie eine Datei mit dem Namen cli.js Fügen Sie die folgenden Zeilen in die Datei ein:



Wenn Sie dieses Skript jetzt mit dem node cli.js , werden die Ergebnisse in verschiedenen Farben dargestellt:



Wenn Sie das Skript jedoch mit CI=true node cli.js , wird die Farbformatierung der Texte abgebrochen:



In einem anderen denkwürdigen Szenario wird stdout im Terminalmodus ausgeführt, d. H. Daten werden an das Terminal ausgegeben. In diesem Fall können die Ergebnisse mit boxen gut angezeigt werden. Andernfalls wird die Ausgabe höchstwahrscheinlich in eine Datei oder an eine andere Stelle umgeleitet.

Sie können den Betrieb von stdin , stdout oder stderr Streams im Terminalmodus überprüfen, indem Sie sich das isTTY Attribut des entsprechenden Streams isTTY . Zum Beispiel process.stdout.isTTY . TTY bedeutet "Teletypewriter" und ist in diesem Fall speziell für das Terminal konzipiert.

Die Werte können für jeden der drei Threads variieren, je nachdem, wie die Node.js-Prozesse gestartet wurden. Detaillierte Informationen hierzu finden Sie in der Node.js-Dokumentation im Abschnitt „Eingabe / Ausgabe von Prozessen“ .

Mal sehen, wie sich der Wert von process.stdout.isTTY in verschiedenen Situationen process.stdout.isTTY . cli.js Datei cli.js , um sie zu überprüfen:



Führen Sie nun den node cli.js im Terminal aus und sehen Sie das Wort true node cli.js die Nachricht in farbiger Schrift angezeigt:



Danach führen wir den Befehl erneut aus, leiten die Ausgabe jedoch in eine Datei um und zeigen dann den Inhalt an:



Dieses Mal wurde das undefined Wort im Terminal angezeigt, gefolgt von einer Meldung in farbloser Schrift, da der stdout Stream es aus dem Terminalmodus umgeleitet hat. Hier verwendet chalk das isTTY supports-color Tool, das aus Sicht der internen Struktur die isTTY entsprechenden Streams überprüft.



Werkzeuge wie chalk erledigen diese Dinge selbstständig. Wenn Sie jedoch eine Befehlszeilenschnittstelle entwickeln, sollten Sie immer Situationen berücksichtigen, in denen die Schnittstelle in einem kontinuierlichen Integrationssystem funktioniert oder die Ausgabe umgeleitet wird. Mit diesen Tools können Sie die Befehlszeilenschnittstelle auf einer höheren Ebene verwenden. Beispielsweise können die Daten im Terminal strukturierter organisiert werden. Wenn isTTY undefined , wechseln Sie zu einer einfacheren Analysemethode.

Fazit


Die Verwendung von JavaScript und die Eingabe der ersten Zeile in das Konsolenprotokoll mit console.log recht einfach. Bevor Sie den Code in der Produktion bereitstellen, sollten Sie jedoch verschiedene Aspekte der Verwendung des Protokolls berücksichtigen. Dieser Artikel ist nur eine Einführung in die verschiedenen Methoden und Lösungen, die beim Organisieren des Ereignisprotokolls verwendet werden. Es enthält nicht alles, was Sie wissen müssen. Daher wird empfohlen, auf erfolgreiche Open Source-Projekte zu achten und zu überwachen, wie sie das Protokollierungsproblem gelöst haben und welche Tools verwendet werden. Und jetzt versuchen Sie, sich zu protokollieren, ohne Daten an die Konsole auszugeben.



Wenn Sie andere erwähnenswerte Tools kennen, schreiben Sie in den Kommentaren darüber.

Source: https://habr.com/ru/post/de461881/


All Articles