我使用winston@3.2.0 / winston-daily-rotate-file@3.6.0登录我的node [v11.6]项目并按以下步骤进行设置:
const appRoot = require('app-root-path');
const { createLogger, format, transports } = require('winston');
const { combine, timestamp, printf, colorize, splat, prettyPrint, label } = format;
require('winston-daily-rotate-file');
const logFormat = printf(({ timestamp, label, level, user, filifu, message }) => {
let u = (user === undefined ? '' : user);
let f = (filifu === undefined ? '' : `filifu`);
return `${timestamp} [${label}] [${level}] [${u}] ${f}: ${message}`;
});
const logDir = `${appRoot}/logs`;
const appName = 'my App';
const options = {
file: {
level: 'debug',
filename: `${logDir}/%DATE%.log`,
datePattern: 'YYYYMMDD',
format: combine(
splat(),
label({label: appName}),
timestamp({ format: 'YYYY-MM-DD HH:mm:ss' }),
logFormat
),
prepend: true,
zippedArchive: true,
json: true,
handleExceptions: true
},
console: {
level: 'debug',
format: combine(
splat(),
label({label: appName}),
colorize(),
timestamp({ format: 'YYYY-MM-DD HH:mm:ss' }),
logFormat
),
handleExceptions: true
}
};
const logger = createLogger({
transports: [
new transports.Console(options.console),
new transports.DailyRotateFile(options.file)
],
exitOnError: false
});
我正在使用magic-globals module的修改版本来按当前文件,行和功能扩展日志记录。为了节省编写时间,我在magic-globals.js中添加了以下代码:
Object.defineProperty(global, '__filifu', {
get: function(){
var file = __stack[1].getFileName().split(/[\\\/]/).slice(-1)[0];
var line = __stack[1].getLineNumber();
var func = arguments.callee.caller && arguments.callee.caller.name || '(anonymous)';
return file + ' (' + line + '): ' + func;
}
});
这样,人们就可以写'filifu:__filifu'而不是'file:__file,line:__line,func:__func'。
在控制台中,日志按方面显示,但是在日志文件中,如果存在另一个对象,我会错过“位置”:
// works as aspected:
logger.debug('plain text');
// console: 2019-02-09 16:35:22 [my App] [debug] [] []: plain text
// file: 2019-02-09 16:35:22 [my App] [debug] [] []: plain text
// no problems:
logger.info(`test object without user and filifu %o`, {test: 'test', number: 123});
// console: 2019-02-09 16:35:22 [my App] [info] [] []: test object without user and filifu { test: 'test', number: 123 }
// file: 2019-02-09 16:35:22 [my App] [info] [] []: test object without user and filifu { test: 'test', number: 123 }
// still no problems:
logger.warn(`a log with user and filifu`, {user: 'testuser', filifu: __filifu});
// console: 2019-02-09 16:35:22 [my App] [warn] [testuser] [index.js (12): myFunction]: a log with user and filifu
// file: 2019-02-09 16:35:22 [my App] [warn] [testuser] [index.js (12): myFunction]: a log with user and filifu
// using object substitution pattern fails for log file - it is undefined and set to an empty string by 'logFormat':
logger.warn(`test object with user and filifu %o`, {test: 'test 2', number: 456}, {user: 'testuser', filifu: __filifu});
// console: 2019-02-09 16:35:22 [my App] [warn] [testuser] [index.js (13): myFunction]: test object with user and filifu { test: 'test 2', number: 456 }
// file: 2019-02-09 16:35:22 [my App] [warn] [] []: test object with user and filifu { test: 'test 2', number: 456 }
// same for string ubstitution pattern:
logger.info(`a string: %s`, 'mystring', {user: 'testuser', filifu: __filifu});
// console: 2019-02-09 16:35:22 [my App] [info] [testuser] [index.js (20): myFunction]: a string: mystring
// file: 2019-02-09 16:35:22 [my App] [info] [] []: a string: mystring
我发现可能的解决方法是使用'JSON.stringify'代替'%o',并使用模板文字代替'%s':
logger.warn('test object with user and filifu ' + JSON.stringify({test: 'test 2', number: 456}), {user: 'testuser', filifu: __filifu});
// console: 2019-02-09 16:35:22 [my App] [warn] [testuser] [index.js (41): myFunction]: test object with user and filifu {"test":"test 2","number":456}
// file: 2019-02-09 16:35:22 [my App] [warn] [testuser] [index.js (41): myFunction]: test object with user and filifu {"test":"test 2","number":456}
var myTestString = 'this is my test string';
logger.error(`another string ${myTestString}`, {user: 'testuser', filifu: __filifu});
// console: 2019-02-09 16:35:22 [my App] [error] [testuser] [index.js (22): myFunction]: another string this is my test string
// file: 2019-02-09 16:35:22 [my App] [error] [testuser] [index.js (22): myFunction]: another string this is my test string
但是在我看来,这会导致更多的打字和更少的可读性。
是否可以设置winston(-daily-rotate-file)以便以所需的方式记录丢失的内容?