Wie kann ich mithilfe der Node.js-Bibliothek Winston einen Zeitstempel zu Protokollen hinzufügen?

92

Ich möchte den Protokollen einen Zeitstempel hinzufügen. Was ist der beste Weg, um dies zu erreichen?

kolrie
quelle
Dies bleibt zu weit gefasst, da Sie dies NICHT vom Client-Computer aus tun können.
Joshua

Antworten:

112

Ich habe mich selbst mit dem gleichen Thema befasst. Es gibt zwei Möglichkeiten, wie ich dies tun konnte.

Wenn Sie Winston einschließen, wird normalerweise standardmäßig ein Konsolentransport hinzugefügt. Damit Zeitstempel in diesem Standardfall funktionieren, musste ich entweder:

  1. Entfernen Sie den Konsolentransport und fügen Sie ihn erneut mit der Zeitstempeloption hinzu.
  2. Erstellen Sie Ihr eigenes Logger-Objekt mit der Zeitstempeloption true.

Der Erste:

var winston = require('winston');
winston.remove(winston.transports.Console);
winston.add(winston.transports.Console, {'timestamp':true});

Die zweite und sauberere Option:

var winston = require('winston');
var logger = new (winston.Logger)({
    transports: [
      new (winston.transports.Console)({'timestamp':true})
    ]
});

Einige der anderen Optionen für den Konsolentransport finden Sie hier :

  • Ebene: Ebene der Nachrichten, die dieser Transport protokollieren soll (Standard 'Debug').
  • Silent: Boolesches Flag, das angibt, ob die Ausgabe unterdrückt werden soll (Standardwert false).
  • colorize: Boolesches Flag, das angibt, ob die Ausgabe koloriert werden soll (Standardwert false).
  • Zeitstempel: Boolesches Flag, das angibt, ob der Ausgabe Zeitstempel vorangestellt werden sollen (Standardwert false). Wenn die Funktion angegeben ist, wird ihr Rückgabewert anstelle von Zeitstempeln verwendet.
Imagreenplant
quelle
1
Erstaunlich und einfach zugleich. Danke dir!
Kolrie
7
Das ist toll. Normalerweise verpacke ich dies in eine dedizierte Datei, damit ich meinen konfigurierten Logger problemlos aus jeder Datei abrufen kann, dh ich füge den obigen Code (Option 2) in eine neue Datei logger.js ein, gefolgt von module.exports = logger; dann mache ich aus jeder Datei var logger = require ('./ logger.js') und kann dann logger.info ('hallo') aus jeder Datei machen und die gleiche Konfiguration von Winston erhalten.
JHH
TypeError: (Zwischenwert) ist keine Funktion
Urasquirrel
79

Die obigen Antworten haben bei mir nicht funktioniert. Wenn Sie versuchen, Ihren Protokollen mit der neuesten Version von Winston - 3.0.0-rc1 einen Zeitstempel hinzuzufügen, hat dies wie ein Zauber funktioniert:

    const {transports, createLogger, format} = require('winston');

    const logger = createLogger({
        format: format.combine(
            format.timestamp(),
            format.json()
        ),
        transports: [
            new transports.Console(),
            new transports.File({filename: 'logs/error/error.log', level: 'error'}),
            new transports.File({filename: 'logs/activity/activity.log', level:'info'})
        ]
    });

Ich habe 'format.combine ()' verwendet. Da ich für alle meine Transporte einen Zeitstempel benötigte, habe ich die Formatierungsoption im createLogger und nicht in jedem Transport hinzugefügt. Meine Ausgabe auf der Konsole und in der Datei (activity.log) lautet wie folgt:

{"message":"Connected to mongodb","level":"info","timestamp":"2018-02-01T22:35:27.758Z"}
{"message":"Connected to mongodb","level":"info","timestamp":"2018-02-01T22:35:27.758Z"}

Wir können diesem Zeitstempel wie gewohnt eine Formatierung in 'format.combine ()' hinzufügen, indem wir Folgendes verwenden:

format.timestamp({format:'MM-YY-DD'})
Siva Kiran
quelle
Vielen Dank! Das hat bei mir funktioniert.
JOTT
14

Das können wir auch

var winston = require('winston');
    const { createLogger, format, transports } = require('winston')
    var config = require('../configurations/envconfig.js');

    var loggerLevel = process.env.LOGGERLEVEL ||  config.get('LOGGERLEVEL');

    var logger = winston.createLogger({ format: format.combine(
            format.timestamp({
                format: 'YYYY-MM-DD HH:mm:ss'
            }),
            format.printf(info => `${info.timestamp} ${info.level}: ${info.message}`+(info.splat!==undefined?`${info.splat}`:" "))
        ), 
        transports: [
            new (winston.transports.Console)({ level: loggerLevel }),
           ]
    });
    module.exports = logger;
Biswadev
quelle
Funktioniert das auch für logger.info('Message', someObject)? Ich habe ein benutzerdefiniertes Format mit Mähdrescher eingerichtet und kann das someObjectin der Protokollnachricht enthaltene Format anscheinend nicht erhalten .
Etwas am
1
Ich konnte someObjectmithilfe der folgenden printf-Anweisung aufgenommen werden ${info.timestamp} [${info.level.toUpperCase()}]: ${info.message} ${JSON.stringify(info)}. Es enthält die Ebene, den Zeitstempel und die Nachricht, die ich vermutlich löschen könnte.
Etwas am
9

Sie können das integrierte util und für immer verwenden , um die Protokollierung mit Zeitstapel für Ihren nodejs-Server zu erreichen. Wenn Sie einen Server starten, fügen Sie die Protokollausgabe als Teil des Parameters hinzu:

