Um registrador para quase tudo.
Consulte o Guia de atualização para obter mais informações. Relatórios de bugs e PRs são bem-vindos!
[email protected]
? Observe que a documentação abaixo é para winston@3
. Leia a documentação [email protected]
.
winston
foi projetado para ser uma biblioteca de registro simples e universal com suporte para vários transportes. Um transporte é essencialmente um dispositivo de armazenamento para seus logs. Cada registrador winston
pode ter vários transportes (consulte: Transportes) configurados em diferentes níveis (consulte: Níveis de registro). Por exemplo, pode-se querer que os logs de erros sejam armazenados em um local remoto persistente (como um banco de dados), mas todos os logs sejam enviados para o console ou para um arquivo local.
winston
pretende desacoplar partes do processo de registro para torná-lo mais flexível e extensível. É dada atenção ao suporte à flexibilidade na formatação de log (consulte: Formatos) e níveis (consulte: Usando níveis de registro personalizados) e garantindo que essas APIs sejam desacopladas da implementação do registro de transporte (ou seja, como os logs são armazenados/indexados, consulte: Adicionando Transportes) para a API que eles expuseram ao programador.
DR; Confira o exemplo de início rápido em ./examples/
. Existem vários outros exemplos em ./examples/*.js
. Não vê um exemplo que você acha que deveria estar lá? Envie uma solicitação pull para adicioná-lo!
A maneira recomendada de usar winston
é criar seu próprio registrador. A maneira mais simples de fazer isso é usando winston.createLogger
:
const winston = require ('winston'); // // - Grava todos os logs com nível de importância `error` ou superior em `error.log` // (ou seja, erro, fatal, mas não outros níveis) // new winston.transports.File({ filename: 'error.log', level: 'error' }), // // - Grava todos os logs com nível de importância `info` ou superior em `combined.log` // (ou seja, fatal, erro, aviso e informações , mas não trace) // new winston.transports.File({ filename: 'combined.log' }), ],});//// Se não estivermos em produção, registre-se no `console` com o formatar:// `${info.level}: ${info.message} JSON.stringify({ ...rest }) `//if (process.env.NODE_ENV !== 'produção') { logger.add(new winston. transports.Console({formato:winston.format.simple(), }));}
Você também pode fazer logon diretamente por meio do registrador padrão exposto por require('winston')
, mas isso apenas pretende ser um registrador compartilhado conveniente para usar em todo o seu aplicativo, se assim desejar. Observe que o criador de logs padrão não possui nenhum transporte por padrão. Você precisa adicionar transportes sozinho, e deixar o criador de logs padrão sem nenhum transporte pode produzir um problema de alto uso de memória.
Motivação
Início rápido
Uso
Índice
Registro
Criando seu registrador
Streams, objectMode
e objetos info
Formatos
Combinando formatos
Interpolação de strings
Filtrando objetos info
Criando formatos personalizados
Níveis de registro
Usando níveis de registro
Usando níveis de registro personalizados
Transportes
Vários transportes do mesmo tipo
Adicionando transportes personalizados
Opções comuns de transporte
Exceções
Tratamento de exceções não detectadas com Winston
Sair ou não sair
Rejeições
Lidando com rejeições de promessas não detectadas com Winston
Perfil
Registros de streaming
Consultando registros
Leitura adicional
Usando o registrador padrão
Aguardando que os logs sejam gravados em winston
Trabalhando com vários Loggers em winston
Roteamento de mensagens de transporte do console para o console em vez de stdout e stderr
Instalação
Executar testes
Os níveis de registro em winston
estão em conformidade com a ordem de severidade especificada pela RFC5424: supõe-se que a severidade de todos os níveis seja numericamente ascendente do mais importante para o menos importante.
níveis const = {erro: 0, aviso: 1, informação: 2, http: 3, detalhado: 4, depuração: 5, bobo: 6};
Você começa criando um criador de logs usando winston.createLogger
:
const logger =winston.createLogger({transportes: [newwinston.transports.Console(),newwinston.transports.File({nome do arquivo: 'combined.log' }) ]});
Um registrador aceita os seguintes parâmetros:
Nome | Padrão | Descrição |
---|---|---|
level | 'info' | Registrar somente se info.level for menor ou igual a este nível |
levels | winston.config.npm.levels | Níveis (e cores) representando prioridades de log |
format | winston.format.json | Formatação para mensagens info (ver: Formatos) |
transports | [] (Sem transportes) | Conjunto de destinos de registro para mensagens info |
exitOnError | true | Se for falso, as exceções tratadas não causarão process.exit |
silent | false | Se for verdade, todos os logs serão suprimidos |
Os níveis fornecidos para createLogger
serão definidos como métodos de conveniência no logger
retornado.
//// Logging//logger.log({ level: 'info', message: 'Olá arquivos de log distribuídos!'});logger.info('Olá novamente logs distribuídos');
Você pode adicionar ou remover transportes do logger
depois que ele for fornecido a você por winston.createLogger
:
const files = new Winston.transports.File({ filename: 'combined.log' });const console = new Winston.transports.Console();logger .clear() // Remover todos os transportes .add(console) // Adicionar transporte de console .add(files) // Adicionar transporte de arquivo .remove(console); //Remove o transporte do console
Você também pode reconfigurar uma instância winston.Logger
usando o método configure
:
const logger = Winston.createLogger({ nível: 'info', transportes: [ new Winston.transports.Console(), new Winston.transports.File({ nome do arquivo: 'combined.log' }) ]});/// / Substitui os transportes anteriores por aqueles na // nova configuração atacado.//const DailyRotateFile = require('winston-daily-rotate-file');logger.configure({ level: 'detalhado', transportes: [new DailyRotateFile(opts) ]});
Você pode criar criadores de logs filhos a partir de criadores de logs existentes para passar substituições de metadados:
const logger = winston.createLogger({transportes: [ new winston.transports.Console(), ]});const childLogger = logger.child({ requestId: '451' });
É provável que
.child
esteja bugado se você também estiver estendendo a classeLogger
, devido a alguns detalhes de implementação que fazem com quethis
palavra-chave aponte para coisas inesperadas. Use com cuidado.
objectMode
e objetos info
Em winston
, as instâncias Logger
e Transport
são tratadas como fluxos objectMode
que aceitam um objeto info
.
O parâmetro info
fornecido para um determinado formato representa uma única mensagem de log. O objeto em si é mutável. Cada info
deve ter pelo menos as propriedades level
e message
:
const info = { level: 'info', // Nível da mensagem de log message: 'Hey! Registrar alguma coisa? // Mensagem descritiva sendo registrada.};
Propriedades além de nível e mensagem são consideradas " meta
". ou seja:
const {nível, mensagem, ...meta} = info;
Vários dos formatos no próprio logform
adicionam propriedades adicionais:
Propriedade | Formato adicionado por | Descrição |
---|---|---|
splat | splat() | Splat de interpolação de string para mensagens no estilo %d %s . |
timestamp | timestamp() | carimbo de data/hora em que a mensagem foi recebida. |
label | label() | Etiqueta personalizada associada a cada mensagem. |
ms | ms() | Número de milissegundos desde a mensagem de log anterior. |
Como consumidor, você pode adicionar quaisquer propriedades que desejar – o estado interno é mantido pelas propriedades Symbol
:
Symbol.for('level')
(READ-ONLY) : igual à propriedade level
. É tratado como imutável por todo o código.
Symbol.for('message'):
mensagem de string completa definida por "finalizando formatos":
json
logstash
printf
prettyPrint
simple
Symbol.for('splat')
: argumentos adicionais de interpolação de string. Usado exclusivamente pelo formato splat()
.
Esses Símbolos são armazenados em outro pacote: triple-beam
para que todos os consumidores do logform
possam ter a mesma referência de Símbolo. ou seja:
const { LEVEL, MESSAGE, SPLAT } = require('triple-beam');console.log(LEVEL === Symbol.for('level'));// trueconsole.log(MESSAGE === Symbol.for( 'mensagem'));// trueconsole.log(SPLAT === Símbolo.for('splat'));// verdadeiro
NOTA: qualquer propriedade
{ message }
em ummeta
fornecido será automaticamente concatenada a qualquermsg
já fornecida: Por exemplo, o exemplo abaixo irá concatenar 'world' em 'hello':logger.log('erro', 'olá', { mensagem: 'mundo' });logger.info('olá', { mensagem: 'mundo' });
Os formatos em winston
podem ser acessados em winston.format
. Eles são implementados em logform
, um módulo separado do winston
. Isto permite flexibilidade ao escrever seus próprios transportes caso você deseje incluir um formato padrão em seu transporte.
Nas versões modernas do modelo node
, as strings têm muito desempenho e são a forma recomendada para fazer a maior parte da formatação do usuário final. Se você deseja formatar seus logs sob medida, winston.format.printf
é para você:
const { createLogger, formato, transportes } = require('winston');const { combine, timestamp, label, printf } = format;const myFormat = printf(({ nível, mensagem, rótulo, timestamp }) => { return ` ${timestamp} [${label}] ${level}: ${message}`;});const logger = createLogger({ format: combine( label({ label: 'right miau!' }), timestamp(), myFormat ), transportes: [novos transportes.Console()]});
Para ver quais formatos integrados estão disponíveis e saber mais sobre como criar seus próprios formatos de log personalizados, consulte logform
.
Qualquer número de formatos pode ser combinado em um único formato usando format.combine
. Como format.combine
não aceita opts
, por conveniência ele retorna uma instância pré-criada do formato combinado.
const { createLogger, format, transports } = require('winston');const { combine, timestamp, label, prettyPrint } = format;const logger = createLogger({ format: combine( label({ label: 'right meow!' } ), timestamp(), prettyPrint() ), transports: [new transports.Console()]})logger.log({ level: 'info', message: 'A que horas é o teste?'});// Outputs:// { level: 'info',// message: 'Que horas é o teste?', // label: 'right meow!', // timestamp: '2017-09-30T03:57:26.875Z ' }
O método log
fornece a interpolação de string usando util.format. Deve ser habilitado usando format.splat()
.
Abaixo está um exemplo que define um formato com interpolação de string de mensagens usando format.splat
e então serializa toda a mensagem info
usando format.simple
.
const { createLogger, formato, transportes } = require('winston');const logger = createLogger({ formato: format.combine( formato.splat(), formato.simple() ), transportes: [novos transportes.Console() ]});// info: mensagem de teste minha string {}logger.log('info', 'mensagem de teste %s', 'minha string'); // info: mensagem de teste 123 {}logger.log('info ', 'teste mensagem %d', 123);// info: mensagem de teste primeiro segundo {número: 123}logger.log('info', 'mensagem de teste %s, %s', 'primeiro', 'segundo', { número: 123 });
info
Se você deseja filtrar completamente um determinado objeto info
durante o registro, simplesmente retorne um valor falsey.
const { createLogger, format, transports } = require('winston');// Ignora mensagens de log se elas tiverem { private: true }const ignorePrivate = format((info, opts) => { if (info.private) { return false; } return info;});const logger = createLogger({ format: format.combine( ignorePrivate(), format.json() ), transportes: [new transports.Console()]});// Saídas: {"level":"error","message":"Erro público para compartilhar"}logger.log({ level: 'error', message: 'Erro público para share'});// Mensagens com { private: true } não serão escritas quando logadas.logger.log({ private: true, level: 'error', message: 'This is super secret - hide it.'}) ;
O uso de format.combine
respeitará qualquer retorno de valores falsos e interromperá a avaliação de formatos posteriores na série. Por exemplo:
const { format } = require('winston');const { combine, timestamp, label } = format;const willNeverThrow = format.combine( format(info => { return false })(), // Ignora tudo format(info => { throw new Error('Nunca alcançado') })());
Os formatos são objetos prototípicos (ou seja, instâncias de classe) que definem um único método: transform(info, opts)
e retornam as info
mutadas:
info
: um objeto que representa a mensagem de log.
opts
: configuração específica para a instância atual do formato.
Espera-se que eles retornem uma de duas coisas:
Um objeto info
que representa o argumento info
modificado. As referências a objetos não precisam ser preservadas se a imutabilidade for preferida. Todos os formatos integrados atuais consideram info
mutável, mas [immutablejs] está sendo considerado para versões futuras.
Um valor falsey que indica que o argumento info
deve ser ignorado pelo chamador. (Veja: Filtrando objetos info
) abaixo.
winston.format
foi projetado para ser o mais simples possível. Para definir um novo formato, basta passar uma função transform(info, opts)
para obter um novo Format
.
O Format
nomeado retornado pode ser usado para criar quantas cópias do Format
fornecido desejar:
const { formato } = require('winston');const volume = formato((info, opts) => { if (opts.yell) { info.message = info.message.toUpperCase(); } else if (opts. sussurro) { info.message = info.message.toLowerCase(); } return info;});// `volume` agora é uma função que retorna instâncias do format.const grito = volume({ grito: verdadeiro });console.dir(scream.transform({ nível: 'info', mensagem: `desculpe por fazer você GRITAR na sua cabeça!`}, grito.options)); // {// nível: 'info'// mensagem: 'DESCULPE POR FAZER VOCÊ GRITAR NA SUA CABEÇA!'// }// `volume` pode ser usado várias vezes para criar diferentes formatos.const sussurro = volume({ sussurro : verdadeiro });console.dir(whisper.transform({ level: 'info', message: `POR QUE ELES ESTÃO FAZENDO-NOS GRITAR TANTO!`}, Whisper.options));// {// level: 'info'/ / mensagem: 'por que eles estão nos fazendo gritar tanto!'// }
Os níveis de registro em winston
estão em conformidade com a ordem de severidade especificada pela RFC5424: supõe-se que a severidade de todos os níveis seja numericamente ascendente do mais importante para o menos importante.
Cada level
recebe uma prioridade inteira específica. Quanto maior a prioridade, mais importante é considerada a mensagem e menor a prioridade inteira correspondente. Por exemplo, conforme especificado exatamente no RFC5424, os níveis syslog
são priorizados de 0 a 7 (do maior para o menor).
{emergir: 0, alerta: 1, crítico: 2, erro: 3, aviso: 4, aviso: 5, informações: 6, depuração: 7}
Da mesma forma, os níveis de registro npm
são priorizados de 0 a 6 (do maior para o menor):
{erro: 0, aviso: 1, informação: 2, http: 3, detalhado: 4, depuração: 5, bobo: 6}
Se você não definir explicitamente os níveis que winston
deve usar, os níveis npm
acima serão usados.
A definição do nível da sua mensagem de registro pode ser realizada de duas maneiras. Você pode passar uma string representando o nível de log para o método log() ou usar os métodos especificados de nível definidos em cada Winston Logger.
//// Qualquer instância do logger //logger.log('silly', "127.0.0.1 - não há lugar como a nossa casa");logger.log('debug', "127.0.0.1 - não há lugar como a nossa casa") ;logger.log('verbose', "127.0.0.1 - não há lugar como a nossa casa");logger.log('info', "127.0.0.1 - não há lugar como a nossa casa");logger.log('warn', "127.0.0.1 - não há lugar como a nossa casa");logger.log('error', "127.0.0.1 - não há lugar como a nossa casa"); logger.info("127.0.0.1 - não há lugar como a nossa casa");logger.warn("127.0.0.1 - não há lugar como a nossa casa");logger.warn("127.0.0.1 - não há lugar como home");logger.error("127.0.0.1 - não há lugar como a nossa casa");//// Logger padrão//winston.log('info', "127.0.0.1 - não há lugar como a nossa casa"); Winston.info("127.0.0.1 - não há lugar como a nossa casa");
winston
permite definir uma propriedade level
em cada transporte que especifica o nível máximo de mensagens que um transporte deve registrar. Por exemplo, usando os níveis syslog
você pode registrar apenas mensagens error
no console e todas info
abaixo em um arquivo (que inclui mensagens error
):
const logger =winston.createLogger({níveis:winston.config.syslog.levels,transports:[newwinston.transports.Console({nível: 'erro'}), novowinston.transports.File({nome do arquivo: 'combined. log', nível: 'info' }) ]});
Você também pode alterar dinamicamente o nível de log de um transporte:
const transportes = {console: novo Winston.transports.Console({ nível: 'warn' }), arquivo: novo Winston.transports.File({ nome do arquivo: 'combined.log', nível: 'erro' })};const logger = winston.createLogger({ transportes: [transports.console, transportes.file ]});logger.info('Também não estará logado transporte!');transports.console.level = 'info';transports.file.level = 'info';logger.info('Será logado em ambos os transportes!');
winston
oferece suporte a níveis de registro personalizáveis, padronizando os níveis de registro no estilo npm. Os níveis devem ser especificados no momento da criação do seu registrador.
Além dos níveis predefinidos npm
, syslog
e cli
disponíveis em winston
, você também pode optar por definir o seu próprio:
const meusCustomLevels = { níveis: { foo: 0, barra: 1, baz: 2, foobar: 3 }, cores: { foo: 'azul', barra: 'verde', baz: 'amarelo', foobar: 'vermelho' }};const customLevelLogger = winston.createLogger({ níveis: myCustomLevels.levels});customLevelLogger.foobar('alguns mensagem de nível foobar');
Embora haja uma pequena repetição nesta estrutura de dados, ela permite o encapsulamento simples caso não queira ter cores. Se você deseja ter cores, além de passar os níveis para o próprio Logger, você deve informar Winston sobre elas:
Winston.addColors(myCustomLevels.colors);
Isso permite que os criadores de logs que usam o formatador colorize
coloram e estilizem adequadamente a saída dos níveis personalizados.
Além disso, você também pode alterar a cor de fundo e o estilo da fonte. Por exemplo,
baz: 'amarelo itálico',foobar: 'negrito vermelho cyanBG'
As opções possíveis estão abaixo.
Estilos de fonte: bold
, dim
, italic
, underline
, inverse
, hidden
, strikethrough
.
Cores de primeiro plano da fonte: black
, red
, green
, yellow
, blue
, magenta
, cyan
, white
, gray
, grey
.
Cores de fundo: blackBG
, redBG
, greenBG
, yellowBG
, blueBG
magentaBG
, cyanBG
, whiteBG
Para colorir o nível de registro padrão, adicione
winston.format.combine(winston.format.colorize(),winston.format.simple());
onde winston.format.simple()
é qualquer outro formatador que você deseja usar. O formatador colorize
deve vir antes de qualquer formatador que adicione o texto que você deseja colorir.
Para colorir a linha de log completa com o formatador json, você pode aplicar o seguinte
winston.format.combine(winston.format.json(),winston.format.colorize({todos: verdadeiro }));
Existem vários transportes principais incluídos em winston
, que aproveitam a rede integrada e a E/S de arquivos oferecidas pelo núcleo do Node.js. Além disso, existem transportes adicionais escritos por membros da comunidade.
É possível usar vários transportes do mesmo tipo, por exemplo, winston.transports.File
quando você constrói o transporte.
const logger = winston.createLogger({ transportes: [ new winston.transports.File({ nome do arquivo: 'combined.log', nível: 'info' }), new winston.transports.File({ nome do arquivo: 'errors.log' , nível: 'erro' }) ]});
Se mais tarde você quiser remover um desses transportes, poderá fazê-lo usando o próprio transporte. por exemplo:
const combinadoLogs = logger.transports.find(transport => { return transport.filename === 'combined.log'});logger.remove(combinedLogs);
Adicionar um transporte personalizado é fácil. Tudo o que você precisa fazer é aceitar todas as opções necessárias, implementar um método log() e consumi-lo com winston
.
const Transport = require('winston-transport');const util = require('util');//// Herdar de `winston-transport` para que você possa aproveitar // a funcionalidade base e `.exceptions.handle ()`.//module.exports = class YourCustomTransport estende Transporte { construtor (opções) { super (opções); // // Consumir qualquer opção personalizada aqui. ex.: // - Informações de conexão para bancos de dados // - Informações de autenticação para APIs (ex. loggly, papertrail, // logentries, etc.). // } log(info, retorno de chamada) { setImmediate(() => { this.emit('logged', info); }); // Realiza a gravação no serviço remoto callback(); }};
Como todo transporte herda do transporte Winston, é possível definir um formato personalizado e um nível de log personalizado em cada transporte separadamente:
const logger =winston.createLogger({transportes: [newwinston.transports.File({nome do arquivo: 'error.log', nível: 'error', formato:wston.format.json()}), novowinston.transports. Http({nível: 'avisar', formato: winston.format.json() }), novo winston.transports.Console({nível: 'info', formato: winston.format.combine(winston.format.colorize(),winston.format.simple() ) }) ]});
Com winston
, é possível capturar e registrar eventos uncaughtException
do seu processo. Com sua própria instância do logger, você pode ativar esse comportamento quando ele for criado ou posteriormente no ciclo de vida de seus aplicativos:
const { createLogger, transports } = require('winston');// Habilite o tratamento de exceções ao criar seu logger.const logger = createLogger({ transports: [ new transports.File({ filename: 'combined.log' }) ] , exceçãoHandlers: [ new transports.File({ filename: 'exceptions.log' }) ]});// Ou habilite-o mais tarde adicionando um transporte ou usando `.exceptions.handle`const logger = createLogger({ transports: [ new transports.File({ filename: 'combined.log' }) ]});// Chame exceptions.handle com um transporte para lidar com exceptionslogger.exceptions.handle ( new transports.File({ nome do arquivo: 'exceptions.log' }));
Se você quiser usar esse recurso com o criador de logs padrão, basta chamar .exceptions.handle()
com uma instância de transporte.
//// Você pode adicionar um registrador de exceções separado passando-o para `.exceptions.handle`//winston.exceptions.handle( new winston.transports.File({ filename: 'path/to/exceptions.log' }) );//// Alternativamente, você pode definir `handleExceptions` como true ao adicionar transportes// ao Winston.//winston.add(new Winston.transports.File({ filename: 'caminho/para/combined.log', handleExceptions: true}));
Por padrão, o Winston sairá após registrar uma uncaughtException. Se este não for o comportamento desejado, defina exitOnError = false
const logger = winston.createLogger({ exitOnError: false });//// ou, assim://logger.exitOnError = false;
Ao trabalhar com instâncias do criador de logs customizadas, você pode passar transportes separados para a propriedade exceptionHandlers
ou definir handleExceptions
em qualquer transporte.
const logger = winston.createLogger({ transportes: [ new winston.transports.File({ nome do arquivo: 'caminho/para/combined.log' }) ], exceçãoHandlers: [ new winston.transports.File({ nome do arquivo: 'caminho/ to/exceptions.log' }) ]});
const logger =winston.createLogger({transportes: [newwinston.transports.Console({handleExceptions: true })], exitOnError: false});
A opção exitOnError
também pode ser uma função para evitar a saída apenas em certos tipos de erros:
function ignoreEpipe(err) { return err.code !== 'EPIPE';}const logger = winston.createLogger({ exitOnError: ignoreEpipe });//// ou, assim://logger.exitOnError = ignoreEpipe;
Com winston
, é possível capturar e registrar eventos unhandledRejection
do seu processo. Com sua própria instância do logger, você pode ativar esse comportamento quando ele for criado ou posteriormente no ciclo de vida de seus aplicativos:
const { createLogger, transports } = require('winston');// Ativa o tratamento de rejeição ao criar seu logger.const logger = createLogger({ transports: [ new transports.File({ filename: 'combined.log' }) ] , rejeiçãoHandlers: [ new transports.File({ filename: 'rejections.log' }) ]});// Ou habilite-o mais tarde adicionando um transporte ou usando `.rejections.handle`const logger = createLogger({ transports: [ new transports.File({ filename: 'combined.log' }) ]});// Chame rejeições.handle com um transporte para lidar com rejeiçõeslogger.rejections.handle ( new transports.File({ nome do arquivo: 'rejections.log' }));
Se você quiser usar esse recurso com o criador de logs padrão, basta chamar .rejections.handle()
com uma instância de transporte.
//// Você pode adicionar um registrador de rejeição separado passando-o para `.rejections.handle`//winston.rejections.handle( new winston.transports.File({ filename: 'path/to/rejections.log' }) );//// Alternativamente, você pode definir `handleRejections` como true ao adicionar transportes // ao Winston.//winston.add(new Winston.transports.File({ filename: 'caminho/para/combined.log', handleRejections: true}));
Além de registrar mensagens e metadados, winston
também possui um mecanismo simples de criação de perfil implementado para qualquer criador de logs:
//// Iniciar perfil de 'test' //logger.profile('test');setTimeout(function () { // // Parar perfil de 'test'. O registro ocorrerá agora: // '17 Jan 21 :00:00 - informações: duração do teste=1000ms' // logger.profile('test');}, 1000);
Além disso, você pode iniciar um cronômetro e manter uma referência na qual você pode chamar .done()
:
// Retorna um objeto correspondente a um tempo específico. Quando done // for chamado, o cronômetro terminará e registrará a duração. por exemplo: // const profiler = logger.startTimer(); setTimeout(function () { profiler.done({ mensagem: 'Mensagem de registro' }); }, 1000);
Todas as mensagens de perfil são definidas no nível 'info' por padrão, e tanto a mensagem quanto os metadados são opcionais. Para mensagens de perfil individuais, você pode substituir o nível de log padrão fornecendo a um objeto de metadados uma propriedade level
:
logger.profile('teste', {nível: 'depuração' });
winston
oferece suporte à consulta de logs com opções semelhantes ao Loggly. Consulte API de pesquisa Loggly. Especificamente: File
, Couchdb
, Redis
, Loggly
, Nssocket
e Http
.
opções const = {de: nova Data() - (24 * 60 * 60 * 1000), até: nova Data(), limite: 10, início: 0, pedido: 'desc', campos: ['mensagem']} ;//// Encontre itens registrados entre hoje e ontem.//logger.query(options, function (err, results) { if (err) { /* TODO: handle me */ throw err; } console.log(resultados);});
O streaming permite que você transmita seus logs do transporte escolhido.
//// Começa no final.//winston.stream({ start: -1 }).on('log', function(log) { console.log(log);});
O registrador padrão pode ser acessado diretamente através do módulo winston
. Qualquer método que você possa chamar em uma instância de um criador de logs está disponível no criador de logs padrão:
const winston = require('winston');winston.log('info', 'Olá arquivos de log distribuídos!');winston.info('Olá novamente logs distribuídos');winston.level = 'debug';winston.log ('debug', 'Agora minhas mensagens de depuração foram gravadas no console!');
Por padrão, nenhum transporte é configurado no criador de logs padrão. Você deve adicionar ou remover transportes através dos métodos add()
e remove()
:
arquivos const = new winston.transports.File({ nome do arquivo: 'combined.log' });const console = new winston.transports.Console();winston.add(console);winston.add(files);winston.remove (console);
Ou faça isso com uma chamada para configure():
Winston.configure({transportes: [new Winston.transports.File({ nome do arquivo: 'somefile.log' }) ]});
Para obter mais documentação sobre como trabalhar com cada transporte individual suportado pelo winston
consulte o documento winston
Transports.
winston
Muitas vezes é útil esperar que seus logs sejam gravados antes de sair do processo. Cada instância de winston.Logger
também é um [fluxo Node.js]. Um evento finish
será gerado quando todos os logs forem liberados para todos os transportes após o término do fluxo.
const transport = new winston.transports.Console();const logger = winston.createLogger({ transports: [transport]});logger.on('finish', function (info) { // Todas as mensagens de log `info` têm agora foi logado});logger.info('CHILL WINSTON!', { sério: true });logger.end();
Também vale a pena mencionar que o logger também emite um evento de 'erro' se ocorrer um erro dentro do próprio logger, que você deve tratar ou suprimir se não quiser exceções não tratadas:
//// Tratar erros originados no próprio logger //logger.on('error', function (err) { /* Do Something */ });
Freqüentemente, em aplicativos maiores e mais complexos, é necessário ter várias instâncias de registradores com configurações diferentes. Cada registrador é responsável por uma área de recurso (ou categoria) diferente. Isso é exposto no winston
de duas maneiras: por meio de winston.loggers
e instâncias de winston.Container
. Na verdade, winston.loggers
é apenas uma instância predefinida de winston.Container
:
const winston = require('winston');const { format } = winston;const { combine, label, json } = format;//// Configure o logger para `category1`//winston.loggers.add('category1' , { formato: combine( label({ label: 'category one' }), json() ), transportes: [ new winston.transports.Console({ level: 'silly' }), new winston.transports.File({ filename: 'somefile.log' }) ]});//// Configure o logger para `category2`//winston.loggers.add('category2', { format: combine( label ({rótulo: 'categoria dois' }), json() ), transportes: [ new winston.transports.Http({ host: 'localhost', porta:8080 }) ]});
Agora que seus registradores estão configurados, você pode solicitar o Winston em qualquer arquivo do seu aplicativo e acessar esses registradores pré-configurados:
const winston = require('winston');//// Pegue seus registradores pré-configurados//const categoria1 = winston.loggers.get('category1');const categoria2 = winston.loggers.get('category2');category1. info('registrando em transportes de arquivo e console');category2.info('registrando em transporte http');
Se preferir gerenciar o Container
você mesmo, você pode simplesmente instanciar um:
const winston = require ('winston'); (rótulo({rótulo: 'categoria um' }), json() ), transportes: [newwinston.transports.Console({nível: 'bobo' }), novo Winston.transports.File({ filename: 'somefile.log' }) ]});const categoria1 = container.get('category1');category1.info('logging to file and console transports');
Por padrão, o transporte winston.transports.Console
envia mensagens para stdout
e stderr
. Isso é bom na maioria das situações; no entanto, há alguns casos em que isso não é desejável, incluindo:
Depurando usando VSCode e anexando, em vez de iniciar, um processo Node.js
Escrevendo mensagens no formato JSON no AWS Lambda
Registro durante testes do Jest com a opção --silent
Para fazer com que o log de transporte use console.log()
, console.warn()
e console.error()
em vez disso, defina a opção forceConsole
como true
:
const logger = winston.createLogger({ nível: 'info', transportes: [new winston.transports.Console({ forceConsole: true })]});
npm instala o winston
fio adicionar winston
Todos os testes de Winston são escritos com mocha
, nyc
e assume
. Eles podem ser executados com npm
.
teste npm