Einführung
Eine effektive Protokollierungslösung ist entscheidend für den Erfolg jeder Anwendung. Winston ist eine vielseitige Protokollierungsbibliothek und eine beliebte Protokollierungslösung für Node.js-Anwendungen. Zu den Funktionen von Winston gehören Unterstützung für mehrere Speicheroptionen, Protokollstufen, Protokollabfragen und ein integrierter Profiler.
In diesem Tutorial verwenden Sie Winston, um eine Node/Express-Anwendung zu protokollieren, die Sie im Rahmen dieses Prozesses erstellen werden. Sie werden auch sehen, wie Sie Winston mit Morgan, einem weiteren beliebten HTTP-Anforderungsmiddleware-Logger für Node.js, kombinieren, um HTTP-Anforderungsdatenprotokolle mit anderen Informationen zusammenzufassen. Nach Abschluss dieses Tutorials wird auf Ihrem Ubuntu-Server eine kleine Node/Express-Anwendung ausgeführt, und Winston wird implementiert sein, um Fehler und Nachrichten in einer Datei und auf der Konsole zu protokollieren.
Voraussetzungen
Um diesem Tutorial folgen zu können, benötigen Sie:
-
Einen Ubuntu 20.04-Server mit einem sudo-fähigen Nicht-Root-Benutzer, den Sie durch Befolgen der Anleitung zum erstmaligen Einrichten des Servers einrichten können.
-
Node.js installiert mit dem offiziellen PPA (persönliches Paketarchiv), das in Anleitung zur Installation von Node.js unter Ubuntu 20.04, Option 2 erklärt wird.
Schritt 1 – Erstellen einer einfachen Node/Express-App
Winston wird oft zum Protokollieren von Ereignissen aus mit Node.js erstellten Webanwendungen verwendet. In diesem Schritt erstellen Sie eine einfache Node.js-Webanwendung unter Verwendung des Express-Frameworks. Sie verwenden express-generator
, ein Befehlszeilenwerkzeug, um eine Node/Express-Webanwendung schnell zum Laufen zu bringen.
Aufgrund der Installation des Node Package Manager während der Voraussetzungen können Sie den Befehl npm
verwenden, um express-generator
zu installieren:
Die -g
-Flagge installiert das Paket global, was bedeutet, dass es als Befehlszeilenwerkzeug außerhalb eines vorhandenen Node-Projekts/Moduls verwendet werden kann.
Mit express-generator
installiert, können Sie Ihre App mit dem express
-Befehl erstellen, gefolgt vom Namen des Verzeichnisses, das Sie für das Projekt verwenden möchten:
Für dieses Tutorial wird das Projekt myApp
genannt.
Hinweis: Es ist auch möglich, das express-generator
-Tool direkt auszuführen, ohne es zuerst global als systemweiten Befehl zu installieren. Führen Sie dazu diesen Befehl aus:
Der npx
-Befehl ist ein Befehlsausführer, der mit dem Node Package Manager geliefert wird und es einfach macht, Befehlszeilenwerkzeuge aus dem npm
-Register auszuführen.
Bei der ersten Ausführung wird es Sie fragen, ob Sie damit einverstanden sind, das Paket herunterzuladen:
Need to install the following packages:
express-generator
Ok to proceed? (y)
Antworten Sie mit y
und drücken Sie ENTER
. Jetzt können Sie npx express-generator
anstelle von express
verwenden.
Anschließend installieren Sie Nodemon, das die Anwendung automatisch neu lädt, wenn Sie Änderungen vornehmen. Eine Node.js-Anwendung muss jedes Mal neu gestartet werden, wenn Änderungen am Quellcode vorgenommen werden, damit diese Änderungen wirksam werden. Nodemon überwacht automatisch Änderungen und startet die Anwendung neu. Da Sie nodemon
als Befehlszeilenwerkzeug verwenden möchten, installieren Sie es mit der -g
-Flagge:
Um die Einrichtung der Anwendung abzuschließen, wechseln Sie in das Anwendungsverzeichnis und installieren Sie die Abhängigkeiten wie folgt:
Standardmäßig werden Anwendungen, die mit express-generator
erstellt wurden, auf Port 3000
ausgeführt. Daher müssen Sie sicherstellen, dass die Firewall den Port nicht blockiert.
Um den Port 3000
zu öffnen, führen Sie den folgenden Befehl aus:
Jetzt haben Sie alles, was Sie benötigen, um Ihre Webanwendung zu starten. Führen Sie dazu den folgenden Befehl aus:
Dieser Befehl startet die Anwendung auf Port 3000
. Sie können überprüfen, ob sie funktioniert, indem Sie Ihren Browser auf http://ihre_server_ip:3000
lenken. Sie sollten etwas Ähnliches sehen:
Zu diesem Zeitpunkt können Sie eine zweite SSH-Sitzung zu Ihrem Server starten, um den Rest dieses Tutorials durchzuführen, während die von Ihnen gerade gestartete Webanwendung in der Originalsitzung ausgeführt wird. Für den Rest dieses Artikels wird die anfängliche SSH-Sitzung, die aktuell die Anwendung ausführt, als Sitzung A bezeichnet. Alle Befehle in Sitzung A werden auf einem dunkelblauen Hintergrund wie diesem angezeigt:
Sie werden die neue SSH-Sitzung zum Ausführen von Befehlen und zum Bearbeiten von Dateien verwenden. Diese Sitzung wird als Sitzung B bezeichnet. Alle Befehle in Sitzung B werden auf einem hellblauen Hintergrund wie diesem angezeigt:
Sofern nicht anders angegeben, führen Sie alle verbleibenden Befehle in Sitzung B aus.
In diesem Schritt haben Sie die Grundanwendung erstellt. Als nächstes werden Sie sie anpassen.
Schritt 2 — Anpassen der Protokollvariablen
Während die Standardanwendung, die von express-generator
erstellt wurde, ein guter Anfang ist, müssen Sie die Anwendung anpassen, damit sie den richtigen Logger aufruft, wenn nötig.
express-generator
enthält das Morgan HTTP-Logging-Middleware, das Sie verwenden werden, um Daten zu allen HTTP-Anfragen zu protokollieren. Da Morgan Ausgabeströme unterstützt, passt es gut zu der in Winston integrierten Stream-Unterstützung, sodass Sie HTTP-Anforderungsdatenprotokolle mit allem anderen konsolidieren können, was Sie mit Winston protokollieren möchten.
Die express-generator
-Vorlage verwendet die Variable logger
, wenn auf das Paket morgan
Bezug genommen wird. Da Sie sowohl morgan
als auch winston
verwenden werden, die beide Logging-Pakete sind, kann es verwirrend sein, eines davon logger
zu nennen. Um anzugeben, welche Variable Sie möchten, können Sie die Variablendeklarationen ändern, indem Sie die Datei app.js
bearbeiten.
Um app.js
zur Bearbeitung zu öffnen, verwenden Sie nano
oder Ihren bevorzugten Texteditor:
Finden Sie die folgende Zeile in der Nähe des Anfangs der Datei:
Ändern Sie den Variablennamen von logger
in morgan
:
Mit diesem Update wird festgelegt, dass die deklarierte Variable morgan
die mit dem Morgan-Anforderungslogger verknüpfte require()
-Methode aufrufen wird.
Sie müssen herausfinden, wo die Variable logger
in der Datei noch referenziert wurde, und sie in morgan
ändern. Sie müssen auch das Protokollformat ändern, das vom morgan
-Paket verwendet wird, auf combined
, das das Standard-Apache-Protokollformat ist und nützliche Informationen in den Protokollen enthält, wie die IP-Adresse des entfernten Hosts und den User-Agent-HTTP-Request-Header.
Um dies zu tun, finden Sie die folgende Zeile:
Aktualisieren Sie sie zu folgender:
Diese Änderungen helfen Ihnen zu verstehen, welches Protokollierungspaket zu einem beliebigen Zeitpunkt nach der Integration der Winston-Konfiguration referenziert wird.
Wenn Sie fertig sind, speichern und schließen Sie die Datei.
Jetzt, da Ihre App eingerichtet ist, können Sie mit Winston arbeiten.
Schritt 3 — Installieren und Konfigurieren von Winston
In diesem Schritt werden Sie Winston installieren und konfigurieren. Sie werden auch die Konfigurationsoptionen erkunden, die als Teil des winston
-Pakets verfügbar sind, und einen Logger erstellen, um Informationen in eine Datei und auf die Konsole zu protokollieren.
Installieren Sie winston
mit dem folgenden Befehl:
Es ist hilfreich, alle Support- oder Hilfskonfigurationsdateien für Ihre Anwendungen in einem speziellen Verzeichnis aufzubewahren. Erstellen Sie einen config
-Ordner, der die Konfiguration von winston
enthält:
Als nächstes erstellen Sie einen Ordner, der Ihre Protokolldateien enthält:
Zuletzt installieren Sie app-root-path
:
Das Paket app-root-path
ist nützlich beim Festlegen von Pfaden in Node.js. Obwohl dieses Paket nicht direkt mit Winston zusammenhängt, ist es hilfreich beim Festlegen von Pfaden zu Dateien in Node.js. Sie werden es verwenden, um den Speicherort der Winston-Protokolldateien vom Stamm des Projekts aus anzugeben und um eine hässliche relative Pfadsyntax zu vermeiden.
Jetzt, da die Konfiguration für das Protokollieren vorhanden ist, können Sie Ihre Einstellungen definieren. Erstellen und öffnen Sie ~/myApp/config/winston.js
zum Bearbeiten:
Die Datei winston.js
wird Ihre winston
-Konfiguration enthalten.
Fügen Sie als nächstes den folgenden Code hinzu, um die Pakete app-root-path
und winston
zu benötigen:
Mit diesen Variablen können Sie die Konfigurationseinstellungen für Ihre Transports definieren. Transports sind ein Konzept, das von Winston eingeführt wurde und sich auf die Speicher-/Ausgabemechanismen bezieht, die für die Protokolle verwendet werden. Winston wird standardmäßig mit vier Kerntransports geliefert: Konsole, Datei, HTTP und Stream.
Sie konzentrieren sich in diesem Tutorial auf die Konsole und die Datei-Transports. Der Konsolen-Transport protokolliert Informationen in die Konsole, und der Datei-Transport protokolliert Informationen in eine angegebene Datei. Jede Transportdefinition kann Konfigurationseinstellungen wie Dateigröße, Protokollstufen und Protokollformat enthalten.
Hier eine kurze Zusammenfassung der Einstellungen, die Sie für jeden Transport verwenden werden:
level
: Level der zu protokollierenden Nachrichten.filename
: Die Datei, die zum Schreiben von Protokolldaten verwendet werden soll.handleExceptions
: Fangen und protokollieren von unbehandelten Ausnahmen.maxsize
: Maximale Größe der Protokolldatei in Bytes, bevor eine neue Datei erstellt wird.maxFiles
: Begrenzen Sie die Anzahl der erstellten Dateien, wenn die Größe der Protokolldatei überschritten wird.format
: Wie die Protokollausgabe formatiert wird.
Protokollstufen geben die Nachrichtenpriorität an und werden durch eine Ganzzahl angegeben. Winston verwendet npm
-Protokollstufen, die von 0 bis 6 priorisiert sind (höchste bis niedrigste):
- 0: Fehler
- 1: Warnung
- 2: Info
- 3: HTTP
- 4: Ausführlich
- 5: Debuggen
- 6: Albern
Beim Festlegen einer Protokollstufe für einen bestimmten Transport werden alle Nachrichten auf diesem oder höherem Niveau protokolliert. Wenn beispielsweise eine Stufe von Info
festgelegt wird, werden alle Nachrichten auf den Ebenen Fehler
, Warnung
oder Info
protokolliert.
Protokollstufen werden beim Aufrufen des Protokollers angegeben, was bedeutet, dass Sie den folgenden Befehl ausführen können, um einen Fehler aufzuzeichnen: Protokollfehler ('Testfehlermeldung')
.
Fügen Sie immer noch der Konfigurationsdatei den folgenden Code hinzu, um die Konfigurationseinstellungen für die Transports Datei
und Konsole
in der Winston
-Konfiguration zu definieren:
Füge als Nächstes den folgenden Code hinzu, um einen neuen winston
-Logger mit Datei- und Konsolentransporten zu instanziieren, wobei die Eigenschaften verwendet werden, die in der Variablen options
definiert sind:
Standardmäßig gibt morgan
nur auf der Konsole aus, daher definierst du eine Stream-Funktion, die in der Lage sein wird, die von morgan
generierte Ausgabe in die winston
-Protokolldateien zu leiten. Du wirst das Niveau info
verwenden, um die Ausgabe von beiden Transporten (Datei und Konsole) abzurufen. Füge den folgenden Code zur Konfigurationsdatei hinzu:
Füge schließlich den folgenden Code hinzu, um den Logger zu exportieren, damit er in anderen Teilen der Anwendung verwendet werden kann:
Die vollständige winston
-Konfigurationsdatei wird jetzt wie folgt aussehen:
Speichern und schließen Sie die Datei.
Sie haben jetzt den Logger konfiguriert, aber Ihre Anwendung ist sich dessen noch nicht bewusst, oder wie man ihn verwendet, daher müssen Sie den Logger in die Anwendung integrieren.
Schritt 4 — Integrieren von Winston in die Anwendung
Um Ihren Logger mit der Anwendung zu verwenden, müssen Sie sicherstellen, dass express
davon Kenntnis hat. Sie haben in Schritt 2 gesehen, dass Ihre express
-Konfiguration in app.js
liegt, daher können Sie Ihren Logger in diese Datei importieren.
Öffnen Sie die Datei zum Bearbeiten:
Fügen Sie eine Variablendeklaration für winston
in der Nähe der oberen Stelle der Datei mit den anderen require
-Anweisungen hinzu:
Der erste Ort, an dem du winston
verwenden wirst, ist mit morgan
. Immer noch in app.js
, finde die folgende Zeile:
Aktualisiere sie, um die stream
-Option einzuschließen:
Hier setzt du die stream
-Option auf das Stream-Interface, das du als Teil der winston
-Konfiguration erstellt hast.
Speichere und schließe die Datei.
In diesem Schritt hast du deine Express-Anwendung so konfiguriert, dass sie mit Winston funktioniert. Als nächstes wirst du die Protokolldaten überprüfen.
Schritt 5 — Zugriff auf Protokolldaten und Aufzeichnung von benutzerdefinierten Protokollnachrichten
Jetzt, da die Anwendung konfiguriert wurde, bist du bereit, einige Protokolldaten zu sehen. In diesem Schritt wirst du die Protokolleinträge überprüfen und deine Einstellungen mit einer Beispielbenutzerprotokollnachricht aktualisieren.
Wenn du die Seite im Webbrowser neu lädst, solltest du etwas Ähnliches wie die folgende Ausgabe in der Konsole von SSH-Sitzung A sehen:
Output[nodemon] restarting due to changes...
[nodemon] starting `node bin/www`
info: ::1 - - [25/Apr/2022:18:10:55 +0000] "GET / HTTP/1.1" 200 170 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/100.0.4896.127 Safari/537.36"
info: ::1 - - [25/Apr/2022:18:10:55 +0000] "GET /stylesheets/style.css HTTP/1.1" 304 - "http://localhost:3000/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/100.0.4896.127 Safari/537.36"
Hier gibt es zwei Protokolleinträge: der erste für die Anfrage an die HTML-Seite; der zweite für die zugehörige Stylesheet-Datei. Da jeder Transport so konfiguriert ist, dass er Protokolldaten auf Stufe info
verarbeitet, solltest du ähnliche Informationen auch im Dateitransport sehen, der sich unter ~/myApp/logs/app.log
befindet.
Um den Inhalt der Protokolldatei anzuzeigen, führe den folgenden Befehl aus:
tail
gibt die letzten Teile der Datei in Ihrem Terminal aus.
Sie sollten etwas Ähnliches wie das Folgende sehen:
{"level":"info","message":"::1 - - [25/Apr/2022:18:10:55 +0000] \"GET / HTTP/1.1\" 304 - \"-\" \"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/100.0.4896.127 Safari/537.36\"\n","timestamp":"2022-04-25T18:10:55.573Z"}
{"level":"info","message":"::1 - - [25/Apr/2022:18:10:55 +0000] \"GET /stylesheets/style.css HTTP/1.1\" 304 - \"http://localhost:3000/\" \"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/100.0.4896.127 Safari/537.36\"\n","timestamp":"2022-04-25T18:10:55.588Z"}
Die Ausgabe in der Datei „transport“ wird als JSON-Objekt geschrieben, da Sie winston.format.json()
in der format
-Option für die Konfiguration des Dateitransports verwendet haben. Sie können mehr über JSON in Eine Einführung in JSON erfahren.
Bisher zeichnet Ihr Logger nur HTTP-Anfragen und zugehörige Daten auf. Diese Informationen sind wichtig, um sie in Ihren Protokollen zu haben.
In Zukunft möchten Sie möglicherweise benutzerdefinierte Protokollmeldungen aufzeichnen, z. B. zum Erfassen von Fehlern oder zum Profilieren der Leistung von Datenbankabfragen. Als Beispiel werden Sie den Logger aus der Fehlerbehandlungsroutine aufrufen. Standardmäßig enthält das express-generator
-Paket bereits eine Fehlerbehandlungsroutine für 404
und 500
, mit der Sie arbeiten werden.
Öffnen Sie die Datei ~/myApp/app.js
:
Finden Sie den Codeblock am Ende der Datei, der so aussieht:
Dieser Abschnitt ist die endgültige Fehlerbehandlungsroutine, die letztendlich eine Fehlerantwort an den Client zurücksenden wird. Da alle serverseitigen Fehler durch diese Route laufen, ist es ein guter Ort, um den winston
-Logger einzuschließen.
Da du nun mit Fehlern umgehst, möchtest du den error
-Protokollpegel verwenden. Beide Transporte sind konfiguriert, um Nachrichten mit dem error
-Pegel zu protokollieren, sodass du die Ausgabe sowohl in den Konsolen- als auch in den Datei-Protokollen sehen solltest.
Sie können alles, was Sie möchten, im Protokoll einschließen, einschließlich Informationen wie:
err.status
: Der HTTP-Fehlerstatuscode. Wenn keiner vorhanden ist, standardmäßig auf500
setzen.err.message
: Details zum Fehler.req.originalUrl
: Die angeforderte URL.req.path
: Der Pfadteil der Anforderungs-URL.req.method
: HTTP-Methode der Anfrage (GET, POST, PUT usw.).req.ip
: Remote-IP-Adresse der Anfrage.
Aktualisieren Sie die Fehlerbehandlungsrouten, um das winston
-Protokollierung einzubeziehen:
Datei speichern und schließen.
Um diesen Prozess zu testen, versuchen Sie auf eine nicht vorhandene Seite in Ihrem Projekt zuzugreifen. Der Zugriff auf eine nicht vorhandene Seite löst einen 404-Fehler aus. Versuchen Sie in Ihrem Webbrowser, die folgende URL zu laden: http://Ihr_Server_IP:3000/foo
. Dank des von express-generator
erstellten Grundgerüsts ist die Anwendung so eingerichtet, dass sie auf einen solchen Fehler reagiert.
Ihr Browser wird eine Fehlermeldung wie diese anzeigen:
Wenn Sie sich die Konsole in SSH-Sitzung A ansehen, sollte dort ein Protokolleintrag für den Fehler vorhanden sein. Dank des angewendeten colorize
-Formats sollte es einfach sein, dies zu erkennen:
Output[nodemon] starting `node bin/www`
error: 404 - Not Found - /foo - GET - ::1
info: ::1 - - [25/Apr/2022:18:08:33 +0000] "GET /foo HTTP/1.1" 404 982 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/100.0.4896.127 Safari/537.36"
info: ::1 - - [25/Apr/2022:18:08:33 +0000] "GET /stylesheets/style.css HTTP/1.1" 304 - "http://localhost:3000/foo" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/100.0.4896.127 Safari/537.36"
Was den Datei-Logger betrifft, sollte das erneute Ausführen des Befehls tail
Ihnen die neuen Protokolleinträge anzeigen:
Sie werden eine Nachricht wie die folgende sehen:
{"level":"error","message":"404 - Not Found - /foo - GET - ::1","timestamp":"2022-04-25T18:08:33.508Z"}
Die Fehlermeldung enthält alle Daten, die Sie winston
speziell angewiesen haben, als Teil des Fehlerhandlers zu protokollieren. Diese Informationen umfassen den Fehlerstatus (404 – Nicht gefunden), die angeforderte URL (localhost/foo
), die Anforderungsmethode (GET
), die IP-Adresse, die die Anforderung stellt, und den Zeitstempel für die Anforderung.
Fazit
In diesem Tutorial haben Sie eine einfache Node.js-Webanwendung erstellt und eine Winston-Protokollierungslösung integriert, die als effektives Werkzeug zur Analyse der Leistung der Anwendung fungieren wird.
Sie können viel mehr tun, um robuste Protokollierungslösungen für Ihre Anwendungen zu erstellen, insbesondere wenn Ihre Anforderungen komplexer werden. Um mehr über Winston-Transporte zu erfahren, siehe Winston-Transportdokumentation. Um eigene Transporte zu erstellen, siehe Hinzufügen von benutzerdefinierten Transporten. Um einen HTTP-Endpunkt für die Verwendung mit dem HTTP-Kerntransport zu erstellen, siehe winstond
. Um Winston als Profiling-Tool zu verwenden, siehe Profiling.