Winston 的多个日志文件?

Posted

技术标签:

【中文标题】Winston 的多个日志文件?【英文标题】:Multiple log files with Winston? 【发布时间】:2012-04-20 05:07:32 【问题描述】:

我们想使用 Winston 来登录 Node.js。但是,我们无法弄清楚如何拥有两个日志文件:一个仅用于错误,另一个用于其他所有文件。

但是,以天真的方式这样做是行不通的:添加多个 winston.transports.File 传输会出错。

Others have run into this problem, with vague hints of a solution, but no real answer.

有什么想法吗?

【问题讨论】:

【参考方案1】:

很遗憾,pesho 提到的补丁似乎还没有包含在正式版中(参见pull request #149@stephenbeeson 的评论)。

所以,我改用了一种解决方法。当 winston 比较名称属性时,您可以通过自己定义名称来欺骗它:

winston = require 'winston'

logger = new winston.Logger
  transports: [
    new winston.transports.File
      name: 'file#debug'
      level: 'debug'
      filename: '/tmp/debug.log'
    new winston.transports.File
      name: 'file#error'
      level: 'error'
      filename: '/tmp/error.log'
  ]
logger.error 'error' # both logs
logger.debug 'debug' # on debug log

也许不优雅,但至少它有效。

【讨论】:

'FileTransportOptions' 类型中不存在 name'。发生此错误。【参考方案2】:

与此同时,您可以使用相同的接口实现一个基本的包装器

var winston = require('winston');
var configs = require('./env.js');

var debug = new winston.Logger(
  levels: 
    debug: 0
  ,
  transports: [
    new (winston.transports.File)( filename: configs.PATH_TO_LOG, level: 'debug'),
    new (winston.transports.Console)(level: 'debug')
  ]
);

var info = new winston.Logger(
  levels: 
    info: 1
  ,
  transports: [
    new (winston.transports.File)( filename: configs.PATH_TO_LOG, level: 'info'),
    new (winston.transports.Console)(level: 'info')
  ]
);

var warn = new winston.Logger(
  levels: 
    warn: 2
  ,
  transports: [
    new (winston.transports.File)( filename: configs.PATH_TO_LOG, level: 'warn'),
    new (winston.transports.Console)(level: 'warn')
  ]
);

var error = new winston.Logger(
  levels: 
    error: 3
  ,
  transports: [
    new (winston.transports.File)( filename: configs.PATH_TO_LOG, level: 'error'),
    new (winston.transports.Console)(level: 'error')
  ]
);

var exports = 
  debug: function(msg)
    debug.debug(msg);
  ,
  info: function(msg)
    info.info(msg);
  ,
  warn: function(msg)
    warn.warn(msg);
  ,
  error: function(msg)
    error.error(msg);
  ,
  log: function(level,msg)
    var lvl = exports[level];
    lvl(msg);
  
;

module.exports = exports;

这将涵盖基本的 winston API。可以扩展元数据等...

【讨论】:

【参考方案3】:

我刚刚发送了一个拉取请求,允许在一个记录器中使用多个文件传输。 https://github.com/flatiron/winston/pull/149

它已经合并到 flatiron/winston。

您也可以使用我的分叉回购: https://github.com/pdobrev/winston

【讨论】:

【参考方案4】:

你只需要给运输一个自定义的name 属性,这样你就不会发生冲突:

const logger = new (winston.Logger)(
  transports: [
    new (winston.transports.Console)(),
    new (winston.transports.File)( name: 'text', filename: logFile, json: false ),
    new (winston.transports.File)( name: 'json', filename: logFileJson )
  ]
);

您可以在文档中阅读有关多种传输的更多信息:https://github.com/winstonjs/winston#multiple-transports-of-the-same-type

【讨论】:

我试过这个,但消息不断被写入两者,我不知道如何指定何时写入哪个。我最终只是制作了一个单独的记录器来在需要时针对该单独的文件。【参考方案5】:

Winston 现已正式支持此功能,并在 README here 中进行了说明

代码示例:

const logger = winston.createLogger(
  level: 'info',
  format: winston.format.json(),
  defaultMeta:  service: 'user-service' ,
  transports: [
    //
    // - Write to all logs with level `info` and below to `combined.log` 
    // - Write all logs error (and below) to `error.log`.
    //
    new winston.transports.File( filename: 'error.log', level: 'error' ),
    new winston.transports.File( filename: 'combined.log' )
  ]
);

//
// If we're not in production then log to the `console` with the format:
// `$info.level: $info.message JSON.stringify( ...rest ) `
// 
if (process.env.NODE_ENV !== 'production') 
  logger.add(new winston.transports.Console(
    format: winston.format.simple()
  ));

【讨论】:

以上是关于Winston 的多个日志文件?的主要内容,如果未能解决你的问题,请参考以下文章

如何将 Winston 限制为每个日志文件只有 1 个文件描述符

NodeJS winston 日志文件不会因大小限制而改变

除第一天外,如何使用 Winston 每天轮换日志

温斯顿日志到文件不起作用

如何在 Winston/Node.js 中设置日志级别

Winston:尝试在没有传输的情况下写入日志