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?
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}]
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With