我在系统中发生了不同的事件,并希望将其中一些事件记录到一个文件中,将其他事件记录到另一个文件中。
例如:
在系统中我会运行它:
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()
答案 0 :(得分:0)
虽然它可能不是完美的解决方案,但我发现自己处于类似情况。我有不同的文件可能活动也可能不活动,管理应用程序的不同部分。
我的解决方案是让我自己拥有"记录器,基于温斯顿。由于每个源代码文件都需要一个记录器来记录不同的文件,并且需要一个" common"文件,我做了一个"生成器"我打电话而不是直接要求温斯顿:
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');
虽然它远非一个完美的解决方案,并且可能不适用于您的特定问题,但类似的东西可能比手动创建每个记录器更清晰。
答案 1 :(得分:0)
想出了一个稍微不同的解决方案,它可以解决类似但不匹配的问题。我想将作业开始和完成的两条日志消息发送到 cloudwatch,同时在进程运行时做更多的日志记录,以不同的方式处理。 (cloudwatch 环境与我们的监控有关,我们有几百个作业通过 cloudwatch 报告失败)。
因此,当我将日志记录到 cloudwatch 时,我只是添加和删除传输:
function logSomethingForMonitoring(msg){
try{
parentLogger.add(cloudwatch)
parentLogger.info(msg)
} finally {
parentLogger.remove(cloudwatch)
}
}
我怀疑这不是超级性能,所以它可能是正常日志的最佳解决方案,但如果这不是正常日志,它似乎工作正常。还没有真正测试过,因为就像我说的,我只将它用于两条消息。