Come posso aggiungere il timestamp ai log utilizzando la libreria Node.js Winston?


93

Voglio aggiungere il timestamp ai log. Qual è il modo migliore per ottenere questo risultato?


Questo rimane troppo ampio perché NON è possibile farlo dalla macchina client.
Joshua,

Risposte:


112

Ho affrontato lo stesso problema io stesso. Ci sono due modi in cui sono riuscito a farlo.

Quando includi Winston, in genere viene impostato per impostazione predefinita l'aggiunta di un trasporto della console. Per far funzionare i timestamp in questo caso predefinito, avevo bisogno di:

  1. Rimuovere il trasporto della console e aggiungerlo di nuovo con l'opzione timestamp.
  2. Crea il tuo oggetto Logger con l'opzione timestamp impostata su true.

Il primo:

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

La seconda e più pulita opzione:

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

Alcune delle altre opzioni per il trasporto della console possono essere trovate qui :

  • livello: livello di messaggi che questo trasporto deve registrare ("debug" predefinito).
  • silent: flag booleano che indica se sopprimere l'output (impostazione predefinita false).
  • colorize: flag booleano che indica se dobbiamo colorare l'output (valore predefinito false).
  • timestamp: flag booleano che indica se dobbiamo anteporre l'output con timestamp (impostazione predefinita false). Se viene specificata la funzione, verrà utilizzato il valore restituito al posto dei timestamp.

1
Incredibile e semplice allo stesso tempo. Grazie!
kolrie

7
Questo è fantastico. Di solito lo inserisco in un file dedicato in modo da poter facilmente ottenere il mio logger configurato da qualsiasi file, cioè, metto il codice sopra (opzione 2) in un nuovo file logger.js, seguito da module.exports = logger; quindi da qualsiasi file faccio var logger = require ('./ logger.js') e poi posso fare logger.info ('hello') da qualsiasi file e ottenere la stessa configurazione di Winston.
JHH

TypeError: (valore intermedio) non è una funzione
Urasquirrel

80

Le risposte di cui sopra non hanno funzionato per me. Nel caso in cui tu stia cercando di aggiungere il timestamp ai tuoi log utilizzando l'ultima versione di Winston - 3.0.0-rc1, questo ha funzionato alla perfezione:

    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'})
        ]
    });

Ho usato "format.combine ()". Poiché avevo bisogno del timestamp su tutti i miei trasporti, ho aggiunto l'opzione di formattazione all'interno del createLogger, piuttosto che all'interno di ogni trasporto. I miei output su console e su file (activity.log) sono i seguenti:

{"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"}

Possiamo aggiungere la formattazione a questo timestamp in "format.combine ()" come al solito usando:

format.timestamp({format:'MM-YY-DD'})

14

Possiamo fare anche questo

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;

Funziona anche per questo logger.info('Message', someObject)? Ho impostato un formato personalizzato utilizzando Combina e non riesco a ottenere il messaggio someObjectincluso nel registro.
Qualcosa il

1
Sono stato in grado di essere someObjectincluso utilizzando la seguente istruzione printf ${info.timestamp} [${info.level.toUpperCase()}]: ${info.message} ${JSON.stringify(info)}. Include il livello, il timestamp e il messaggio che immagino di poter eliminare.
Qualcosa il

9

Puoi utilizzare util e forever per ottenere la registrazione con timestap per il tuo server nodejs. Quando si avvia un server, aggiungere l'output del log come parte del parametro:

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

E poi puoi scrivere util nel tuo server.js

server.js

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

L'output sarà simile al file out.log:

out.log

15 Mar 15:09:28 - something with timestamp

1
Sfortunatamente, util.error()salta la marcatura temporale dell'output.
Saran

4

Anche se non sono a conoscenza di Winston, questo è un suggerimento. Uso log4js per la registrazione e per impostazione predefinita i miei log hanno questo aspetto

[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'

Lo sviluppo è l'ambiente del mio processo nodo e [INFO | FATAL] è a livello di registro

In log4js è possibile mantenere diversi profili per la registrazione. Ho profili di sviluppo e produzione. Inoltre ci sono tipi di logger come appender file in rotazione, appender console, ecc. Come addon i tuoi file di log saranno colorati in base al livello di log [Trace, Info, Debug, Error, Fatal];)

log4js sovrascriverà la tua console.log È un parametro configurabile ora in 0.5+


FYI: le versioni più recenti di log4js-node (0.5+) non sovrascrivono automaticamente console.log.
Jeff Hiltz

@jeffhiltz Ya hai ragione :) Ora è un parametro configurabile
Tamil

2

A volte il formato del timestamp predefinito può non essere conveniente per te. Puoi sovrascriverlo con la tua implementazione.

Invece di

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

tu puoi scrivere

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

Vedi https://github.com/winstonjs/winston#custom-log-format per i dettagli



0

Un'altra soluzione è avvolgere il logger in un file che esporta alcune funzioni come logger.info (), logger.error (), ecc. Quindi basta passare una chiave extra da inviare su ogni registro dei messaggi.

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
}

qualunque-file.js

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

logger.info('Hello World!')

tuo-log.log

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

0

Ho preso la risposta di Biswadev e ho creato un oggetto JSON con stringhe. In questo modo, se ho bisogno di elaborare i log in un secondo momento, sarà in un formato ben strutturato.

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,
};

Utilizzo:

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

Produzione:

file info.log:

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

Console:

info:    app is running on port 3001
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.