如何在使用Winstonjs 3.2+时使用splat生成相同的输出?

huangapple go评论81阅读模式
英文:

how to produce the same output with splat using winstonjs 3.2+

问题

我一直在推迟将winstonjs从版本 3.1.0 升级到 3.2.x,因为我无法让它以相同的方式处理额外的元数据。

例如,我在应用程序中有包含字符串和对象形式的元数据的日志消息。
3.1.0 中,这个设置很好地创建了我想要的输出:

const { createLogger, format, transports } = require('winston');
const { combine, timestamp, label, printf, colorize } = format;

const formatStr = printf(info => {
  return `[${info.timestamp}] ${info.level}\t ${info.label} ${info.message} ${JSON.stringify(info.meta)}`
});

let logger = createLogger({
  transports: [new transports.Console({ level: 'info' })],
  format: combine(
    colorize({message: true, level: true}),
    timestamp({format: 'MMM D, YYYY HH:mm'}),
    format.splat(),
    formatStr
  )
});

logger.info('any message',{extra: true});
logger.info('simple', "one", "two",{extra: true});

其中输出如下:

[Jan 3, 2020 14:36] info	 undefined any message {"extra":true}
[Jan 3, 2020 14:36] info	 undefined simple ["one","two",{"extra":true}]

但在 3.2.1 中,我能够获得的最接近我理想的日志格式是:

[Jan 3, 2020 14:31] info	 undefined any message {"extra":true,"timestamp":"Jan 3, 2020 14:31"}
[Jan 3, 2020 14:31] info	 undefined simple {"0":"t","1":"w","2":"o","timestamp":"Jan 3, 2020 14:31","extra":true}

使用以下代码:

const { createLogger, format, transports } = require('winston');
const { combine, timestamp, label, printf, colorize } = format;

// 帮助程序,用于字符串化所有剩余属性
function rest(info) {
  return JSON.stringify(Object.assign({}, info, {
    level: undefined,
    message: undefined,
    splat: undefined,
    label: undefined
  }));
}

const formatStr = printf(info => {
  return `[${info.timestamp}] ${info.level}\t ${info.label} ${info.message} ${rest(info)}`
});

let logger = createLogger({
  transports: [new transports.Console({ level: 'info' })],
  format: combine(
    colorize({message: true, level: true}),
    timestamp({format: 'MMM D, YYYY HH:mm'}),
    format.splat(),
    formatStr
  )
});

logger.info('any message',{extra: true});
logger.info('simple', "one", "two",{extra: true});

随着在 3.2.0 中移除了 meta 数据,https://github.com/winstonjs/winston/blob/master/CHANGELOG.md#new-splat-behavior,我应该如何在我的应用程序中的所有现有日志记录结构中使用这个新特性?

英文:

I've been postponing upgrading winstonjs from 3.1.0 to 3.2.x, because I can't manage to get it to handle the extra meta data the same way.

For example, I have log messages throughout the app that include meta data in strings and object form.
In 3.1.0 this setup works well to create the output I'm looking for:

const { createLogger, format, transports } = require('winston');
const { combine, timestamp, label, printf, colorize } = format;

const formatStr = printf(info => {
  return `[${info.timestamp}] ${info.level}\t ${info.label} ${info.message} ${JSON.stringify(info.meta)}`
});

let logger = createLogger({
  transports: [new transports.Console({ level: 'info' })],
  format: combine(
    colorize({message: true, level: true}),
    timestamp({format: 'MMM D, YYYY HH:mm'}),
    format.splat(),
    formatStr
  )
});

logger.info('any message',{extra: true});
logger.info('simple', "one", "two",{extra: true});

Where the output is like this:

[Jan 3, 2020 14:36] info	 undefined any message {"extra":true}
[Jan 3, 2020 14:36] info	 undefined simple ["one","two",{"extra":true}]

But in 3.2.1 the closest I can get to my ideal log format is:

