@tars/winston-tars

@tars/winston-tars 提供基于 winston 的 TARS 扩展,以提供符合 TARS 框架的日志格式与输出。

@tars/winston-tars 中提供4种 transport 对象:

  • TarsBase: 提供符合 TARS日志 的基础类
  • TarsRotate: 提供按大小输出的滚动日志
  • TarsDate: 提供按日期输出的日志
  • TafRemote: 输出至远程日志(tars.tarslog)

并提供一种自定义日志级别:

  • TarsConfig: 提供符合TARS框架标准的日志级别与颜色值

以及相关的辅助方法:

  • Formatter: 提供了符合TARS日志格式标准的内容格式化方法
  • DateFormat: 定义了与时间相关日志滚动的处理方法

请注意:如果您的服务在 TARS平台 上运行,应直接使用 @tars/logs 模块,更为便捷

安装

npm install @tars/winston-tars

使用

  1. var winston = require('winston');
  2. // Requiring `@tars/winston-tars` will expose
  3. // transports
  4. // `winston.transport.TarsRotate`
  5. // `winston.transport.TarsDate`
  6. // config
  7. // `winston.config.tars.levels`
  8. // `winston.config.tars.colors`
  9. require('@tars/winston-tars');

日志格式

对于支持 formattertransport 对象,@tars/winston-tars 提供2种方法格式化日志内容:

  • 详细日志: Formatter.Detail([options])
  • 精简日志: Formatter.Simple([options])

options:

  • separ: 日志内容项与项之间的分隔符, 默认值为 |

详细日志:

  1. var winston = require('winston');
  2. var winstonTars = require('@tars/winston-tars');
  3. var logger = new (winston.Logger)({
  4. transports: [
  5. new (winston.transports.Console)({
  6. formatter : winstonTars.Formatter.Detail()
  7. })]
  8. });

输出日志的格式为:日期 时间|PID|日志级别|文件名与行号|内容

其中 文件名与行号 部分可选(详见 Metadata 节)

精简日志

  1. var winston = require('winston');
  2. var winstonTars = require('@tars/winston-tars');
  3. var logger = new (winston.Logger)({
  4. transports: [
  5. new (winston.transports.Console)({
  6. formatter : winstonTars.Formatter.Simple()
  7. })]
  8. });

输出日志的格式为:日期 时间|内容

TarsConfig

winston.config.tars 提供了符合TARS框架标准的日志级别(levels)与颜色(colors

TARS框架的日志级别从低到高(及其对应的颜色)为:

  • info : white
  • debug : cyan
  • warn : yellow
  • error : red
  • none : grey

在使用时需要主动引入:

  1. logger.setLevels(winston.config.tars.levels);
  2. winston.addColors(winston.config.tars.colors);

TarsBase

此模块可单独使用,也可作为其他日志模块的基类。

模块实现了与现有 TARS 日志类似的管理方式:

  • 定时重新打开日志文件,以便获取 fd 的变更。(当用户删除/移动当前文件后,模块会自动创建新文件)
  • 在文件打开的过程中,产生的日志将会写入临时内存队列,等待文件打开完成后一次性写入。(只要不超过队列最大长度,所有日志均会写入文件)
  • 此模块使用文件名 options.filename 作缓存,所以使用相同的 options.filename 多次实例化此模块仅会产生一个单例(共享一个实例)

独立使用

  1. winston.add(winston.transports.TarsBase, options)

options:

  • filename: 输出的文件名
  • interval: 重新打开日志文件的间隔, 默认值为 5000ms
  • bufferSize: 临时队列的最大长度(单位为 条), 默认值为 10000条
  • prefix: 每条日志内容前缀, 默认值为 空
  • formatter: 定义日志内容格式化方法, 默认值为 Formatter.Detail()

作为其他类的基类

需要重写如下2个对象:

  • TarsBase.prototype.name:Transport 模块名
  • TarsBase.prototype._checkfile(callback):当重新打开日志文件时会调用此函数,函数处理完成之后,应显式调用 callback([err])

例如:

  1. var TarsFile = function (options) {
  2. var instance = TarsBase.call(this, options);
  3. //由于父类存在缓存,所以这里需判断父类是否有返回值,如存在(命中缓存)则直接返回无需继续初始化
  4. if (instance) {
  5. return instance;
  6. }
  7. //业务代码
  8. };
  9. util.inherits(TarsFile, TarsBase);
  10. TarsFile.prototype.name = 'tarsFile';
  11. TarsFile.prototype._checkfile = function(cb) {
  12. //业务代码
  13. cb();
  14. };
  15. winston.transports.TarsFile = TarsFile;

TarsRotate

此模块继承于 TarsBase

提供按文件大小输出的滚动日志

当到达设定的最大大小时,会自动向下滚动,并创建一个新的日志文件。

例如:app.log 文件写到最大大小,则会将会执行如下过程:

delete app_n.logapp_n-1.log ===> app_n.log… …app_1.log ===> app_2.logapp.log ===> app_1.logcreate app.log

  1. winston.add(winston.transports.TarsRotate, options)

options:

  • filename: 输出的文件名
  • maxFiles: 最大的文件总数(也就是例子中的 n), 默认值为 10
  • maxSize: 单文件最大大小(单位为 bytes), 默认值为 10M
  • concatStr: 日志文件名中字符间的连接符, 默认值为 _
  • formatter: 定义日志内容格式化方法, 默认值为 Formatter.Detail()

TarsRotate.Master

如果业务脚本通过 Cluster(多进程方式启动的): Worker 则只负写入文件、而移动文件由 Master 完成,以解决多进程资源竞争问题。

当服务进程(Worker)打开日志文件准备写入时会向主进程发送消息,如下:

  1. {
  2. cmd : 'log:rotate',
  3. msg : {
  4. filename : String, //文件名
  5. interval : Number, //多久打开一回文件
  6. maxFiles : Number, //最大文件数
  7. maxSize : Number, //最大单个文件大小
  8. concatStr String //日志文件名中字符间的连接符
  9. }
  10. }

主进程(Master)收到消息后,需透传给 TarsRotate.Master.start 方法,完整的例子如下:

  1. worker.on('message', function(msg) {
  2. if (msg && typeof msg === 'object' && msg.cmd === 'log:rotate') {
  3. var data = msg.msg;
  4. TarsRotate.Master.start(data.filename, data.interval, data.maxFiles, data.maxSize, data.concatStr);
  5. }
  6. });
  7. process.on('exit', function() {
  8. TarsRotate.Master.close();
  9. });

如果服务通过 node-agent (或在TARS平台)运行,则无需配置平台)运行,无需显式调用此模块。只需按照平时的写法 console.[log|info|warn|error] 即可正确的输出滚动日志

