Un registrador para casi todo.
Consulte la Guía de actualización para obtener más información. ¡Bienvenidos informes de errores y relaciones públicas!
[email protected]
? Tenga en cuenta que la documentación siguiente es para winston@3
. Lea la documentación de [email protected]
.
winston
está diseñado para ser una biblioteca de registro simple y universal con soporte para múltiples transportes. Un transporte es esencialmente un dispositivo de almacenamiento para sus registros. Cada registrador winston
puede tener múltiples transportes (ver: Transportes) configurados en diferentes niveles (ver: Niveles de registro). Por ejemplo, es posible que desee que los registros de errores se almacenen en una ubicación remota persistente (como una base de datos), pero que todos los registros se envíen a la consola o a un archivo local.
winston
pretende desacoplar partes del proceso de registro para hacerlo más flexible y extensible. Se presta atención a admitir la flexibilidad en el formato de registro (consulte: Formatos) y niveles (consulte: Uso de niveles de registro personalizados) y a garantizar que las API estén desacopladas de la implementación del registro de transporte (es decir, cómo se almacenan/indexan los registros, consulte: Agregar registros personalizados). Transportes) a la API que expusieron al programador.
TL;DR? Consulte el ejemplo de inicio rápido en ./examples/
. Hay varios otros ejemplos en ./examples/*.js
. ¿No ves un ejemplo que crees que debería estar ahí? ¡Envíe una solicitud de extracción para agregarlo!
La forma recomendada de utilizar winston
es crear su propio registrador. La forma más sencilla de hacerlo es utilizando winston.createLogger
:
const winston = require('winston');const logger = winston.createLogger({ nivel: 'info', formato: winston.format.json(), defaultMeta: { servicio: 'servicio-usuario' }, transportes: [ / // - Escribe todos los registros con un nivel de importancia de `error` o superior en `error.log` // (es decir, error, fatal, pero no otros niveles) // new winston.transports.File({ filename: 'error.log', nivel: 'error' }), // // - Escribe todos los registros con un nivel de importancia de `info` o superior en `combined.log` // (es decir, fatal, error, advertencia e información , pero no rastrear) // new winston.transports.File({ filename: 'combined.log' }), ],});//// Si no estamos en producción, inicie sesión en la `consola` con el formato:// `${info.level}: ${info.message} JSON.stringify({ ...rest }) `//if (process.env.NODE_ENV !== 'producción') { logger.add(new winston.transports.Console({ formato: winston .formato.simple(), }));}
También puede iniciar sesión directamente a través del registrador predeterminado expuesto por require('winston')
, pero esto simplemente pretende ser un registrador compartido conveniente para usar en toda su aplicación si así lo desea. Tenga en cuenta que el registrador predeterminado no tiene ningún transporte de forma predeterminada. Necesita agregar transportes usted mismo y dejar el registrador predeterminado sin ningún transporte puede producir un problema de uso elevado de memoria.
Motivación
Inicio rápido
Uso
Tabla de contenido
Explotación florestal
Creando su registrador
Streams, objectMode
y objetos info
Formatos
Combinando formatos
Interpolación de cadenas
Filtrar objetos info
Creando formatos personalizados
Niveles de registro
Usando niveles de registro
Usar niveles de registro personalizados
Transportes
Múltiples transportes del mismo tipo
Agregar transportes personalizados
Opciones de transporte comunes
Excepciones
Manejo de excepciones no detectadas con Winston
Salir o no salir
Rechazos
Manejo de rechazos de promesas no detectadas con Winston
Perfilado
Registros de transmisión
Consultar registros
Lectura adicional
Usando el registrador predeterminado
En espera de que se escriban registros en winston
Trabajar con múltiples registradores en winston
Enrutamiento de mensajes de transporte de consola a la consola en lugar de stdout y stderr
Instalación
Ejecutar pruebas
Los niveles de registro en winston
se ajustan al orden de gravedad especificado en RFC5424: se supone que la gravedad de todos los niveles asciende numéricamente del más importante al menos importante.
niveles constantes = { error: 0, advertencia: 1, información: 2, http: 3, detallado: 4, depuración: 5, tonto: 6};
Comience creando un registrador usando winston.createLogger
:
const logger = winston.createLogger({ transportes: [ nuevo winston.transports.Console(), nuevo winston.transports.File({ nombre de archivo: 'combined.log' }) ]});
Un registrador acepta los siguientes parámetros:
Nombre | Por defecto | Descripción |
---|---|---|
level | 'info' | Registre solo si info.level es menor o igual a este nivel |
levels | winston.config.npm.levels | Niveles (y colores) que representan prioridades de registro |
format | winston.format.json | Formato de mensajes info (ver: Formatos) |
transports | [] (Sin transportes) | Conjunto de objetivos de registro para mensajes info |
exitOnError | true | Si es falso, las excepciones manejadas no causarán process.exit |
silent | false | Si es verdadero, se suprimen todos los registros. |
Los niveles proporcionados para createLogger
se definirán como métodos convenientes en el logger
devuelto.
//// Logging//logger.log({ nivel: 'info', mensaje: '¡Hola archivos de registro distribuidos!'});logger.info('Hola nuevamente registros distribuidos');
Puede agregar o eliminar transportes del logger
una vez que se los haya proporcionado desde winston.createLogger
:
const files = new winston.transports.File({ filename: 'combined.log' });const console = new winston.transports.Console();logger .clear() // Eliminar todos los transportes .add(console) // Agregar transporte de consola .add(files) // Agregar transporte de archivos .remove(console); // Quitar el transporte de la consola
También puede reconfigurar al por mayor una instancia winston.Logger
utilizando el método configure
:
const logger = winston.createLogger({ nivel: 'info', transportes: [nuevo winston.transports.Console(), nuevo winston.transports.File({ nombre de archivo: 'combined.log' }) ]});/// / Reemplaza los transportes anteriores con los de la // nueva configuración al por mayor.//const DailyRotateFile = require('winston-daily-rotate-file');logger.configure({ nivel: 'detallado', transportes: [nuevo DailyRotateFile(opts)]});
Puede crear registradores secundarios a partir de registradores existentes para pasar anulaciones de metadatos:
const logger = winston.createLogger({ transportes: [ new winston.transports.Console(), ]}); const childLogger = logger.child({ requestId: '451' });
Es probable que
.child
tenga errores si también extiende la claseLogger
, debido a algunos detalles de implementación que hacen quethis
palabra clave apunte a cosas inesperadas. Úselo con precaución.
objectMode
y objetos info
En winston
, las instancias de Logger
y Transport
se tratan como secuencias objectMode
que aceptan un objeto info
.
El parámetro info
proporcionado a un formato determinado representa un único mensaje de registro. El objeto en sí es mutable. Cada info
debe tener al menos las propiedades level
y message
:
const info = {level: 'info', // Nivel del mensaje de registro message: '¡Oye! ¿Registrar algo? // Mensaje descriptivo que se está registrando.};
Las propiedades además del nivel y el mensaje se consideran " meta
". es decir:
const {nivel, mensaje, ...meta} = información;
Varios de los formatos del propio logform
añaden propiedades adicionales:
Propiedad | Formato añadido por | Descripción |
---|---|---|
splat | splat() | Símbolo de interpolación de cadenas para mensajes estilo %d %s . |
timestamp | timestamp() | marca de tiempo en que se recibió el mensaje. |
label | label() | Etiqueta personalizada asociada a cada mensaje. |
ms | ms() | Número de milisegundos desde el mensaje de registro anterior. |
Como consumidor, puede agregar las propiedades que desee; el estado interno se mantiene mediante las propiedades Symbol
:
Symbol.for('level')
(SÓLO LECTURA) : igual a la propiedad level
. Todo el código lo trata como inmutable.
Symbol.for('message'):
mensaje de cadena completo establecido por "finalización de formatos":
json
logstash
printf
prettyPrint
simple
Symbol.for('splat')
: argumentos de interpolación de cadenas adicionales. Usado exclusivamente por el formato splat()
.
Estos símbolos se almacenan en otro paquete: triple-beam
para que todos los consumidores de logform
puedan tener la misma referencia de símbolo. es decir:
const { NIVEL, MENSAJE, SPLAT } = require('triple-beam');console.log(NIVEL === Symbol.for('level'));// trueconsole.log(MENSAJE === Symbol.for( 'mensaje'));// trueconsole.log(SPLAT === Symbol.for('splat'));// verdadero
NOTA: cualquier propiedad
{ message }
en unmeta
proporcionado se concatenará automáticamente a cualquiermsg
ya proporcionado: por ejemplo, lo siguiente concatenará 'mundo' con 'hola':logger.log('error', 'hola', { mensaje: 'mundo' });logger.info('hola', { mensaje: 'mundo' });
Se puede acceder a los formatos en winston
desde winston.format
. Se implementan en logform
, un módulo independiente de winston
. Esto permite flexibilidad al escribir sus propios transportes en caso de que desee incluir un formato predeterminado con su transporte.
En las versiones modernas de las cadenas de plantillas node
tienen un gran rendimiento y son la forma recomendada para realizar la mayoría de los formateo para el usuario final. Si desea formatear sus registros a medida, winston.format.printf
es para usted:
const { createLogger, formato, transportes } = require('winston'); const { combinar, marca de tiempo, etiqueta, printf } = formato; const myFormat = printf(({ nivel, mensaje, etiqueta, marca de tiempo }) => { return ` ${marca de tiempo} [${label}] ${nivel}: ${mensaje}`;});const logger = createLogger({ formato: combinar( etiqueta({ etiqueta: 'derecha ¡miau!' }), marca de tiempo(), myFormat ), transportes: [nuevos transportes.Console()]});
Para ver qué formatos integrados están disponibles y obtener más información sobre cómo crear sus propios formatos de registro personalizados, consulte logform
.
Se puede combinar cualquier número de formatos en un solo formato usando format.combine
. Dado que format.combine
no acepta opts
, para su comodidad devuelve una instancia creada previamente del formato combinado.
const { createLogger, formato, transportes } = require('winston'); const { combinar, marca de tiempo, etiqueta, PrettyPrint } = formato; const logger = createLogger({ formato: combinar ( etiqueta ({ etiqueta: '¡miau correcto!' } ), timestamp(), PrettyPrint() ), transportes: [new transports.Console()]})logger.log({ nivel: 'info', mensaje: '¿A qué hora es la prueba? at?'});// Salidas:// { nivel: 'info',// mensaje: '¿A qué hora es la prueba?',// etiqueta: '¡miau!',// marca de tiempo: '2017- 09-30T03:57:26.875Z' }
El método log
proporciona la interpolación de cadenas utilizando util.format. Debe habilitarse usando format.splat()
.
A continuación se muestra un ejemplo que define un formato con interpolación de cadenas de mensajes usando format.splat
y luego serializa todo el mensaje info
usando format.simple
.
const { createLogger, formato, transportes } = require('winston'); const logger = createLogger({ formato: format.combine( format.splat(), format.simple() ), transportes: [nuevos transportes.Console() ]});// info: mensaje de prueba mi cadena {}logger.log('info', 'mensaje de prueba %s', 'mi cadena');// info: mensaje de prueba 123 {}logger.log('info', 'mensaje de prueba %d', 123);// info: mensaje de prueba primer segundo {número: 123}logger.log('info', 'mensaje de prueba %s, %s' , 'primero', 'segundo', { número: 123 });
info
Si desea filtrar completamente un objeto info
determinado al iniciar sesión, simplemente devuelva un valor falso.
const { createLogger, format, transports } = require('winston');// Ignora los mensajes de registro si tienen {privado: verdadero} const ignorePrivate = format((info, opts) => { if (info.private) { return false; } devolver información;}); const logger = createLogger({ formato: format.combine( ignorePrivate(), format.json() ), transporta: [nuevo transports.Console()]});// Salidas: {"level":"error","message":"Error público al compartir"}logger.log({ nivel: 'error', mensaje: 'Error público al share'});// Los mensajes con {privado: verdadero} no se escribirán cuando se registre.logger.log({privado: verdadero, nivel: 'error', mensaje: 'Esto es súper secreto, ocultelo.'}) ;
El uso de format.combine
respetará cualquier retorno de valores falsos y detendrá la evaluación de formatos posteriores de la serie. Por ejemplo:
const {formato} = require('winston');const {combinar, marca de tiempo, etiqueta} = formato;const willNeverThrow = format.combine(formato(info => { return false })(), // Ignora todo formato(info => { throw new Error('Nunca alcanzado') })());
Los formatos son objetos prototípicos (es decir, instancias de clase) que definen un único método: transform(info, opts)
y devuelven la info
mutada:
info
: un objeto que representa el mensaje de registro.
opts
: configuración específica de la instancia actual del formato.
Se espera que devuelvan una de dos cosas:
Un objeto info
que representa el argumento info
modificado. No es necesario conservar las referencias a objetos si se prefiere la inmutabilidad. Todos los formatos integrados actuales consideran que info
es mutable, pero se está considerando [immutablejs] para futuras versiones.
Un valor falso que indica que la persona que llama debe ignorar el argumento info
. (Ver: Filtrado de objetos info
) a continuación.
winston.format
está diseñado para ser lo más simple posible. Para definir un nuevo formato, simplemente pásele una función transform(info, opts)
para obtener un nuevo Format
.
El Format
con nombre devuelto se puede utilizar para crear tantas copias del Format
dado como se desee:
const { formato } = require('winston');const volumen = formato((info, opts) => { if (opts.yell) { info.message = info.message.toUpperCase(); } else if (opts. susurro) { info.message = info.message.toLowerCase(); return info;});// `volume` ahora es una función que devuelve instancias del formato format.const. = volumen({ yell: true });console.dir(scream.transform({ nivel: 'info', mensaje: `¡perdón por hacerte GRITAR en tu cabeza!`}, gritar.options));// {/ / nivel: 'info'// mensaje: '¡PERDÓN POR HACERTE GRITAR EN TU CABEZA!'// }// `volumen` se puede usar varias veces para crear diferentes formatos.const susurro = volumen({ susurro: verdadero });console.dir(whisper.transform({ nivel: 'info', mensaje: `¡POR QUÉ NOS HACEN GRITAR TANTO!`}, susurro.options));// {// nivel: 'info'/ / mensaje: '¡por qué nos hacen gritar tanto!'// }
Los niveles de registro en winston
se ajustan al orden de gravedad especificado en RFC5424: se supone que la gravedad de todos los niveles asciende numéricamente del más importante al menos importante.
A cada level
se le asigna una prioridad entera específica. Cuanto mayor sea la prioridad, más importante se considera el mensaje y menor será la prioridad entera correspondiente. Por ejemplo, como se especifica exactamente en RFC5424, los niveles syslog
tienen prioridad de 0 a 7 (de mayor a menor).
{emerg: 0, alerta: 1, crítico: 2, error: 3, advertencia: 4, aviso: 5, información: 6, depuración: 7}
De manera similar, los niveles de registro npm
tienen prioridad de 0 a 6 (de mayor a menor):
{error: 0, advertencia: 1, información: 2, http: 3, detallado: 4, depuración: 5, tonto: 6}
Si no define explícitamente los niveles que debe usar winston
, se usarán los niveles npm
anteriores.
La configuración del nivel para su mensaje de registro se puede lograr de dos maneras. Puede pasar una cadena que represente el nivel de registro al método log() o utilizar los métodos de nivel especificado definidos en cada Winston Logger.
//// Cualquier instancia de registrador//logger.log('silly', "127.0.0.1 - no hay lugar como el hogar");logger.log('debug', "127.0.0.1 - no hay lugar como el hogar") ;logger.log('verbose', "127.0.0.1 - no hay lugar como el hogar");logger.log('info', "127.0.0.1 - no hay ningún lugar como el hogar");logger.log('warn', "127.0.0.1 - no hay ningún lugar como el hogar");logger.log('error', "127.0.0.1 - no hay ningún lugar como el hogar"); como en casa");logger.info("127.0.0.1 - no hay lugar como home");logger.warn("127.0.0.1 - no hay lugar como el hogar");logger.error("127.0.0.1 - no hay lugar como el hogar");//// Registrador predeterminado//winston.log( 'info', "127.0.0.1 - no hay lugar como el hogar");winston.info("127.0.0.1 - no hay lugar como el hogar");
winston
le permite definir una propiedad level
en cada transporte que especifica el nivel máximo de mensajes que un transporte debe registrar. Por ejemplo, al utilizar los niveles syslog
puede registrar solo mensajes error
en la consola y toda info
que aparece a continuación en un archivo (que incluye mensajes error
):
const logger = winston.createLogger({ niveles: winston.config.syslog.levels, transportes: [ nuevo winston.transports.Console({ nivel: 'error' }), nuevo winston.transports.File({ nombre de archivo: 'combinado. log', nivel: 'info' }) ]});
También puedes cambiar dinámicamente el nivel de registro de un transporte:
const transports = { consola: nuevo winston.transports.Console({ nivel: 'advertir' }), archivo: nuevo winston.transports.File({ nombre de archivo: 'combined.log', nivel: 'error' })};const logger = winston.createLogger({ transports: [ transports.console, transports.file ]});logger.info('Tampoco se iniciará sesión transport!');transports.console.level = 'info';transports.file.level = 'info';logger.info('¡Se registrará en ambos transportes!');
winston
admite niveles de registro personalizables y, de forma predeterminada, utiliza niveles de registro de estilo npm. Los niveles deben especificarse al momento de crear su registrador.
Además de los niveles npm
, syslog
y cli
predefinidos disponibles en winston
, también puede optar por definir los suyos propios:
const myCustomLevels = { niveles: { foo: 0, bar: 1, baz: 2, foobar: 3 }, colores: { foo: 'azul', bar: 'verde', baz: 'amarillo', foobar: 'rojo' }};const customLevelLogger = winston.createLogger({ niveles: myCustomLevels.levels});customLevelLogger.foobar('algunos foobar mensaje nivelado');
Aunque hay una ligera repetición en esta estructura de datos, permite una encapsulación simple si no desea tener colores. Si deseas tener colores, además de pasar los niveles al propio Logger, debes hacérselo saber a Winston:
winston.addColors(misNivelesPersonalizados.colores);
Esto permite a los registradores que utilizan el formateador colorize
colorear y diseñar adecuadamente la salida de niveles personalizados.
Además, también puedes cambiar el color de fondo y el estilo de fuente. Por ejemplo,
baz: 'cursiva amarilla',foobar: 'negrita roja cianBG'
Las posibles opciones están a continuación.
Estilos de fuente: bold
, dim
, italic
, underline
, inverse
, hidden
, strikethrough
.
Colores de primer plano de la fuente: black
, red
, green
, yellow
, blue
, magenta
, cyan
, white
, gray
, grey
.
Colores de fondo: blackBG
, redBG
, greenBG
, yellowBG
, blueBG
magentaBG
, cyanBG
, whiteBG
Para colorear el nivel de registro estándar, agregue
winston.format.combine( winston.format.colorize(), winston.format.simple());
donde winston.format.simple()
es cualquier otro formateador que desee utilizar. El formateador colorize
debe ir antes que cualquier formateador que agregue el texto que desea colorear.
Para colorear la línea de registro completa con el formateador json, puede aplicar lo siguiente
winston.format.combine( winston.format.json(), winston.format.colorize({ todo: verdadero }));
Hay varios transportes principales incluidos en winston
, que aprovechan las redes integradas y la E/S de archivos que ofrece el núcleo Node.js. Además, hay transportes adicionales escritos por miembros de la comunidad.
Es posible utilizar varios transportes del mismo tipo, por ejemplo, winston.transports.File
al construir el transporte.
const logger = winston.createLogger({ transportes: [ nuevo winston.transports.File({ nombre de archivo: 'combined.log', nivel: 'info' }), nuevo winston.transports.File({ nombre de archivo: 'errors.log' , nivel: 'error' }) ]});
Si luego deseas retirar uno de estos transportes podrás hacerlo utilizando el propio transporte. p.ej:
const combinadoLogs = logger.transports.find(transporte => { return transporte.filename === 'combined.log'});logger.remove(combinedLogs);
Agregar un transporte personalizado es fácil. Todo lo que necesita hacer es aceptar las opciones que necesite, implementar un método log() y consumirlo con winston
.
const Transport = require('winston-transport');const util = require('util');//// Hereda de `winston-transport` para que puedas aprovechar// la funcionalidad base y `.exceptions.handle ()`.//module.exports = clase YourCustomTransport extiende Transporte { constructor(opts) { super(opts); // // Consuma cualquier opción personalizada aquí. por ejemplo: // - Información de conexión para bases de datos // - Información de autenticación para API (por ejemplo, loggly, papertrail, // logentries, etc.). // } log(info, devolución de llamada) { setImmediate(() => { this.emit('logged', info); }); // Realizar la escritura en la devolución de llamada del servicio remoto(); }};
Como cada transporte hereda de winston-transport, es posible establecer un formato personalizado y un nivel de registro personalizado en cada transporte por separado:
const logger = winston.createLogger({ transportes: [ nuevo winston.transports.File({ nombre de archivo: 'error.log', nivel: 'error', formato: winston.format.json() }), nuevo winston.transports. Http({ nivel: 'advertir', formato: winston.format.json() }), nuevo winston.transports.Console({ nivel: 'información', formato: winston.format.combine( winston.format.colorize(), winston.format.simple() ) }) ]});
Con winston
, es posible detectar y registrar eventos uncaughtException
de su proceso. Con su propia instancia de registrador, puede habilitar este comportamiento cuando se crea o más adelante en el ciclo de vida de su aplicación:
const { createLogger, transports } = require('winston');// Habilite el manejo de excepciones cuando cree su logger.const logger = createLogger({ transports: [ new transports.File({ filename: 'combined.log' }) ] ,ExceptionHandlers: [ new transports.File({ filename: 'exceptions.log' }) ]});// O habilítelo más adelante agregando un transporte o usando `.exceptions.handle`const logger = createLogger({ transports: [ new transports.File({ filename: 'combined.log' }) ]});// Llama a excepciones.handle con un transporte para manejar excepcioneslogger.exceptions.handle ( nuevos transportes.File({ nombre de archivo: 'exceptions.log' }));
Si desea utilizar esta función con el registrador predeterminado, simplemente llame a .exceptions.handle()
con una instancia de transporte.
//// Puede agregar un registrador de excepciones independiente pasándolo a `.exceptions.handle`//winston.exceptions.handle( new winston.transports.File({ filename: 'path/to/exceptions.log' }) );//// Alternativamente, puede establecer `handleExceptions` en verdadero al agregar transportes// a winston.//winston.add(new winston.transports.File({ filename: 'ruta/a/combined.log', handleExceptions: verdadero}));
De forma predeterminada, Winston saldrá después de registrar una excepción no detectada. Si este no es el comportamiento que desea, establezca exitOnError = false
const logger = winston.createLogger({ exitOnError: false });//// o, así: //logger.exitOnError = false;
Cuando trabaje con instancias de registradores personalizados, puede pasar transportes separados a la propiedad exceptionHandlers
o establecer handleExceptions
en cualquier transporte.
const logger = winston.createLogger({ transportes: [ nuevo winston.transports.File({ nombre de archivo: 'ruta/a/combined.log' }) ], manejadores de excepciones: [nuevo winston.transports.File({ nombre de archivo: 'ruta/ a/exceptions.log' }) ]});
const logger = winston.createLogger({ transportes: [ new winston.transports.Console({ handleExceptions: true }) ], exitOnError: false});
La opción exitOnError
también puede ser una función para evitar la salida solo en ciertos tipos de errores:
function ignoreEpipe(err) { return err.code !== 'EPIPE';}const logger = winston.createLogger({ exitOnError: ignoreEpipe });//// o, así: //logger.exitOnError = ignoreEpipe;
Con winston
, es posible detectar y registrar eventos de unhandledRejection
de su proceso. Con su propia instancia de registrador, puede habilitar este comportamiento cuando se crea o más adelante en el ciclo de vida de su aplicación:
const { createLogger, transports } = require('winston');// Habilite el manejo de rechazo cuando cree su logger.const logger = createLogger({ transports: [ new transports.File({ filename: 'combined.log' }) ] , rechazoHandlers: [ new transports.File({ filename: 'rejections.log' }) ]});// O habilítelo más adelante agregando un transporte o usando `.rejections.handle`const logger = createLogger({ transports: [ new transports.File({ filename: 'combined.log' }) ]});// Llame a rechazos.handle con un transporte para manejar rechazoslogger.rejections.handle ( nuevos transportes.File({ nombre de archivo: 'rejections.log' }));
Si desea utilizar esta función con el registrador predeterminado, simplemente llame a .rejections.handle()
con una instancia de transporte.
//// Puede agregar un registrador de rechazos independiente pasándolo a `.rejections.handle`//winston.rejections.handle( new winston.transports.File({ filename: 'path/to/rejections.log' }) );//// Alternativamente, puede establecer `handleRejections` en verdadero al agregar transportes// a winston.//winston.add(new winston.transports.File({ filename: 'ruta/a/combined.log', handleRejections: true}));
Además de registrar mensajes y metadatos, winston
también tiene implementado un mecanismo de creación de perfiles simple para cualquier registrador:
//// Iniciar perfil de 'prueba'//logger.profile('test');setTimeout(function () { // // Detener perfil de 'prueba'. El registro ahora tendrá lugar: // '17 21 de enero :00:00 - información: duración de la prueba=1000ms' // logger.profile('prueba');}, 1000);
También puede iniciar un temporizador y mantener una referencia a la que puede llamar .done()
:
// Devuelve un objeto correspondiente a un momento específico. Cuando se llama a done //, el temporizador finalizará y registrará la duración. por ejemplo: // const perfilador = logger.startTimer(); setTimeout(function () { perfilador.done({ mensaje: 'Mensaje de registro' }); }, 1000);
Todos los mensajes de perfil están configurados en el nivel 'información' de forma predeterminada, y tanto el mensaje como los metadatos son opcionales. Para mensajes de perfil individuales, puede anular el nivel de registro predeterminado proporcionando un objeto de metadatos con una propiedad level
:
logger.profile('prueba', {nivel: 'depuración' });
winston
admite la consulta de registros con opciones similares a Loggly. Consulte API de búsqueda de Loggly. Específicamente: File
, Couchdb
, Redis
, Loggly
, Nssocket
y Http
.
opciones constantes = { desde: nueva Fecha() - (24 * 60 * 60 * 1000), hasta: nueva Fecha(), límite: 10, inicio: 0, orden: 'desc', campos: ['mensaje']} ;//// Buscar elementos registrados entre hoy y ayer.//logger.query(options, function (err, results) { if (err) { /* TODO: manejarme */ throw err; } console.log(resultados);});
La transmisión le permite transmitir sus registros desde el transporte elegido.
//// Comienza por el final.//winston.stream({ start: -1 }).on('log', function(log) { console.log(log);});
Se puede acceder al registrador predeterminado directamente a través del módulo winston
. Cualquier método que pueda invocar en una instancia de un registrador está disponible en el registrador predeterminado:
const winston = require('winston');winston.log('info', '¡Hola archivos de registro distribuidos!');winston.info('Hola nuevamente registros distribuidos');winston.level = 'debug';winston.log ('debug', '¡Ahora mis mensajes de depuración están escritos en la consola!');
De forma predeterminada, no se configuran transportes en el registrador predeterminado. Debes agregar o eliminar transportes mediante los métodos add()
y remove()
:
archivos const = new winston.transports.File({ nombre de archivo: 'combined.log' });const console = new winston.transports.Console();winston.add(console);winston.add(files);winston.remove (consola);
O hazlo con una llamada a configure():
winston.configure({ transportes: [ new winston.transports.File({ nombre de archivo: 'somefile.log' }) ]});
Para obtener más documentación sobre cómo trabajar con cada transporte individual respaldado por winston
consulte el documento winston
Transports.
winston
A menudo es útil esperar a que se escriban los registros antes de salir del proceso. Cada instancia de winston.Logger
también es una [secuencia de Node.js]. Se generará un evento finish
cuando todos los registros se hayan enviado a todos los transportes después de que finalice la transmisión.
const transport = new winston.transports.Console();const logger = winston.createLogger({ transports: [transport]});logger.on('finish', function (info) { // Todos los mensajes de registro `info` tienen ahora se ha iniciado sesión});logger.info('CHILL WINSTON!', {en serio: verdadero});logger.end();
También vale la pena mencionar que el registrador también emite un evento de 'error' si ocurre un error dentro del propio registrador que debe manejar o suprimir si no desea excepciones no controladas:
//// Maneja los errores que se originan en el propio registrador //logger.on('error', function (err) { /* Do Something */ });
A menudo, en aplicaciones más grandes y complejas es necesario tener varias instancias de registrador con diferentes configuraciones. Cada registrador es responsable de un área (o categoría) de características diferente. Esto se expone en winston
de dos maneras: a través de winston.loggers
e instancias de winston.Container
. De hecho, winston.loggers
es solo una instancia predefinida de winston.Container
:
const winston = require('winston');const {formato} = winston;const {combinar, etiqueta, json} = formato;//// Configurar el registrador para `categoría1`//winston.loggers.add('categoría1' , {formato: combinar( etiqueta({ etiqueta: 'categoría uno' }), json() ), transportes: [ new winston.transports.Console({ nivel: 'tonto' }), new winston.transports.File({ filename: 'somefile.log' }) ]});//// Configure el registrador para `category2`//winston.loggers.add('category2', { format: combine( etiqueta({ etiqueta: 'categoría dos' }), json() ), transportes: [ new winston.transports.Http({ host: 'localhost', puerto:8080 }) ]});
Ahora que sus registradores están configurados, puede solicitar winston en cualquier archivo de su aplicación y acceder a estos registradores preconfigurados:
const winston = require('winston');//// Tome sus registradores preconfigurados//const categoría1 = winston.loggers.get('categoría1');const categoría2 = winston.loggers.get('categoría2');categoría1. info('iniciar sesión en transportes de archivos y consola');category2.info('iniciar sesión en transporte http');
Si prefiere administrar el Container
usted mismo, simplemente puede crear una instancia de uno:
const winston = require('winston');const {formato} = winston;const {combinar, etiqueta, json} = formato;const contenedor = nuevo winston.Container();container.add('categoría1', {formato: combinar ( etiqueta ({ etiqueta: 'categoría uno' }), json() ), transportes: [ nuevo winston.transports.Console ({ nivel: 'tonto' }), nuevo winston.transports.File({ filename: 'somefile.log' }) ]});const categoría1 = contenedor.get('categoría1');categoría1.info('registro en archivos y transportes de consola');
De forma predeterminada, el transporte winston.transports.Console
envía mensajes a stdout
y stderr
. Esto está bien en la mayoría de las situaciones; sin embargo, hay algunos casos en los que esto no es deseable, entre ellos:
Depurar usando VSCode y adjuntar, en lugar de iniciar, un proceso Node.js
Escribir mensajes en formato JSON en AWS Lambda
Registro durante las pruebas de Jest con la opción --silent
Para hacer que el registro de transporte utilice console.log()
, console.warn()
y console.error()
en su lugar, establezca la opción forceConsole
en true
:
const logger = winston.createLogger({ nivel: 'información', transportes: [new winston.transports.Console({ forceConsole: true })]});
instalación npm de winston
hilo agregar winston
Todas las pruebas de Winston están escritas con mocha
, nyc
y assume
. Se pueden ejecutar con npm
.
prueba de NPM