[译]Node.js日志库Winston

原文地址:Comparing Winston and Bunyan Node.js Logging

如果你正在编写一些生存周期比较长的应用程序,详细的日志记录对于发现问题和调试代码来说非常重要。没有日志,你无法得知你的应用正在做什么,有没有发生错误,应用已经完成了预期的工作还是在你看不见的地方偷懒。

要求

我们先列出一些要求来确定选用哪个框架:

  1. 每个日志行都应该有一个时间戳。这很好解释——你应该能够从日志中得知每个动作发生的时间。
  2. 日志格式应当很容易被人和机器解读。
  3. 允许多个可配置的目标流。例如,你可能会将跟踪日志写入一个文件,而当有错误发生时,将错误信息写入同一个文件和错误日志文件,并且第一时间使用邮件将错误信息发送出去。

基于这些要求,有两个Node.js的日志库值得一试:

  • Trent Mick开发的Bunyan
  • 作为Flatiron.js的一部分并由nodejitstu赞助的Winston

控制台

在我们开始介绍Winston之前,先让我们回顾一下我们的老朋友控制台。你使用得最多的打印日志的方式可能是console.log()console.error()。这比什么都不做要好,但并不是最好的解决方案。控制台将以上信息分别写入标准输出stdout和标准错误stderr中。

当目标是终端或文件时,控制台函数是同步的(避免丢失提早退出应用程序的信息),而当目标是管道时,它们是异步的(避免长时间阻塞)。

也就是说,在下面的例子中,stdout是非阻塞的,而stderr则是阻塞的:

$ nodescript.js2>error.log | teeinfo.log

这种方式依赖于个人进行配置和管理每一件事情,既耗时又容易出错。你可能想要专注于你的应用程序功能而不是这些琐事。考虑到有持续维护并且开源的日志库,如果你希望将注意力集中在开发功能上,大可不必在这上面消耗精力。

Winston

WinstonNode.js上最流行的日志库之一。它被设计为一个简单通用的日志库,支持多种传输(一种传输实际上就是一种存储设备,例如日志存储在哪里)。Winston中的每一个logger实例在不同的日志级别可以存在多个传输配置。

安装

npm install winston

使用

Winston最基本的使用方法就是导入Winston模块后使用默认实例。

var winston = require('winston');
winston.log('info', 'Hello distributed log files!');
winston.info('Hello again distributed logs');

相当于:

var winston = require('winston');
var logger = new winston.Logger();
logger.log('info', 'Hello distributed log files!');
logger.info('Hello again distributed logs');

上面两个例子都会产生以下输出:

info: Hello distributed log files!
info: Hello again distributed logs

格式化

我个人对默认格式化程序的缺乏细节有点小疑惑。没有时间戳、机器名或进程ID,而且输出格式并不适合机器分析。话虽如此,你可以通过增加一点额外的工作量来得到所有的信息。

winston.info('Hello world!', {timestamp: Date.now(), pid: process.pid});

执行上面语句会得到以下信息更为丰富的输出结果,但仍然不是非常适合机器进行分析。

info: Hello world! timestamp=1402286804314, pid=80481

最后,日志方法提供了相同的字符串插值方法util.format,例如:

winston.log('info', 'test message %d', 123);

Transporters

Winston可以通过构造函数或项目的Github页面上详细介绍的接口来进行配置。大部分配置项都围绕着传输。开箱即用的Winston配备了console对象和基于文件的传输,如果你打开npmjs.org的话会发现,从MongoDB到第三方社区平台,一切你能想到的模块都有。
在我看来最值得关注的transporters之一是Nathan Zadoks开发的winstron-irc,可以用于向团队的IRC频道记录错误日志,我觉得这非常方便。

winston.add(require('winston-irc'), {
  host: 'irc.somewhere.net',
  nick: 'logger',
  pass: 'hunter2',
  channels: {
    '#logs': true,
    'sysadmin': ['warn', 'error']
  }
});

多个记录器

一旦你的应用开始增长,你可能会希望有多个不同配置的记录器,每个记录器负责不同的功能区。Winston有两种方式支持以上做法:通过winston.loggers或者winston.Container的实例。事实上,winston.loggers只是一个预定义的winston.Container实例。

winston.loggers.add('category1', {console: {...}, file: {...}});
winston.loggers.add('category2', {irc: {...}, file: {...}});

既然你的记录器已经配置好了,你可以在任意文件中引入Winston并访问这些预配置的记录器:

var category1 = winston.loggers.get('category1');
category1.info('logging from your IoC container-based logger');

更多

以上是最基本的Winston使用方法,它还有一些其他的功能,其中最值得注意的是:

  • Profiling
  • String interpolation
  • Querying and streaming
  • Handling exeptions

你可能感兴趣的:([译]Node.js日志库Winston)