node.js - 如何使用Winston将日志发送到不同的传输方式?

标签 node.js logging winston

我的系统中发生了不同的事件,并且希望将其中一些事件记录到一个文件中,而将其他事件记录到另一个文件中。

例如:

  • “start”、“stop”等服务器事件将转至“server.log”,传输名为“ServerLogger”。
  • 用户事件“登录”、“注销”、“注册”将通过 UsersLogger 放入“users.log”中
  • “已付款”、“已拒绝”等付款事件将通过 PaymentsLogger 保存在“payments.log”中。

在系统中我会像这样运行它:

logger.log(ServerLogger, 'start');
logger.log(UsersLogger, 'login','john');
logger.log(PaymentsLogger, 'paid','100', 'john');

如何让它像这样工作,以便当我想登录到某个特定的记录器时,它会被使用?

我应该像这样将每个记录器注册为新的 winston 实例吗?

const serverLogger = new winston.Logger()
const usersLogger = new winston.Logger()
const paymentsLogger = new winston.Logger()

最佳答案

虽然这可能不是完美的解决方案,但我发现自己处于类似的情况。我有不同的文件,这些文件可能处于事件状态,也可能不处于事件状态,管理应用程序的不同部分。

我的解决方案是基于 winston 制作我的“自己的”记录器。由于每个源代码文件都需要一个记录到不同文件的记录器和一个“通用”文件,因此我制作了一个我调用的“生成器”,而不是直接需要winston:

log.js:

'use strict';

const util = require('util'),
    winston = require('winston'),
    config = require('./config.json');

//If I don't want to log in files and only in console
let testMode = (config.log.mode === 'test');

//"Common" log file
const fileTransport = new (winston.transports.File)({
        timestamp: true,
        name: config.log.all.file,
        filename: config.log.all.file,
        level: config.log.all.level
    }),
//"Common" error log file
    errorTransport = new (winston.transports.File)({
        timestamp: true,
        name: config.log.error.file,
        filename: config.log.error.file,
        level: 'error'
    });

//Logs are also sent in mongoDB, with the same schema as in the files
let mongoTransport = {},
    mongoErrorTransport = {};

if(!testMode) {
    //Add winston.transport.MongoDB
    require('winston-mongodb');

    mongoTransport = new (winston.transports.MongoDB)({
        name: 'all',
        host: config.log.db.host,
        safe: config.log.db.safe,
        collection: 'all',
        level: config.log.all.level,
        db: config.log.db.db
    });
    mongoErrorTransport = new (winston.transports.MongoDB)({
        name: 'error',
        host: config.log.db.host,
        safe: config.log.db.safe,
        collection: 'error',
        level: 'error',
        db: config.log.db.db
    });
}

function getTransports(file) {
    let transports = [];

//Log in the console
    transports.push(new (winston.transports.Console)({
        timestamp: true,
        level: config.log.all.level,
        formatter: (args) => {
            let d = new Date();
            return d.getFullYear() +
                    '/' + d.getMonth(), +
                    '/' + d.getDate(), +
                    ' ' + d.getHours(), +
                    ':' + d.getMinutes(), +
                    ':' + d.getSeconds(), +
                    ':' + d.getMilliseconds(), +
                    ' - ' + file +
                    ' - ' + args.level + 
                    ' -\t' + args.message + 
                    '\t' + util.inspect(args.meta);
        }
    }));

    if(testMode) {
        return transports;
    }

    let name,
        level,
        filename;

    transports.push(fileTransport);
    transports.push(errorTransport);
    transports.push(mongoTransport);
    transports.push(mongoErrorTransport);

//Module specific logs

    if(config.log[file] && config.log[file].file) {
        name = config.log[file].file;
    } else {
        name = file;
    }
    if(config.log[file] && config.log[file].level) {
        level = config.log[file].level;
    } else if(config.log.default && config.log.default.level) {
        level = config.log.default.level;
    } else {
        level = 'info';
    }
    if(config.log[file] && config.log[file].file) {
        filename = config.log[file].file;
    } else if(config.log.default && config.log.default.file) {
        filename = config.log.default.path + file + '.log';
    } else if(config.log.default && config.log.default.path) {
        filename = config.log.default.file;
    } else {
        filename = './log/' + file + '.log';
    }

//Module specific log file

    transports.push(new (winston.transports.File)(
        {
            timestamp: true,
            name: name,
            level: level,
            filename: filename
        }
    ));

//Module specific Mongo collection for logs

    transports.push(new (winston.transports.MongoDB)({
        name: 'mongo' + file,
        host: config.log.db.host,
        safe: config.log.db.safe,
        collection: file,
        level: level,
        db: config.log.db.db
    }));

    return transports;
}

//Generator
module.exports = (file) => {
    let transports = getTransports(file);
    return new (winston.Logger)({
        rewriters: [
            (level, msg, meta) => {
                meta.app = file + '.js';
                return meta;
            }
        ],
        transports: transports
    });
};

被称为:

'use strict';

const Logger = require('./log.js'),
    logger = Logger('myModule');

logger.debug('Hi');
logger.error('Oops');

虽然它远非完美的解决方案,并且可能不适用于您的特定问题,但类似的方法可能比手动创建每个记录器更干净。

关于node.js - 如何使用Winston将日志发送到不同的传输方式?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40125557/

相关文章:

php - 在 PHP MVC 应用程序中在哪里捕获异常?

node.js - winston 记录对象

node.js - 在winston中记录每个请求的请求信息

node.js - Heroku web : npm ERR! 缺少脚本:开始

javascript - Mongoose 查找所有引用的文档

html - 获取 Angular js 中返回的 JSON 对象的值

debugging - 我想在 bluez 上启用调试消息

spring - Spring Cloud Gateway全局异常处理/记录

node.js - 如何在几个模块中使用 Winston?

node.js - Sails.js:模型上的动态表名