【问题标题】:Winston / Morgan logging avoiding duplicate entriesWinston / Morgan 记录避免重复条目
【发布时间】:2019-11-16 08:19:07
【问题描述】:

我刚刚实现了 Winston Logging,它按预期工作,但我遇到了一些我无法找到答案的问题。

据我所知,winston 的工作方式,设置的日志级别和低于优先级的任何内容,比如出错时它还将包括信息日志等。有没有办法创建一个特定的日志级别让称它为 HTTP 或 db,我只记录 http 或 db 事件,它们不会出现在组合文件或控制台中?

【问题讨论】:

    标签: node.js winston morgan


    【解决方案1】:

    我可以用一个参数来初始化一个winston,在你的例子中是文件名。我使用类似的设置来记录单独的 cron 任务(我使用 type 参数而不是 filename,它用作日志中的前缀,因此我可以在一个日志文件中识别多个 cron 任务中的问题)。我希望你熟悉 ES6 语法。

    utils/winston.js

    const { createLogger, transports } = require('winston');
    
    const infoLogger = filename => createLogger({
        transports: [
            new transports.File({
                filename: 'info-' + filename,
                level: 'info'
            }),
            new transports.Console(),
        ],
            exitOnError: false
        });
    
    const errorLogger = filename => createLogger({
        transports: [
            new transports.File({
                filename: 'error-' + filename,
                level: 'error'
            }),
            new transports.Console(),
        ],
            exitOnError: false
        });
    
    export default filename => ({
        errorLogger: errorLogger(filename).error,
        infoLogger: infoLogger(filename).info
    });
    

    因此,在您的代码中,您可以从 utils 导入自定义 winston 设置并使用文件名对其进行初始化。注意,我基本上只导出winstonerrorLogger(filename).error的错误函数,你可以修改成你可以接受的方式

    main.js

    import logger from './utils/winston';
    const { errorLogger, infoLogger } = logger('http.log');
    errorLogger('some http fail'); // destination file => error-http.log
    infoLogger('some http info'); // destination file => info-http.log
    

    【讨论】:

    • 这就是我目前所拥有的,但如果我说错误,它还会将错误以下的任何内容记录到该文件中,其中包括信息等。我正在尝试创建一个除了我的数据库之外不记录任何内容的文件查询的
    • @MisterniceGuy 我认为我们彼此不了解,我做了一些更改以使其更清晰
    • 是的,新代码使您的方法更加清晰,最终您创建了 2 个不同的记录器实例。这可能有效,但不确定这是最好的方法
    • @MisterniceGuy 是的,它有点奇怪,也许你可以尝试另一个记录器包,因为在我看来,温斯顿的错误记录方式是一种技术标准,因此它可能是最佳方式。如果您发现有趣的事情,请告诉我
    【解决方案2】:

    更好的解决方案是使用具有格式功能的单个记录器作为“级别过滤器”来指定哪些传输记录哪个特定级别。这是解决方案(注意,levelFilter 可以很容易地扩展为采用一系列可接受的级别)。

    关键的见解是,如果没有从格式化程序链返回 info 对象,则不会记录任何内容。

    const { createLogger, format, transports } = require('winston');
    
    const levelFilter = (level) =>
      format((info, opts) => {
         if (info.level != level) { return false; }
          return info;
      })();
    
    const logger = createLogger({
      transports: [
        new transports.Console({
            format: format.combine(
              levelFilter("info"),
              format.json()
            )
        }),
        new transports.File({
            filename: "test.log",
            format: format.combine(
              levelFilter("error"),
              format.json()
            )
        }),
      ]
    });
    
    // ONLY is logged to test.log
    logger.log({
      level: 'error',
      message: 'abcd'
    });
    
    // ONLY is logged to console
    logger.log({
      level: 'info',
      message: '1234'
    });
    

    【讨论】:

    • 是的,但是@MisterniceGuy 也想为特定目的使用单独的日志文件,这就是为什么多个记录器,但也许有一种方法可以动态更改文件名属性
    • 在我的示例中,我有一个控制台传输和一个文件传输,但是您可以轻松地使用两种文件传输,一种记录错误级别的消息,另一种记录信息级别的消息。不过,仍然可以使用单个记录器。
    猜你喜欢
    • 2015-03-10
    • 2019-06-12
    • 1970-01-01
    • 2015-09-26
    • 2012-08-24
    • 1970-01-01
    • 2015-09-17
    • 2019-11-12
    相关资源
    最近更新 更多