如何使用字符串替换在Winston记录器中处理多个对象?

时间:2019-02-09 16:24:18

标签: javascript node.js logging winston

我使用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)以便以所需的方式记录丢失的内容?

0 个答案:

没有答案