Un enregistreur pour à peu près tout.
Consultez le Guide de mise à niveau pour plus d'informations. Les rapports de bogues et les relations publiques sont les bienvenus !
[email protected]
? Veuillez noter que la documentation ci-dessous concerne winston@3
. Lisez la documentation [email protected]
.
winston
est conçu pour être une bibliothèque de journalisation simple et universelle prenant en charge plusieurs transports. Un transport est essentiellement un périphérique de stockage pour vos journaux. Chaque enregistreur winston
peut avoir plusieurs transports (voir : Transports) configurés à différents niveaux (voir : Niveaux de journalisation). Par exemple, on peut souhaiter que les journaux d'erreurs soient stockés dans un emplacement distant persistant (comme une base de données), mais que tous les journaux soient envoyés à la console ou à un fichier local.
winston
vise à découpler certaines parties du processus de journalisation pour le rendre plus flexible et extensible. Une attention particulière est portée à la prise en charge de la flexibilité dans le formatage des journaux (voir : Formats) et aux niveaux (voir : Utilisation de niveaux de journalisation personnalisés), et à la garantie que ces API sont découplées de la mise en œuvre de la journalisation de transport (c'est-à-dire comment les journaux sont stockés/indexés, voir : Ajout de paramètres personnalisés). Transports) vers l'API qu'ils ont exposée au programmeur.
TL;DR? Consultez l'exemple de démarrage rapide dans ./examples/
. Il existe un certain nombre d'autres exemples dans ./examples/*.js
. Vous ne voyez pas d'exemple qui, selon vous, devrait être présent ? Soumettez une pull request pour l’ajouter !
La méthode recommandée pour utiliser winston
est de créer votre propre enregistreur. La façon la plus simple de procéder consiste à utiliser winston.createLogger
:
const winston = require('winston');const logger = winston.createLogger({ niveau : 'info', format : winston.format.json(), defaultMeta : { service : 'user-service' }, transports : [ / / // - Écrivez tous les journaux avec un niveau d'importance de `error` ou supérieur dans `error.log` // (c'est-à-dire erreur, fatal, mais pas les autres niveaux) // new winston.transports.File({ nom de fichier : 'error.log', niveau : 'error' }), // // - Écrivez tous les journaux avec un niveau d'importance de `info` ou supérieur dans `combined.log` // (c'est-à-dire fatal, erreur, avertissement, et informations, mais pas de trace) // new winston.transports.File({ filename: 'combined.log' }), ],});//// Si nous ne sommes pas en production, connectez-vous à la `console` avec le format:// `${info.level} : ${info.message} JSON.stringify({ ...rest }) `//if (process.env.NODE_ENV !== 'production') { logger. ajouter(nouveau winston.transports.Console({ format : winston.format.simple(), }));}
Vous pouvez également vous connecter directement via l'enregistreur par défaut exposé par require('winston')
, mais celui-ci est simplement destiné à être un enregistreur partagé pratique à utiliser dans toute votre application si vous le souhaitez. Notez que l'enregistreur par défaut n'a aucun transport par défaut. Vous devez ajouter des transports par vous-même, et laisser l'enregistreur par défaut sans aucun transport peut produire un problème d'utilisation élevée de la mémoire.
Motivation
Démarrage rapide
Usage
Table des matières
Enregistrement
Créer votre enregistreur
Flux, objectMode
et objets info
Formats
Combiner des formats
Interpolation de chaîne
Filtrage info
sur les objets
Création de formats personnalisés
Niveaux de journalisation
Utiliser les niveaux de journalisation
Utilisation de niveaux de journalisation personnalisés
Transports
Plusieurs transports du même type
Ajout de transports personnalisés
Options de transport communes
Exceptions
Gestion des exceptions non interceptées avec Winston
Sortir ou ne pas sortir
Rejets
Gérer les rejets de promesses non capturées avec Winston
Profilage
Journaux de streaming
Interrogation des journaux
Lectures complémentaires
Utiliser l'enregistreur par défaut
En attente d'écriture des journaux dans winston
Travailler avec plusieurs enregistreurs à winston
La console de routage transporte les messages vers la console au lieu de stdout et stderr
Installation
Exécuter des tests
Les niveaux de journalisation dans winston
sont conformes à l'ordre de gravité spécifié par la RFC5424 : la gravité de tous les niveaux est supposée être numériquement croissante, du plus important au moins important.
const niveaux = { erreur : 0, avertissement : 1, info : 2, http : 3, verbeux : 4, débogage : 5, idiot : 6} ;
Vous commencez par créer un enregistreur en utilisant winston.createLogger
:
const logger = winston.createLogger({ transports : [ new winston.transports.Console(), new winston.transports.File({ filename : 'combined.log' }) ]});
Un enregistreur accepte les paramètres suivants :
Nom | Défaut | Description |
---|---|---|
level | 'info' | Enregistrez uniquement si info.level est inférieur ou égal à ce niveau |
levels | winston.config.npm.levels | Niveaux (et couleurs) représentant les priorités des journaux |
format | winston.format.json | Formatage des messages info (voir : Formats) |
transports | [] (Pas de transport) | Ensemble de cibles de journalisation pour les messages info |
exitOnError | true | Si faux, les exceptions gérées ne provoqueront pas process.exit |
silent | false | Si c'est vrai, tous les journaux sont supprimés |
Les niveaux fournis à createLogger
seront définis comme méthodes pratiques sur le logger
renvoyé.
//// Logging//logger.log({ level: 'info', message: 'Bonjour les fichiers journaux distribués !'});logger.info('Bonjour à nouveau les journaux distribués');
Vous pouvez ajouter ou supprimer des transports de l' logger
une fois qu'il vous a été fourni par winston.createLogger
:
const files = new winston.transports.File({ filename: 'combined.log' });const console = new winston.transports.Console();logger .clear() // Supprime tous les transports .add(console) // Ajouter un transport de console .add(files) // Ajouter un transport de fichiers .remove(console); // Supprime le transport de la console
Vous pouvez également reconfigurer en gros une instance winston.Logger
à l'aide de la méthode configure
:
const logger = winston.createLogger({ niveau : 'info', transports : [ new winston.transports.Console(), new winston.transports.File({ nom de fichier : 'combined.log' }) ]});/// / Remplace les transports précédents par ceux de la// nouvelle configuration en gros.//const DailyRotateFile = require('winston-daily-rotate-file');logger.configure({ niveau : 'verbeux', transports : [ new DailyRotateFile(opts) ]});
Vous pouvez créer des enregistreurs enfants à partir d'enregistreurs existants pour transmettre les remplacements de métadonnées :
const logger = winston.createLogger({ transports : [ new winston.transports.Console(), ]});const childLogger = logger.child({ requestId : '451' });
.child
est susceptible d'être buggé si vous étendez également la classeLogger
, en raison de certains détails d'implémentation qui font quethis
mot-clé pointe vers des choses inattendues. A utiliser avec prudence.
objectMode
et objets info
Dans winston
, les instances Logger
et Transport
sont traitées comme des flux objectMode
qui acceptent un objet info
.
Le paramètre info
fourni à un format donné représente un seul message de journal. L'objet lui-même est mutable. Chaque info
doit avoir au moins les propriétés level
et message
:
const info = { level : 'info', // Niveau du message de journalisation message : 'Hey ! Enregistrer quelque chose ? // Message descriptif en cours de journalisation.};
Les propriétés autres que le niveau et le message sont considérées comme des « meta
». c'est à dire :
const { niveau, message, ... méta } = info;
Plusieurs formats du logform
lui-même ajoutent des propriétés supplémentaires :
Propriété | Format ajouté par | Description |
---|---|---|
splat | splat() | Splat d'interpolation de chaîne pour les messages de style %d %s . |
timestamp | timestamp() | horodatage de la réception du message. |
label | label() | Etiquette personnalisée associée à chaque message. |
ms | ms() | Nombre de millisecondes depuis le message de journal précédent. |
En tant que consommateur, vous pouvez ajouter les propriétés de votre choix – l'état interne est maintenu par les propriétés Symbol
:
Symbol.for('level')
(LECTURE SEULE) : égal à la propriété level
. Est traité comme immuable par tout le code.
Symbol.for('message'):
chaîne de message complète définie par "finalisation des formats" :
json
logstash
printf
prettyPrint
simple
Symbol.for('splat')
: arguments d'interpolation de chaîne supplémentaires. Utilisé exclusivement par le format splat()
.
Ces Symboles sont stockés dans un autre package : triple-beam
afin que tous les consommateurs de logform
puissent avoir la même référence de Symbole. c'est à dire :
const { NIVEAU, MESSAGE, SPLAT } = require('triple-beam');console.log(LEVEL === Symbol.for('level'));// trueconsole.log(MESSAGE === Symbol.for( 'message'));// trueconsole.log(SPLAT === Symbol.for('splat'));// true
REMARQUE : toute propriété
{ message }
dans unmeta
-objet fourni sera automatiquement concaténée à toutmsg
déjà fourni : par exemple, ce qui suit concatènera "world" sur "hello" :logger.log('erreur', 'bonjour', { message : 'monde' });logger.info('bonjour', { message : 'monde' });
Les formats dans winston
sont accessibles à partir de winston.format
. Ils sont implémentés sous logform
, un module distinct de winston
. Cela permet une flexibilité lors de l'écriture de vos propres transports au cas où vous souhaiteriez inclure un format par défaut avec votre transport.
Dans les versions modernes des chaînes de modèles node
, les chaînes sont très performantes et constituent la méthode recommandée pour effectuer la plupart des formats destinés à l'utilisateur final. Si vous souhaitez formater vos logs sur mesure, winston.format.printf
est fait pour vous :
const { createLogger, format, transports } = require('winston');const { combine, timestamp, label, printf } = format;const myFormat = printf(({ niveau, message, étiquette, timestamp }) => { return ` ${timestamp} [${label}] ${level} : ${message}`;});const logger = createLogger({ format : combiner( label({ label : 'right miaou !' }), timestamp(), myFormat ), transports : [new transports.Console()]});
Pour voir quels formats intégrés sont disponibles et en savoir plus sur la création de vos propres formats de journalisation personnalisés, consultez logform
.
N'importe quel nombre de formats peut être combiné en un seul format à l'aide de format.combine
. Puisque format.combine
ne prend pas opts
, pour plus de commodité, il renvoie une instance pré-créée du format combiné.
const { createLogger, format, transports } = require('winston');const { combine, timestamp, label, PrettyPrint } = format;const logger = createLogger({ format: combine( label({ label: 'right miaou !' } ), timestamp(), PrettyPrint() ), transports : [new transports.Console()]})logger.log({ level : 'info', message : 'À quelle heure sont les tests at?'});// Outputs:// { level: 'info',// message: 'À quelle heure ont lieu les tests?',// label: 'right miaou!',// timestamp: '2017- 09-30T03:57:26.875Z'}
La méthode log
fournit l'interpolation de chaîne à l'aide de util.format. Il doit être activé à l'aide de format.splat()
.
Vous trouverez ci-dessous un exemple qui définit un format avec interpolation de chaîne de messages à l'aide de format.splat
, puis sérialise l'intégralité du message info
à l'aide de format.simple
.
const { createLogger, format, transports } = require('winston');const logger = createLogger({ format: format.combine( format.splat(), format.simple() ), transports : [new transports.Console() ]});// info : message de test ma chaîne {}logger.log('info', 'message de test %s', 'ma chaîne');// info : message de test 123 {}logger.log('info', 'test message %d', 123);// info : test message première seconde {numéro : 123}logger.log('info', 'test message %s, %s' , 'premier', 'second', { nombre : 123 } );
info
sur les objets Si vous souhaitez filtrer complètement un objet info
donné lors de la connexion, renvoyez simplement une valeur fausse.
const { createLogger, format, transports } = require('winston');// Ignorer les messages du journal s'ils ont { private: true }const ignorePrivate = format((info, opts) => { if (info.private) { return false; } return info;});const logger = createLogger({ format: format.combine( ignorePrivate(), format.json() ), transports: [new transports.Console()]});// Sorties : {"level": "erreur", "message": "Erreur publique à partager"}logger.log({ niveau: 'erreur', message: 'Erreur publique à partager'});// Messages avec { privé : true } ne sera pas écrit lorsque logged.logger.log({ private: true, level: 'error', message: 'Ceci est super secret - cachez-le.'});
L'utilisation de format.combine
respectera tout retour de valeurs fausses et arrêtera l'évaluation des formats ultérieurs de la série. Par exemple:
const { format } = require('winston');const { combine, timestamp, label } = format;const willNeverThrow = format.combine( format(info => { return false })(), // Ignore tout format(info => { throw new Error('Jamais atteint') })());
Les formats sont des objets prototypiques (c'est-à-dire des instances de classe) qui définissent une seule méthode : transform(info, opts)
et renvoient les info
mutées :
info
: un objet représentant le message du journal.
opts
: paramètre spécifique à l'instance actuelle du format.
On s'attend à ce qu'ils retournent l'une des deux choses suivantes :
Un objet info
représentant l’argument info
modifié. Les références d'objet n'ont pas besoin d'être préservées si l'immuabilité est préférée. Tous les formats intégrés actuels considèrent info
comme mutables, mais [immutablejs] est envisagé pour les versions futures.
Une valeur fausse indiquant que l'argument info
doit être ignoré par l'appelant. (Voir : Filtrage des objets info
) ci-dessous.
winston.format
est conçu pour être aussi simple que possible. Pour définir un nouveau format, transmettez-lui simplement une fonction transform(info, opts)
pour obtenir un nouveau Format
.
Le Format
nommé renvoyé peut être utilisé pour créer autant de copies du Format
donné que vous le souhaitez :
const { format } = require('winston');const volume = format((info, opts) => { if (opts.yell) { info.message = info.message.toUpperCase(); } else if (opts. murmur) { info.message = info.message.toLowerCase(); } return info;});// `volume` est maintenant une fonction qui renvoie des instances du format.const scream = volume({ yell: true });console.dir(scream.transform({ level: 'info', message: `désolé de t'avoir fait CRIER dans ta tête !`}, scream.options));// {// level : 'info'// message : 'DÉSOLÉ DE VOUS FAIRE CRIER DANS VOTRE TÊTE !'// }// `volume` peut être utilisé plusieurs fois pour créer différents formats.const murmure = volume({ murmure : vrai });console.dir(whisper.transform({ level: 'info', message: `POURQUOI NOUS FONT-ILS TELLEMENT CRIER!`}, murmur.options));// {// level: 'info'/ / message : 'Pourquoi nous font-ils autant crier !'// }
Les niveaux de journalisation dans winston
sont conformes à l'ordre de gravité spécifié par la RFC5424 : la gravité de tous les niveaux est supposée être numériquement croissante, du plus important au moins important.
Chaque level
se voit attribuer une priorité entière spécifique. Plus la priorité est élevée, plus le message est considéré comme important et plus la priorité entière correspondante est faible. Par exemple, comme spécifié exactement dans la RFC5424, les niveaux syslog
sont hiérarchisés de 0 à 7 (du plus élevé au plus bas).
{ emerg : 0, alerte : 1, critique : 2, erreur : 3, avertissement : 4, avis : 5, info : 6, débogage : 7}
De même, les niveaux de journalisation npm
sont hiérarchisés de 0 à 6 (du plus élevé au plus bas) :
{ erreur : 0, avertissement : 1, info : 2, http : 3, détaillé : 4, débogage : 5, idiot : 6}
Si vous ne définissez pas explicitement les niveaux que winston
doit utiliser, les niveaux npm
ci-dessus seront utilisés.
La définition du niveau de votre message de journalisation peut être effectuée de deux manières. Vous pouvez transmettre une chaîne représentant le niveau de journalisation à la méthode log() ou utiliser les méthodes spécifiées par le niveau définies sur chaque Winston Logger.
//// Toute instance d'enregistreur //logger.log('idiot', "127.0.0.1 - il n'y a pas d'endroit comme à la maison");logger.log('debug', "127.0.0.1 - il n'y a pas d'endroit comme à la maison") ;logger.log('verbose', "127.0.0.1 - il n'y a pas d'endroit comme chez soi");logger.log('info', "127.0.0.1 - il n'y a pas d'endroit comme chez soi");logger.log('warn', "127.0.0.1 - il n'y a pas d'endroit comme chez soi");logger.log('error', "127.0.0.1 - il n'y a pas de place comme à la maison");logger.info("127.0.0.1 - il n'y a aucun endroit comme home");logger.warn("127.0.0.1 - il n'y a pas d'endroit comme la maison");logger.error("127.0.0.1 - il n'y a pas d'endroit comme la maison");//// Enregistreur par défaut//winston.log( 'info', "127.0.0.1 - il n'y a pas d'endroit comme chez soi");winston.info("127.0.0.1 - il n'y a pas d'endroit comme chez soi");winston.info("127.0.0.1 - il n'y a pas d'endroit comme chez soi maison");
winston
vous permet de définir une propriété level
sur chaque transport qui spécifie le niveau maximum de messages qu'un transport doit enregistrer. Par exemple, en utilisant les niveaux syslog
vous pouvez enregistrer uniquement les messages error
sur la console et toutes info
ci-dessous dans un fichier (qui comprend les messages error
) :
const logger = winston.createLogger({ niveaux : winston.config.syslog.levels, transports : [ new winston.transports.Console({ niveau : 'erreur' }), new winston.transports.File({ nom de fichier : 'combiné. log', niveau : 'info' }) ]});
Vous pouvez également modifier dynamiquement le niveau de journalisation d'un transport :
const transports = { console : new winston.transports.Console({ niveau : 'warn' }), fichier : new winston.transports.File({ nom de fichier : 'combined.log', niveau : 'erreur' })};const logger = winston.createLogger({ transports: [ transports.console, transports.file ]});logger.info('Ne sera pas connecté non plus transport!');transports.console.level = 'info';transports.file.level = 'info';logger.info('Sera connecté aux deux transports!');
winston
prend en charge les niveaux de journalisation personnalisables, par défaut sur les niveaux de journalisation de style npm. Les niveaux doivent être précisés au moment de la création de votre logger.
En plus des niveaux npm
, syslog
et cli
prédéfinis disponibles dans winston
, vous pouvez également choisir de définir les vôtres :
const myCustomLevels = { niveaux : { foo : 0, bar : 1, baz : 2, foobar : 3 }, couleurs : { foo : 'bleu', barre : 'vert', baz : 'jaune', foobar : 'rouge' }};const customLevelLogger = winston.createLogger({ niveaux : myCustomLevels.levels});customLevelLogger.foobar('some message de niveau foobar');
Bien qu'il y ait une légère répétition dans cette structure de données, elle permet une encapsulation simple si vous ne souhaitez pas avoir de couleurs. Si vous souhaitez avoir des couleurs, en plus de transmettre les niveaux au Logger lui-même, vous devez en informer Winston :
winston.addColors(myCustomLevels.colors);
Cela permet aux enregistreurs utilisant le formateur colorize
de colorer et de styliser de manière appropriée la sortie des niveaux personnalisés.
De plus, vous pouvez également modifier la couleur d’arrière-plan et le style de police. Par exemple,
baz : 'jaune italique',foobar : 'cyanBG rouge gras'
Les options possibles sont ci-dessous.
Styles de police : bold
, dim
, italic
, underline
, inverse
, hidden
, strikethrough
.
Couleurs de premier plan de la police : black
, red
, green
, yellow
, blue
, magenta
, cyan
, white
, gray
, grey
.
Couleurs d'arrière-plan : blackBG
, redBG
, greenBG
, yellowBG
, blueBG
, magentaBG
, cyanBG
, whiteBG
Pour coloriser le niveau de journalisation standard, ajoutez
winston.format.combine( winston.format.colorize(), winston.format.simple());
où winston.format.simple()
est tout autre formateur que vous souhaitez utiliser. Le formateur colorize
doit précéder tout formateur ajoutant le texte que vous souhaitez colorer.
Pour coloriser la ligne de journal complète avec le formateur json, vous pouvez appliquer ce qui suit
winston.format.combine( winston.format.json(), winston.format.colorize({ all: true }));
Il existe plusieurs transports principaux inclus dans winston
, qui exploitent la mise en réseau intégrée et les E/S de fichiers offertes par le noyau Node.js. De plus, il existe des transports supplémentaires écrits par des membres de la communauté.
Il est possible d'utiliser plusieurs transports du même type, par exemple winston.transports.File
lorsque vous construisez le transport.
const logger = winston.createLogger({ transports : [ new winston.transports.File({ nom de fichier : 'combined.log', niveau : 'info' }), new winston.transports.File({ nom de fichier : 'errors.log' , niveau : 'erreur' }) ]});
Si vous souhaitez ultérieurement supprimer l'un de ces transports, vous pouvez le faire en utilisant le transport lui-même. par exemple :
const CombinedLogs = logger.transports.find(transport => { return transport.filename === 'combined.log'});logger.remove(combinedLogs);
Ajouter un transport personnalisé est simple. Tout ce que vous avez à faire est d'accepter toutes les options dont vous avez besoin, d'implémenter une méthode log() et de la consommer avec winston
.
const Transport = require('winston-transport');const util = require('util');//// Héritez de `winston-transport` afin de pouvoir profiter// des fonctionnalités de base et de `.exceptions.handle ()`.//module.exports = class YourCustomTransport extends Transport { constructor(opts) { super(opts); // // Consomme toutes les options personnalisées ici. Par exemple : // - Informations de connexion pour les bases de données // - Informations d'authentification pour les API (par exemple loggly, papertrail, // logentries, etc.). // } log(info, callback) { setImmediate(() => { this.emit('logged', info); }); // Effectue l'écriture dans le rappel du service distant (); }} ;
Comme chaque transport hérite de winston-transport, il est possible de définir un format personnalisé et un niveau de journalisation personnalisé sur chaque transport séparément :
const logger = winston.createLogger({ transports : [ new winston.transports.File({ filename : 'error.log', niveau : 'error', format : winston.format.json() }), new winston.transports. Http({ niveau : 'warn', format : winston.format.json() }), nouveau winston.transports.Console({ niveau : 'info', format : winston.format.combine( winston.format.colorize(), winston.format.simple() ) }) ]});
Avec winston
, il est possible d'attraper et de consigner les événements uncaughtException
de votre processus. Avec votre propre instance de logger, vous pouvez activer ce comportement lors de sa création ou ultérieurement dans le cycle de vie de vos applications :
const { createLogger, transports } = require('winston');// Activer la gestion des exceptions lorsque vous créez votre logger.const logger = createLogger({ transports: [ new transports.File({ filename: 'combined.log' }) ] , exceptionHandlers : [ new transports.File({ filename: 'exceptions.log' }) ]});// Ou activez-le plus tard en ajoutant un transport ou en utilisant `.exceptions.handle`const logger = createLogger({ transports: [ new transports.File({ filename: 'combined.log' }) ]});// Appelez exceptions.handle avec un transport pour gérer exceptionslogger.exceptions.handle ( new transports.File({ filename: 'exceptions.log' }));
Si vous souhaitez utiliser cette fonctionnalité avec le logger par défaut, appelez simplement .exceptions.handle()
avec une instance de transport.
//// Vous pouvez ajouter un enregistreur d'exceptions distinct en le transmettant à `.exceptions.handle`//winston.exceptions.handle( new winston.transports.File({ filename: 'path/to/exceptions.log' }) );//// Vous pouvez également définir `handleExceptions` sur true lors de l'ajout de transports// à winston.//winston.add(new winston.transports.File({ filename : 'chemin/vers/combined.log', handleExceptions : true}));
Par défaut, Winston se fermera après avoir enregistré une exception uncaughtException. Si ce n'est pas le comportement souhaité, définissez exitOnError = false
const logger = winston.createLogger({ exitOnError: false });//// ou, comme ceci://logger.exitOnError = false;
Lorsque vous travaillez avec des instances de journalisation personnalisées, vous pouvez transmettre des transports distincts à la propriété exceptionHandlers
ou définir handleExceptions
sur n'importe quel transport.
const logger = winston.createLogger({ transports : [ new winston.transports.File({ nom de fichier : 'path/to/combined.log' }) ], exceptionHandlers : [ new winston.transports.File({ nom de fichier : 'path/ to/exceptions.log' }) ]});
const logger = winston.createLogger({ transports : [ new winston.transports.Console({ handleExceptions : true }) ], exitOnError : false});
L'option exitOnError
peut également être une fonction permettant d'empêcher la sortie uniquement sur certains types d'erreurs :
function ignoreEpipe(err) { return err.code !== 'EPIPE';}const logger = winston.createLogger({ exitOnError: ignoreEpipe });//// ou, comme ceci://logger.exitOnError = ignoreEpipe;
Avec winston
, il est possible d'attraper et d'enregistrer les événements de unhandledRejection
de votre processus. Avec votre propre instance de logger, vous pouvez activer ce comportement lors de sa création ou ultérieurement dans le cycle de vie de vos applications :
const { createLogger, transports } = require('winston');// Activer la gestion des rejets lorsque vous créez votre logger.const logger = createLogger({ transports: [ new transports.File({ filename: 'combined.log' }) ] , rejetHandlers : [ new transports.File({ filename: 'rejections.log' }) ]});// Ou activez-le plus tard en ajoutant un transport ou en utilisant `.rejections.handle`const logger = createLogger({ transports: [ new transports.File({ filename: 'combined.log' }) ]});// Appelez rejets.handle avec un transport pour gérer les rejetslogger.rejections.handle ( new transports.File({ filename: 'rejections.log' }));
Si vous souhaitez utiliser cette fonctionnalité avec l'enregistreur par défaut, appelez simplement .rejections.handle()
avec une instance de transport.
//// Vous pouvez ajouter un enregistreur de rejet distinct en le transmettant à `.rejections.handle`//winston.rejections.handle( new winston.transports.File({ filename: 'path/to/rejections.log' }) );//// Vous pouvez également définir `handleRejections` sur true lors de l'ajout de transports// à winston.//winston.add(new winston.transports.File({ filename : 'chemin/vers/combined.log', handleRejections : true}));
En plus de journaliser les messages et les métadonnées, winston
dispose également d'un mécanisme de profilage simple implémenté pour n'importe quel enregistreur :
//// Démarrage du profil de 'test'//logger.profile('test');setTimeout(function () { // // Arrêt du profil de 'test'. La journalisation aura maintenant lieu : // '17 janvier 21 :00:00 - info : durée du test=1000ms' // logger.profile('test');}, 1000);
Vous pouvez également démarrer une minuterie et conserver une référence sur laquelle vous pouvez appeler .done()
:
// Renvoie un objet correspondant à un timing spécifique. Une fois terminé // est appelé, la minuterie se terminera et enregistrera la durée. par exemple : // const profiler = logger.startTimer(); setTimeout(function () { profiler.done({ message : 'Message de journalisation' }); }, 1000);
Tous les messages de profil sont définis par défaut au niveau « info », et le message et les métadonnées sont facultatifs. Pour les messages de profil individuels, vous pouvez remplacer le niveau de journalisation par défaut en fournissant un objet de métadonnées avec une propriété level
:
logger.profile('test', { niveau : 'debug' });
winston
prend en charge l'interrogation des journaux avec des options de type Loggly. Voir API de recherche Loggly. Plus précisément : File
, Couchdb
, Redis
, Loggly
, Nssocket
et Http
.
const options = { de : new Date() - (24 * 60 * 60 * 1000), jusqu'à : new Date(), limite : 10, début : 0, ordre : 'desc', champs : ['message']} ;//// Rechercher les éléments enregistrés entre aujourd'hui et hier.//logger.query(options, function (err, results) { if (err) { /* TODO : handle me */ throw err; } console.log(results);});
Le streaming vous permet de diffuser vos journaux depuis le transport choisi.
//// Commencer à la fin.//winston.stream({ start: -1 }).on('log', function(log) { console.log(log);});
L'enregistreur par défaut est accessible directement via le module winston
. Toute méthode que vous pouvez appeler sur une instance d'un enregistreur est disponible sur l'enregistreur par défaut :
const winston = require('winston');winston.log('info', 'Bonjour les fichiers journaux distribués !');winston.info('Bonjour à nouveau les journaux distribués');winston.level = 'debug';winston.log ('debug', 'Maintenant, mes messages de débogage sont écrits sur la console !');
Par défaut, aucun transport n'est défini sur l'enregistreur par défaut. Vous devez ajouter ou supprimer des transports via les méthodes add()
et remove()
:
const files = new winston.transports.File({ nom de fichier : 'combined.log' });const console = new winston.transports.Console();winston.add(console);winston.add(files);winston.remove (console);
Ou faites-le avec un seul appel à configure() :
winston.configure({ transports : [ new winston.transports.File({ filename : 'somefile.log' }) ]});
Pour plus de documentation sur l'utilisation de chaque transport individuel pris en charge par winston
consultez le document winston
Transports.
winston
Il est souvent utile d'attendre que vos logs soient écrits avant de quitter le processus. Chaque instance de winston.Logger
est également un [flux Node.js]. Un événement finish
sera déclenché lorsque tous les journaux auront été vidés vers tous les transports après la fin du flux.
const transport = new winston.transports.Console();const logger = winston.createLogger({ transports: [transport]});logger.on('finish', function (info) { // Tous les messages du journal `info` ont maintenant connecté});logger.info('CHILL WINSTON!', { sérieusement: true });logger.end();
Il convient également de mentionner que l'enregistreur émet également un événement « erreur » si une erreur se produit dans l'enregistreur lui-même, que vous devez gérer ou supprimer si vous ne souhaitez pas d'exceptions non gérées :
//// Gérer les erreurs provenant du logger lui-même//logger.on('error', function (err) { /* Do Something */ });
Souvent, dans les applications plus grandes et plus complexes, il est nécessaire de disposer de plusieurs instances d'enregistreur avec des paramètres différents. Chaque enregistreur est responsable d'une zone de fonctionnalités (ou catégorie) différente. Ceci est exposé dans winston
de deux manières : via winston.loggers
et les instances de winston.Container
. En fait, winston.loggers
n'est qu'une instance prédéfinie de winston.Container
:
const winston = require('winston');const { format } = winston;const { combine, label, json } = format;//// Configurez l'enregistreur pour `category1`//winston.loggers.add('category1' , { format : combiner( label({ label: 'category one' }), json() ), transports : [ new winston.transports.Console({ level: 'idiot' }), new winston.transports.File({ filename: 'somefile.log' }) ]});//// Configurez l'enregistreur pour `category2`//winston.loggers.add('category2', { format: combiner( label({ label : 'category two' }), json() ), transports : [ new winston.transports.Http({ hôte : 'localhost', port:8080 }) ]});
Maintenant que vos enregistreurs sont configurés, vous pouvez exiger Winston dans n'importe quel fichier de votre application et accéder à ces enregistreurs préconfigurés :
const winston = require('winston');//// Récupérez vos enregistreurs préconfigurés//constcategory1 = winston.loggers.get('category1');constcategory2 = winston.loggers.get('category2');category1. info('logging sur les transports de fichiers et de console');category2.info('logging sur le transport http');
Si vous préférez gérer le Container
vous-même, vous pouvez simplement en instancier un :
const winston = require('winston');const { format } = winston;const { combiner, label, json } = format;const conteneur = new winston.Container();container.add('category1', { format: combiner ( label({ label: 'category one' }), json() ), transports : [ new winston.transports.Console({ level: 'silly' }), new winston.transports.File({ filename: 'somefile.log' }) ]});constcategory1 = containers.get('category1');category1.info('logging to file and console transports');
Par défaut, le transport winston.transports.Console
envoie des messages à stdout
et stderr
. C'est très bien dans la plupart des situations ; cependant, il existe certains cas où cela n'est pas souhaitable, notamment :
Débogage à l'aide de VSCode et attachement à un processus Node.js plutôt que de le lancer
Écriture de messages au format JSON dans AWS Lambda
Journalisation pendant les tests Jest avec l'option --silent
Pour que le journal de transport utilise plutôt console.log()
, console.warn()
et console.error()
, définissez l'option forceConsole
sur true
:
const logger = winston.createLogger({ niveau : 'info', transports : [new winston.transports.Console({ forceConsole : true })]});
npm installer Winston
fil ajouter Winston
Tous les tests Winston sont écrits avec mocha
, nyc
et assume
. Ils peuvent être exécutés avec npm
.
test npm