Das Sammeln detaillierter Protokolle ist ein entscheidender Schritt beim Debuggen von verbindungsbezogenen Problemen mit MongoDB. In diesem kurzen Beitrag zeigen wir, wie Sie die Protokollierung für den MongoDB Node.JS-Treiber und Mongoose aktivieren. Wir beziehen uns in dieser Diskussion auf die Mongoose-Version 5.x und die Treiberversion 3.5.
Protokollieren des MongoDB Node.JS-Treibers
Der Protokollierungsmechanismus für den nativen Treiber wird in der Protokollierungsdokumentation gut erklärt. Wesentliche Merkmale sind:
- Es gibt 3 Protokollebenen –
debug
,info
,warn
underror
. Der Standardwert isterror
.info
ist eine anständige Wahl, wenn Sie versuchen, Probleme zu debuggen.debug
ermöglicht ein extrem detailliertes Tracing, verwenden Sie das also nur, wenn die Protokolle unterinfo
generiert werden Niveau sind nicht genug. - Standardmäßig gehen Protokolle zu
console.log()
Festlegen der Protokollebene
Im Code
const MongoClient = require('mongodb').MongoClient; const Logger = require('mongodb').Logger; Logger.setLevel('info');
Wenn Sie die Protokollebene im Code festlegen, können Sie auch Filter für bestimmte Klassen hinzufügen. Z. B.
Logger.filter('class', ['Connection', 'Pool']); // Log only Connection and Pool create things
Über Optionen
Der logger
und logLevel
auch über Verbindungsoptionen übergeben werden können, zeigen wir Ihnen ein Beispiel im Abschnitt Mongoose.
Protokollierung für Mongoose
Das Aktivieren der Debug-Level-Protokollierung für Mongoose ist einfach:
mongoose.set('debug', true)
Dies ermöglicht jedoch nur die Protokollierung von MongoDB-Vorgängen wie Abfragen und Aktualisierungen. Wenn Sie Probleme im Zusammenhang mit der Verbindung, dem Verbindungspool usw. debuggen möchten, ist dies nicht hilfreich.
Da Mongoose andererseits den MongoDB Node.JS-Treiber darunter verwendet, können wir, wenn wir die Protokollierung für den Treiber aktivieren, auch Protokolle vom Treiber erhalten. Der einfachste Weg, dies zu tun, besteht darin, protokollbezogene Optionen zu übergeben. Z. B.
// logging options for the driver var options = { logger: console.log, loggerLevel: 'info', poolSize: 10 } var uri = 'mongodb://user:pass@localhost:port,anotherhost:port,yetanother:port/mydatabase'; // with options mongoose.connect(uri, options);
Außer den Mongoose-spezifischen Optionen gibt Mongoose alle anderen Optionen an den Treiber weiter. Die Treiberdokumentation erläutert die folgenden Optionen:
loggerLevel
– Zeichenfolge – optional – Die Protokollierungsebene (Fehler/Warnung/Info/Debug)logger
– Objekt – Optional – Benutzerdefiniertes Logger-Objekt
Im obigen Beispiel übergeben wir den loggerLevel
als info
und der logger
als console.log
.
Benutzerdefinierter Logger
Obwohl die Treiberdokumentation ein Beispiel zum Schreiben benutzerdefinierter Logger enthält, ist sie nicht sehr nützlich. Normalerweise würden wir versuchen, diese Protokolle an eine andere Datei zu senden, abseits der Standardanwendungsprotokolle, und wir können die benutzerdefinierte Protokollfunktion verwenden, um dies zu tun.
Schaut man sich den Logging-Quellcode des Treibers an, wird folgendes deutlich:
- Standard-Logger ist die
console.log
- Der Logger muss eine Funktion sein
- Die Logger-Funktion benötigt zwei Argumente:
- Die Nachrichtenzeichenfolge im folgenden Format:
[LEVEL-className:pid] timestamp logMsg
Zum Beispiel:
[INFO-Server:9224] 1589439590772 server sg-example-100.servers.scalegrid.io:27017 fired event error out with message {"name":"MongoNetworkError"}
ausgelöst - Ein Zustandsobjekt, das die folgenden Informationen enthält:
var state = { type: 'warn', // level message: message, // log message className: className, // className pid: pid, date: dateTime };
Zum Beispiel:
{ type: 'info', message: 'server sg-rs-91.servers.scalegrid.io:27017 fired event error out with message {"name":"MongoNetworkError"}', className: 'Server', pid: 9224, date: 1589439590772 }
Um also einen benutzerdefinierten Logger zu schreiben, können Sie einfach eine Funktion schreiben, um ein Logging-Framework Ihrer Wahl zu verwenden, um diese Nachrichten in einem von Ihnen gewünschten Format zu protokollieren.
P>Hier ist ein ziemlich primitiver Bunyan-Logger, der als benutzerdefinierter Logger eingerichtet wurde:
var Logger = require('bunyan'); var log = Logger.createLogger({ name: "MongoDB Driver", streams: [ { stream: process.stdout, level: 'info' }, { stream: process.stdout, level: 'debug' }, { stream: process.stderr, level: 'error' } ], }); function mongoLogger(msg, state) { // console.log(msg, state); switch (state.type) { case 'debug': log.debug(state); break; case 'info': log.info(state); break; case 'warn': log.warn(state); case 'error': default: log.error(state); } }
Übergeben Sie es dann in Ihren Optionen:
var options = { logger: mongoLogger, loggerLevel : 'info' }
Die Ausgabe von console.log lautet dann:
[INFO-Server:9413] 1589442507330 server SG-example-85.servers.scalegrid.io:27017 fired event close out with message {"name":"MongoNetworkError","message":"getaddrinfo ENOTFOUND SG-example-85.servers.scalegrid.io SG-example-85.servers.scalegrid.io:27017","stack":"Error: getaddrinfo ENOTFOUND SG-example-85.servers.scalegrid.io SG-example-85.servers.scalegrid.io:27017\n at GetAddrInfoReqWrap.onlookup [as oncomplete] (dns.js:56:26)"} { type: 'info', message: 'server SG-example-85.servers.scalegrid.io:27017 fired event close out with message {"name":"MongoNetworkError","message":"getaddrinfo ENOTFOUND SG-example-85.servers.scalegrid.io SG-example-85.servers.scalegrid.io:27017","stack":"Error: getaddrinfo ENOTFOUND SG-example-85.servers.scalegrid.io SG-example-85.servers.scalegrid.io:27017\\n at GetAddrInfoReqWrap.onlookup [as oncomplete] (dns.js:56:26)"}', className: 'Server', pid: 9413, date: 1589442507330 }
Die Bunyan-Ausgabe lautet:
{"name":"MongoDB Driver","hostname":"<hostname>","pid":9413,"level":30,"type":"info","message":"server SG-example-85.servers.scalegrid.io:27017 fired event close out with message {\"name\":\"MongoNetworkError\",\"message\":\"getaddrinfo ENOTFOUND SG-example-85.servers.scalegrid.io SG-example-85.servers.scalegrid.io:27017\",\"stack\":\"Error: getaddrinfo ENOTFOUND SG-example-85.servers.scalegrid.io SG-example-85.servers.scalegrid.io:27017\\n at GetAddrInfoReqWrap.onlookup [as oncomplete] (dns.js:56:26)\"}","className":"Server","date":1589442507330,"msg":"","time":"2020-05-14T07:48:27.331Z","v":0}
Sie können dann alle Funktionen von Bunyan nutzen, um mit den Protokollen nach Belieben umzugehen, z. Senden an eine rotierende Datei, Trennen von Fehler- und Infomeldungen usw.
Wir hoffen, dass diese Anleitung zum Aktivieren der Protokollierung beim MongoDB Node.JS-Treiber und Mongoose für Sie bei Ihrer Einrichtung hilfreich war. Fühlen Sie sich frei, einen Kommentar im Kommentarbereich unten zu hinterlassen, wenn Sie Fragen haben oder Hilfe benötigen.