DateFormat

定义了与时间相关的日志(TarsDate)滚动的处理方法:

  • 按1天日志:LogByDay([interval, pattern])
    • interval: 1 每隔一天滚动一份日志
    • pattern: %Y%m%d 年月日 (如:20150101)
  • 按1小时日志:LogByHour([interval, pattern])
    • interval: 1 每隔一小时滚动一份日志
    • pattern: %Y%m%d%H 年月日小时 (如:2015010110)
  • 按10分钟日志:LogByMinute([interval, pattern])
    • interval: 10 每隔十分钟滚动一份日志
    • pattern: %Y%m%d%H%M 年月日小时分钟 (如:201501011020)
  • 自定义格式日志:LogByCustom(pattern)
    • pattern: 需要用户自定义

其中 pattern 为日志文件名中的时间格式,可参见 linux strftime

例子

每隔 1天 滚动一份日志

DateFormat.LogByDay或者new DateFormat.LogByDay()

每隔 20分钟 滚动一份日志

new DateFormat.LogByMinute(20)

每隔 20分钟 滚动一份日志,文件名中时间格式为 %Y-%m-%d_%H:%M

new DateFormat.LogByMinute(20, ‘%Y-%m-%d_%H:%M’)

TarsDate

此模块继承于 TarsBase

提供按日期(年、月、日、小时、分)输出的日志

当到达设定的时间间隔时,会自动创建一个新的日志文件

输出的文件名的格式为:filename_[%Y|%m|%d|%H|%M].log,如:app_20141015.log

  1. winston.add(winston.transports.TarsDate, options)

options:

  • filename: 输出的文件名
  • concatStr: 日志文件名中字符间的连接符, 默认值为 _
  • format: 创建新文件的间隔,为 DateFormat 对象, 默认值为 FORMAT.LogByDay
  • formatter: 定义日志内容格式化方法, 默认值为 Formatter.Simple()

为了方便使用 TarsDate.FORMAT = DateFormat

TarsRemote

提供远程日志的功能,会将日志输出至 tars.tarslog.LogObj 服务。

请注意:这里并不是一收到日志就会发送,而是将日志整合在一起定时发送。

  1. var logger = new (winston.Logger)({
  2. transports: [
  3. new (winston.transports.TarsRemote)(options)
  4. ]
  5. });

options:

  • filename: 远端日志文件名(不需要包含日期、路径等附加信息)
  • tarsConfig: tars配置文件路径 或 已配置的 @tars/utils.Config 实例
  • tarsLogServant: 远程日志服务 Servant Obj,默认读取配置文件 tars.application.server.log
  • interval: 发送日志的间隔, 默认值为 500ms
  • format: 创建新文件的间隔,为 DateFormat 对象, 默认值为 FORMAT.LogByDay
  • hasSufix: 日志文件名是否带.log后缀, 默认值为 true
  • hasAppNamePrefix: 是否允许框架在日志文件名上增加业务相关的标识, 默认值为 true
  • concatStr: 日志文件名中用户自定义字符与日期字符间的连接符, 默认值为 _
  • separ: 日志内容项之间的分隔符, 默认值为 |
  • formatter: 定义日志内容格式化方法, 默认值为 Formatter.Detail()

请注意:在 TarsRemoteoptions.format 不能为 FORMAT.LogByCustom

为了方便使用 TarsRemote.FORMAT = DateFormat

如果服务通过 node-agent (或在TARS平台)运行,则无需配置 options.tarsConfig

Metadata

通过指定 Metadata 可输出2种附加数据。

pid

通过 pid 属性,可以指定日志输出条目中 进程id 部分,默认情况下为 process.pid

如:

  1. logger.info('data', {
  2. pid : 123456
  3. });

则输出:

2015-01-01 00:00:01| 123456 |INFO|data

lineno

通过 lineno 属性,可以指定日志输出条目中 文件名与行号 部分,默认值为空(也就是不输出这一节)。

如:

  1. logger.info('data', {
  2. lineno : 'app.js:6'
  3. });

则输出:

2015-01-01 00:00:01|123456|INFO| app.js:6 |data