¿Cómo puedo agregar una marca de tiempo a los registros usando la biblioteca Winston de Node.js?


93

Quiero agregar una marca de tiempo a los registros. ¿Cuál es la mejor manera de lograr esto?


Esto sigue siendo demasiado amplio porque NO puede hacerlo desde la máquina cliente.
Joshua

Respuestas:


112

Yo mismo estaba lidiando con el mismo problema. Hay dos formas en que pude hacer esto.

Cuando incluye Winston, por lo general, el valor predeterminado es agregar un transporte de consola. Para que las marcas de tiempo funcionen en este caso predeterminado, necesitaba:

  1. Quite el transporte de la consola y vuelva a agregar con la opción de marca de tiempo.
  2. Cree su propio objeto Logger con la opción de marca de tiempo establecida en verdadero.

El primero:

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

La segunda opción más limpia:

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

Algunas de las otras opciones para el transporte de la consola se pueden encontrar aquí :

  • level: Nivel de mensajes que este transporte debe registrar ("depuración" por defecto).
  • silencioso: bandera booleana que indica si se debe suprimir la salida (por defecto es falso).
  • colorear: bandera booleana que indica si debemos colorear la salida (por defecto es falso).
  • timestamp: bandera booleana que indica si debemos anteponer la salida con marcas de tiempo (por defecto es falso). Si se especifica la función, se utilizará su valor de retorno en lugar de las marcas de tiempo.

1
Increíble y simple al mismo tiempo. ¡Gracias!
kolrie

7
Esto es genial. Por lo general, envuelvo esto en un archivo dedicado para poder obtener fácilmente mi registrador configurado desde cualquier archivo, es decir, coloco el código anterior (opción 2) en un nuevo archivo logger.js, seguido de module.exports = logger; luego, desde cualquier archivo, hago var logger = require ('./ logger.js') y luego puedo hacer logger.info ('hola') desde cualquier archivo y obtener la misma configuración de Winston.
JHH

TypeError: (valor intermedio) no es una función
Urasquirrel

81

Las respuestas anteriores no funcionaron para mí. En caso de que esté intentando agregar una marca de tiempo a sus registros utilizando la última versión de Winston - 3.0.0-rc1, esto funcionó a la perfección:

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

Usé 'format.combine ()'. Como necesitaba la marca de tiempo en todos mis transportes, agregué la opción de formato dentro de createLogger, en lugar de dentro de cada transporte. Mi salida en la consola y en el archivo (activity.log) es la siguiente:

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

Podemos agregar formato a esta marca de tiempo en 'format.combine ()' como de costumbre usando:

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

14

También podemos hacer esto

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;

¿Esto también funciona logger.info('Message', someObject)? Configuré un formato personalizado usando la combinación y parece que no puedo someObjectincluirlo en el mensaje de registro.
SomethingOn

1
Pude ser someObjectincluido usando la siguiente declaración printf ${info.timestamp} [${info.level.toUpperCase()}]: ${info.message} ${JSON.stringify(info)}. Incluye el nivel, la marca de tiempo y el mensaje que supongo que podría eliminar.
SomethingOn

9

Usted puede usar una función de util y siempre para lograr el registro con timestap para su servidor nodejs. Cuando inicie un servidor, agregue la salida de registro como parte del parámetro:

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

Y luego puedes escribir util en tu server.js

server.js

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

La salida tendrá un aspecto similar al archivo out.log:

out.log

15 Mar 15:09:28 - something with timestamp

1
Desafortunadamente, util.error()omite la marca de tiempo en la salida.
Saran

4

Aunque no conozco a Winston, esta es una sugerencia. Utilizo log4js para registrar y mis registros por defecto se ven así

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

El desarrollo es el entorno de mi proceso de nodo y [INFO | FATAL] es el nivel de registro

Es posible mantener diferentes perfiles para el registro en log4js. Tengo perfiles de Desarrollo y Producción. También hay tipos de registradores como agregador de archivos rodantes, agregador de consola, etc. Como complemento, sus archivos de registro serán coloridos según el nivel de registro [Trace, Info, Debug, Error, Fatal];)

log4js anulará su console.log Es un parámetro configurable ahora en 0.5+


Para su información: las versiones más recientes de log4js-node (0.5+) no anulan automáticamente console.log.
Jeff Hiltz

@jeffhiltz Ya tienes razón :) Ahora es un parámetro configurable
Tamil

2

A veces, el formato de marca de tiempo predeterminado puede no ser conveniente para usted. Puede anularlo con su implementación.

En vez de

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

puedes escribir

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

Consulte https://github.com/winstonjs/winston#custom-log-format para obtener más detalles



0

Otra solución es empaquetar el registrador en un archivo que exporta algunas funciones como logger.info (), logger.error (), etc., luego simplemente pasa una clave adicional para enviarla en cada registro de mensajes.

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
}

cualquier archivo.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"}

0

Tomé la respuesta de Biswadev y creé un objeto JSON en cadena. De esta manera, si necesito procesar los registros más tarde, estará en un formato bien estructurado.

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

Uso:

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

Salida:

archivo info.log:

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

Consola:

info:    app is running on port 3001
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.