forever start -ao log/out.log server.js

Und dann können Sie util in Ihre server.js schreiben

server.js

var util = require('util');
util.log("something with timestamp");

Die Ausgabe sieht in der Datei out.log ungefähr so ​​aus:

out.log

15 Mar 15:09:28 - something with timestamp
KTU
quelle
1
Überspringt leider die util.error()Zeitstempelung der Ausgabe.
Saran
4

Obwohl mir Winston nicht bekannt ist, ist dies ein Vorschlag. Ich verwende log4js für die Protokollierung und meine Protokolle sehen standardmäßig so aus

[2012-04-23 16:36:02.965] [INFO] Development - Node Application is running on port 8090
[2012-04-23 16:36:02.966] [FATAL] Development - Connection Terminated to  '127.0.0.1' '6379'

Entwicklung ist die Umgebung meines Knotenprozesses und [INFO | FATAL] ist die Protokollebene

Das Verwalten verschiedener Profile für die Protokollierung ist in log4js möglich. Ich habe Entwicklungs- und Produktionsprofile. Es gibt auch Logger-Typen wie Rolling File Appender, Console Appender usw. Als Addon werden Ihre Log-Dateien basierend auf der Log-Ebene [Trace, Info, Debug, Error, Fatal] bunt sein;)

log4js überschreibt Ihre console.log. Dies ist ein konfigurierbarer Parameter, der jetzt in 0.5+ enthalten ist

Tamil
quelle
Zu Ihrer Information: Neuere Versionen von log4js-node (0.5+) überschreiben console.log nicht automatisch.
Jeff Hiltz
@ Jeffhiltz Ya Sie haben Recht :) Jetzt ist es ein konfigurierbarer Parameter
Tamil
2

Manchmal ist das Standard-Zeitstempelformat für Sie nicht geeignet. Sie können es mit Ihrer Implementierung überschreiben.

Anstatt

var winston = require('winston');
var logger = new (winston.Logger)({
transports: [
  new (winston.transports.Console)({'timestamp':true})
]
});

Du kannst schreiben

var winston = require('winston');
var logger = new (winston.Logger)({
transports: [
  new (winston.transports.Console)({
     'timestamp': function() {
        return <write your custom formatted date here>;
     }
  })
]
});

Weitere Informationen finden Sie unter https://github.com/winstonjs/winston#custom-log-format

walv
quelle
2

Wir könnten den Konsolenstempel verwenden, um der vorhandenen Konsole Zeitstempel und Protokollstufe hinzuzufügen: require('console-stamp')(console, '[yyyy-mm-dd HH:MM:ss.l]')

Weitere Informationen finden Sie unter https://github.com/starak/node-console-stamp

khoi nguyen
quelle
0

Eine andere Lösung besteht darin, den Logger in eine Datei zu verpacken, die einige Funktionen wie logger.info (), logger.error () usw. exportiert. Anschließend übergeben Sie einfach einen zusätzlichen Schlüssel, der für jedes Nachrichtenprotokoll gesendet wird.

loggerService.js

const logger = winston.createLogger({ ... })

function handleLog(message, level) {
  const logData = {
    timestamp: Date.now(),
    message,
  }

  return logger[level](logData)
}

function info(message) {
  handleLog(message, 'info')
}

function error(message) {
  handleLog(message, 'error')
}

function warn(message) {
  handleLog(message, 'warn')
}

module.exports = {
  info,
  error,
  warn
}

was auch immer-file.js

const logger = require('./services/loggerService')

logger.info('Hello World!')

your-log.log

{"timestamp":"2019-08-21 06:42:27","message":"Hello World!","level":"info"}
Renan Coelho
quelle
0

Ich nahm Biswadevs Antwort und erstellte ein stringifiziertes JSON-Objekt. Auf diese Weise wird es in einem gut strukturierten Format vorliegen, wenn ich die Protokolle später verarbeiten muss.

const winston = require('winston');
const { createLogger, format, transports } = require('winston');

const dotenv = require('dotenv');
dotenv.config();

var logger = createLogger({
    level: 'info',
    format: format.combine(
        format.timestamp({
            format: 'YYYY-MM-DD HH:mm:ss',
        }),
        format.printf((info) =>
            JSON.stringify({
                t: info.timestamp,
                l: info.level,
                m: info.message,
                s: info.splat !== undefined ? `${info.splat}` : '',
            }) + ','
        )
    ),
});

if (process.env.NODE_ENV !== 'PRODUCTION') {
    logger.add(new transports.Console({ format: winston.format.cli() }));

    // Turn these on to create logs as if it were production
    // logger.add(new transports.File({ filename: 'log/output/error.log', level: 'error' }));
    // logger.add(new transports.File({ filename: 'log/output/warn.log', level: 'warn' }));
    // logger.add(new transports.File({ filename: 'log/output/info.log', level: 'info' }));
} else {
    logger.add(new transports.File({ filename: 'log/output/error.log', level: 'error' }));
    logger.add(new transports.File({ filename: 'log/output/warn.log', level: 'warn' }));
    logger.add(new transports.File({ filename: 'log/output/info.log', level: 'info' }));
}

module.exports = {
    logger,
};

Verwendung:

app.listen(port, () => logger.info(`app is running on port ${port}`));

Ausgabe:

info.log Datei:

{"t":"2020-08-06 08:02:05","l":"info","m":"app is running on port 3001","s":""},

Konsole:

info:    app is running on port 3001
Steve
quelle