Parlons de la journalisation, d’accord? Arnold ici portant une bûche géante ressemble à une introduction appropriée à cet article dans lequel nous allons parler de nœud populaire.cadres de journalisation js.
Si vous écrivez n’importe quel type d’application de longue durée, la journalisation détaillée est primordiale pour repérer les problèmes et le débogage. Sans journaux, vous auriez peu de moyens de dire comment se comporte votre application, y a-t-il des erreurs, à quoi ressemblent les performances, fait-elle quoi que ce soit ou tombe-t-elle simplement sur toutes les autres demandes lorsque vous ne la regardez pas.
Requirements
Permet d’identifier quelques exigences que nous pouvons utiliser pour opposer les frameworks les uns aux autres. Certaines de ces exigences sont assez triviales, d’autres ne le sont pas tellement.
- Horodatage de chaque ligne de journal. Celui–ci est assez explicite – vous devriez pouvoir dire quand chaque entrée de journal s’est produite.
- Le format de journalisation doit être facile à digérer par les humains comme par les machines.
- Permet de configurer plusieurs flux de destination. Par exemple, vous pouvez écrire des journaux de traces dans un fichier, mais lorsqu’une erreur se produit, écrivez dans le même fichier, puis dans le fichier d’erreur et envoyez un e-mail en même temps.
Sur la base de ces exigences (et de leur popularité), il existe deux frameworks de journalisation pour Node.js vaut le détour, en particulier:
- Bunyan par Trent Mick.
- Winston fait partie du framework Flatiron et est sponsorisé par nodejitstu.
console
Avant d’arriver à Bunyan et Winston, regardons notre vieil ami console
. Le type de journalisation le plus rudimentaire que vous puissiez faire est d’utiliser les méthodes console.log
et console.error
. C’est mieux que rien mais à peine la meilleure solution. La console écrit sur STDOUT et STDERR respectivement. Il y a une mise en garde très intéressante à savoir en ce qui concerne les méthodes console
dans le nœud.js.
Les fonctions de la console sont synchrones lorsque la destination est un terminal ou un fichier (pour éviter la perte de messages en cas de sortie prématurée) et asynchrones lorsqu’il s’agit d’un tuyau (pour éviter le blocage pendant de longues périodes).
C’est-à-dire, dans l’exemple suivant, stdout ne bloque pas tandis que stderr bloque :
$ node script.js 2> error.log | tee info.log
Il s’agit essentiellement d’une approche de journalisation « roll your own ». C’est entièrement manuel, vous devez créer votre propre format et tout gérer vous-même. Cela prend du temps, est sujet aux erreurs et vous souhaitez probablement vous concentrer sur les fonctionnalités de votre application. Étant donné qu’il existe des bibliothèques de journalisation open source qui sont activement maintenues, cela n’en vaut pas la peine si vous essayez de vous concentrer sur la fourniture de fonctionnalités.
Winston
L’un des nœuds les plus populaires.les frameworks de journalisation js sont Winston. Il est conçu pour être une bibliothèque de journalisation simple et universelle prenant en charge plusieurs transports (un transport dans le monde de Winston est essentiellement un périphérique de stockage, par exemple où vos journaux finissent par être stockés). Chaque instance d’un enregistreur Winston peut avoir plusieurs transports configurés à différents niveaux de journalisation.
Installation
npm install winston
Utilisation
L’utilisation la plus basique de Winston consiste à appeler l’instance par défaut exportée depuis le module winston
.
var winston = require('winston');winston.log('info', 'Hello distributed log files!');winston.info('Hello again distributed logs');
Ce qui précède est le même que:
Les deux exemples produiront la sortie suivante:
info: Hello distributed log files!info: Hello again distributed logs
Formatage
Personnellement, je suis un peu perplexe par le manque de détails dans le formateur par défaut. Il n’y a pas d’horodatage, de nom de machine ou d’ID de processus et le format de sortie est légèrement adapté à l’analyse de la machine. Cela dit, vous pouvez obtenir toutes les informations vous-même avec juste un peu de travail supplémentaire.
winston.info('Hello world!', {timestamp: Date.now(), pid: process.pid});
Produit la sortie suivante, qui est plus informative, mais qui n’est toujours pas très adaptée à l’analyse de la machine.
info: Hello world! timestamp=1402286804314, pid=80481
Enfin, la méthode log
fournit les mêmes méthodes d’interpolation de chaîne que util.format
, par exemple :
winston.log('info', 'test message %d', 123);
Les transporteurs
Winston peuvent être configurés via des options de constructeur ou une méthode exposée qui sont très documentées sur la page GitHub. La plupart de la configuration tourne généralement autour de divers transports. Winston prêt à l’emploi est livré avec des transports basés sur la console et les fichiers et si vous jetez un coup d’œil sur npmjs.org vous verrez qu’il existe des modules communautaires pour à peu près tout ce qui est imaginable, allant de MongoDB aux plates-formes commerciales tierces.
L’un des transporteurs les plus remarquables à mon avis est winston-irc de Nathan Zadoks que vous pouvez utiliser pour enregistrer les erreurs sur le canal IRC de votre équipe. Je peux voir cela très utile.
winston.add(require('winston-irc'), { host: 'irc.somewhere.net', nick: 'logger', pass: 'hunter2', channels: { '#logs': true, 'sysadmin': }});
Plusieurs enregistreurs
Une fois que votre application commence à se développer, il est probable que vous souhaitiez avoir plusieurs enregistreurs avec des configurations différentes où chaque enregistreur est responsable d’une zone d’entité (ou d’une catégorie) différente. Winston prend en charge cela de deux manières : via winston.loggers
et des instances de winston.Container
. En fait, winston.loggers
n’est qu’une instance prédéfinie de winston.Container
:
winston.loggers.add('category1', {console: { ... }, file: { ... }});winston.loggers.add('category2', {irc: { ... }, file: { ... }});
Maintenant que vos enregistreurs sont configurés, vous pouvez avoir besoin de Winston dans n’importe quel fichier de votre application et accéder à ces enregistreurs préconfigurés :
var category1 = winston.loggers.get('category1');category1.info('logging from your IoC container-based logger');
Plus
C’est l’utilisation la plus basique de Winston, mais il y a pas mal d’autres fonctionnalités, notamment:
- Profilage
- Interpolation de chaîne
- Interrogation et diffusion en continu
- Gestion des exeptions
Bunyan
Illustration de Brendan Corris
Bunyan de Trent Mick est un autre cadre de journalisation qui devrait être considéré. Bunyan adopte une approche de l’exploitation forestière légèrement différente de celle de Winston, qui a pour mission de fournir des journaux structurés et lisibles par machine en tant que citoyens de première classe. En conséquence, un enregistrement de journal de Bunyan est une ligne de sortie JSON.stringify
avec des noms communs pour les champs requis et communs pour un enregistrement de journal.
Installation
npm install bunyan
Utilisation
var bunyan = require('bunyan');var log = bunyan.createLogger({name: 'myapp'});log.info('hi');log.warn({lang: 'fr'}, 'au revoir');
Qui produira la sortie suivante:
Comme vous pouvez le voir , Bunyan prêt à l’emploi n’est pas très convivial pour les humains, mais la plupart des systèmes de journalisation modernes comprennent le format JSON en mode natif, ce qui signifie qu’il y a peu à faire ici pour alimenter les journaux ailleurs pour le stockage et le traitement. Par défaut, de nombreuses métadonnées sont incluses dans chaque message, telles que l’horodatage, l’ID de processus, le nom d’hôte et le nom de l’application.
Bien sûr, nous, les humains, ne trouvons pas cela très digeste et pour remédier à cela, il existe un outil CLI bunyan
qui prend en JSON via STDIN. Voici le même exemple acheminé par bunyan
:
node example.js | bunyan
Produit la sortie suivante:
INFO: myapp/13372 on pwony-2: hi WARN: myapp/13372 on pwony-2: au revoir (lang=fr)
Le principal avantage ici est que vous n’avez rien à reconfigurer pour l’environnement de développement, tout ce que vous avez à faire est de diriger vers bunyan
. Consultez la page GitHub pour plus de documentation sur l’outil CLI.
JSON
L’une des principales différences entre Bunyan et Winston est que Bunyan fonctionne très bien lorsque vous souhaitez enregistrer des contextes et des objets complexes. Regardons cette ligne et sa sortie de l’exemple ci-dessus:
Vous pouvez voir que {lang: 'fr'}
a été fusionné avec l’objet journal principal et au revoir
est devenu msg
. Imaginez maintenant quelque chose comme ceci:
log.info(user, 'registered');log.info({user: user}, 'registered');
Qui produit:
Ou lorsqu’il est acheminé par bunyan
:
La beauté de cette approche deviendra claire lorsque vous regarderez les enregistreurs enfants.
Enregistreurs enfants
Bunyan a un concept d’enregistreurs enfants, qui permet de spécialiser un enregistreur pour un sous-composant de votre application, c’est-à-dire pour créer un nouvel enregistreur avec des champs liés supplémentaires qui seront inclus dans ses enregistrements de journal. Un enregistreur enfant est créé avec log.child(...)
. Cela est incroyablement pratique si vous souhaitez avoir des enregistreurs de portée pour différents composants de votre système, des demandes ou tout simplement des appels de fonction simples. Regardons un peu de code.
Imaginez que vous souhaitiez effectuer l’ID de demande à travers toutes les lignes de journal pour une demande donnée afin de pouvoir les lier toutes ensemble.
L’enregistreur req.log
gardera toujours son contexte transmis à la fonction log.child()
et le fusionnera avec tous les appels suivants, de sorte que la sortie ressemblerait à ceci :
{"name":"myapp","hostname":"pwony-2","pid":14837,"level":30,"reqId":"XXXX-XX-XXXX","user":"[email protected]","time":"2014-05-26T18:27:43.530Z","v":0}
Sérialiseurs
Deux problèmes surviennent lorsque Bunyan essaie de stringifier des objets entiers :
- Références circulaires. Winston est un peu plus intelligent ici et détecte les références circulaires lorsqu’elles se produisent (cependant la sortie de résultat
$ref=$
n’est pas très utile). - Bruit indésirable. Il me semble que parce que les objets sont de première classe, il est beaucoup plus facile de prendre l’habitude de tout jeter dans le journal.
Pour aider à gérer les deux, Bunyan a un concept de sérialiseur qui sont essentiellement des fonctions de transformation qui vous permettent de réduire les objets couramment passés aux champs qui vous intéressent:
Maintenant, essayer de consigner req
object inclurait simplement les trois champs qui nous intéressent.
Flux
Les flux dans Bunyan sont la même chose que les transporteurs dans Winston – c’est un moyen d’envoyer vos journaux ailleurs à des fins d’affichage et de stockage. Bunyan utilise une interface de flux inscriptible avec des attributs supplémentaires. Une instance d’enregistreur Bunyan a un ou plusieurs flux et est spécifiée avec l’option streams
:
var log = bunyan.createLogger({ name: "foo", streams: });
Plus
Voici quelques choses plus remarquables à explorer dans Bunyan :
- Journal d’exécution fouinant via Prise en charge de Dtrace
- Champs d’enregistrement de journal
Lequel choisir?
Winston et Bunyan sont à la fois des cadres d’exploitation forestière très matures et établis et sont très à égalité en termes de caractéristiques. Winston a beaucoup de soutien communautaire avec divers modules de journalisation. Bunyan facilite l’analyse des journaux dès la sortie de la boîte, mais laisse la consommation à l’utilisateur (généralement le drain syslog fonctionne assez bien ici). Je pense que tout se résume à la préférence et à la facilité d’intégration avec votre pile.
- Qu’en est-il de la prochaine version du nœud ? Découvrez huit nouvelles fonctionnalités passionnantes de Node v0.12 et comment en tirer le meilleur parti, des auteurs eux-mêmes.
- Prêt à développer des API dans Node.js et les connecter à vos données? Vérifiez le nœud.cadre API js LoopBack. Nous avons facilité le démarrage local ou sur votre cloud préféré, avec une simple installation npm.
- Besoin de formation et de certification pour Node ? En savoir plus sur les options privées et ouvertes offertes par StrongLoop.