How to make `winston` logging library work like `console.log`?

北城以北 提交于 2021-01-02 06:59:26

问题


The winston library is great for transports and flexibility. I'd like to use it to allow configuring levels and redirecting to files, but would like to reproduce console.log behavior for formatting, and having trouble.

Here's what I have so far:

const log = winston.createLogger({
  level: 'debug',
  format: format.combine(
    format.timestamp({format: 'YYYY-MM-DD HH:mm:ss.SSS'}),
    format.splat(),
    format.colorize(),
    format.printf(({level, message, label, timestamp}) => `${timestamp} ${label || '-'} ${level}: ${message}`),
  ),
  transports: [
    new winston.transports.Stream({
      stream: process.stderr,
      level: 'debug',
    })
  ],
});

log.info("Hello, %s", "Bob");   // Works: outputs "Hello, Bob"

But this don't work:

log.info("Hello", "Bob");
log.info("Hello", 123, {someObj: 1});

I'd like all extraneous objects after those taken up by splat() to get added on, space-separated, and converted to string preferably using util.inspect().


回答1:


Answering my own question. The issue is with format.splat -- pure util.format offers a simpler and more expected behavior. Replacing format.splat with this utilFormatter addresses the problem:

const util = require('util');

function transform(info, opts) {
  const args = info[Symbol.for('splat')];
  if (args) { info.message = util.format(info.message, ...args); }
  return info;
}

function utilFormatter() { return {transform}; }

The example from my question then looks like so:

const log = winston.createLogger({
  level: 'debug',
  format: format.combine(
    format.timestamp({format: 'YYYY-MM-DD HH:mm:ss.SSS'}),
    utilFormatter(),     // <-- this is what changed
    format.colorize(),
    format.printf(({level, message, label, timestamp}) => `${timestamp} ${label || '-'} ${level}: ${message}`),
  ),
  transports: [
    new winston.transports.Stream({
      stream: process.stderr,
      level: 'debug',
    })
  ],
});

log.info("Hello, %s", "Bob");          // Works: outputs "Hello, Bob"
log.info("Hello", "Bob");              // Works: outputs "Hello Bob"
log.info("Hello", 123, {someObj: 1});  // Works: outputs "Hello 123 { someObj: 1} "



回答2:


I had a similar problem, and after much trial and error i think i have a solution that you might be interested in. As i mentioned in my last update, we ended up building our own logger. well, over the weekend i published this logger to npm, and you're welcome to check it out.

It should have more or less identical output to console.log. If you notice any inconsistencies, please let me know.

Also it also has multiple transports, and you can even pass custom ones, and you can even "wrap" the console functions to quickly integrate into your project.

example code:

const {createLogger,wrapConsole,unwrapConsole} = require('@r3wt/log');
const log = createLogger({log_level:'info',transports:['console','file']});
wrapConsole(log);//wraps the console globally with the log instance, making integration into large existing project less painful

// NOTE: only the following 4 functions are wrapped. 
console.log('hi!');
console.warn('warning');
console.error('error');
console.info('info');

unwrapConsole();//unwrap console globally

You can find the library here as well as more code examples and basic documentation if you're interested, and PR's with features and fixes are welcomed and encouraged. code is MIT so you are free to fork and create your own version :-)

Best of luck, and i hope this helps.




回答3:


I did this workaround, but I'm finally not using winston :

const wrapper = (original: any) => {
    return (...args: any[]): any => original(args.map((a) => `${a}`).join(' '))
}

logger.error = wrapper(logger.error)
logger.warn = wrapper(logger.warn)
logger.info = wrapper(logger.info)

By the way, logger is an instance of winston.Logger



来源:https://stackoverflow.com/questions/55387738/how-to-make-winston-logging-library-work-like-console-log

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!