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()
.
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} "
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.
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