[Jan 3, 2020 14:31] info	 undefined any message {"extra":true,"timestamp":"Jan 3, 2020 14:31"}
[Jan 3, 2020 14:31] info	 undefined simple {"0":"t","1":"w","2":"o","timestamp":"Jan 3, 2020 14:31","extra":true}

using the following code:

const { createLogger, format, transports } = require('winston');
const { combine, timestamp, label, printf, colorize } = format;

// helper for stringifying all remaining properties
function rest(info) {
  return JSON.stringify(Object.assign({}, info, {
    level: undefined,
    message: undefined,
    splat: undefined,
    label: undefined
  }));
}

const formatStr = printf(info => {
  return `[${info.timestamp}] ${info.level}\t ${info.label} ${info.message} ${rest(info)}`
});

let logger = createLogger({
  transports: [new transports.Console({ level: 'info' })],
  format: combine(
    colorize({message: true, level: true}),
    timestamp({format: 'MMM D, YYYY HH:mm'}),
    format.splat(),
    formatStr
  )
});

logger.info('any message',{extra: true});
logger.info('simple', "one", "two",{extra: true});

With the removal of meta data in 3.2.0, https://github.com/winstonjs/winston/blob/master/CHANGELOG.md#new-splat-behavior, how am I suppose to make use of this with the existing logging structure that I have everywhere in my app?

答案1

得分: 5

我遇到了类似的问题。我正在使用winston 3.2.1

我通过不使用splat格式并从元数据中检索它来找到了解决方案。以下是如何获取你所期望的输出的示例。

const formatMeta = (meta) => {
  // 你可以自己格式化splat
  const splat = meta[Symbol.for('splat')];
  if (splat && splat.length) {
    return splat.length === 1 ? JSON.stringify(splat[0]) : JSON.stringify(splat);
  }
  return '';
};

const customFormat = winston.format.printf(({
  timestamp,
  level,
  message,
  label = '',
  ...meta
}) => `[${timestamp}] ${level}\t ${label} ${message} ${formatMeta(meta)}`);

const logger = createLogger({
  transports: [new transports.Console()],
  format: combine(
    format.colorize(),
    format.timestamp({format: 'MMM D, YYYY HH:mm'}),
    customFormat,
    // 不使用splat格式
  )
});

logger.info('任何消息', { extra: true });
logger.info('简单', "one", "two", { extra: true });

输出:

[Mar 26, 2020 13:03] info    任何消息 {"extra":true}
[Mar 26, 2020 13:03] info    简单 ["one","two",{"extra":true}]
英文:

I've encountered a similar issue. I'm using winston 3.2.1.

I found a solution by not using the splat format and retrieving it from the metadata. Here is an example of how to get the output you're looking for.

const formatMeta = (meta) => {
  // You can format the splat yourself
  const splat = meta[Symbol.for('splat')];
  if (splat && splat.length) {
    return splat.length === 1 ? JSON.stringify(splat[0]) : JSON.stringify(splat);
  }
  return '';
};

const customFormat = winston.format.printf(({
  timestamp,
  level,
  message,
  label = '',
  ...meta
}) => `[${timestamp}] ${level}\t ${label} ${message} ${formatMeta(meta)}`);

const logger = createLogger({
  transports: [new transports.Console()],
  format: combine(
    format.colorize(),
    format.timestamp({format: 'MMM D, YYYY HH:mm'}),
    customFormat,
    // Do not use splat format
  )
});

logger.info('any message', { extra: true });
logger.info('simple', "one", "two", { extra: true });

The output:

[Mar 26, 2020 13:03] info	  any message {"extra":true}
[Mar 26, 2020 13:03] info	  simple ["one","two",{"extra":true}]

huangapple
  • 本文由 发表于 2020年1月3日 21:46:56
  • 转载请务必保留本文链接:https://go.coder-hub.com/59579692.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定