Winston / Morgan 日志记录避免重复条目
Winston / Morgan logging avoiding duplicate entries
我刚刚实施了 Winston Logging,它按预期工作,但我遇到了一些我找不到答案的问题。
据我所知,winston 的工作方式、设置的日志级别以及使用优先级以下的任何内容,例如错误时它还将包括信息日志等。有没有办法创建特定的日志level 让我们称之为 HTTP 或 db,我只记录 http 或 db 事件,它们不会最终出现在组合文件或控制台中?
我可以用参数初始化 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
});
因此,在您的代码中,您可以从实用程序导入自定义 winston 设置并使用文件名对其进行初始化。注意,我基本上只从 winston errorLogger(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
更好的解决方案是使用具有格式功能的单个记录器作为 "level filter" 来指定哪个传输日志哪个特定级别。这是解决方案(注意,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'
});
我刚刚实施了 Winston Logging,它按预期工作,但我遇到了一些我找不到答案的问题。
据我所知,winston 的工作方式、设置的日志级别以及使用优先级以下的任何内容,例如错误时它还将包括信息日志等。有没有办法创建特定的日志level 让我们称之为 HTTP 或 db,我只记录 http 或 db 事件,它们不会最终出现在组合文件或控制台中?
我可以用参数初始化 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
});
因此,在您的代码中,您可以从实用程序导入自定义 winston 设置并使用文件名对其进行初始化。注意,我基本上只从 winston errorLogger(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
更好的解决方案是使用具有格式功能的单个记录器作为 "level filter" 来指定哪个传输日志哪个特定级别。这是解决方案(注意,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'
});