winston: Passing multiple parameters to logging functions doesn't behave as expected
Please tell us about your environment:
winston
version?-
winston@2
-
winston@3
-
node -v
outputs: v8.11.3- Operating System? macOS
- Language? Flow ES6/7
What is the problem?
With 3.x.x:
const winston = require('winston')
const logger = winston.createLogger({
transports: [new winston.transports.Console()]
})
logger.info('test log', 'with a second parameter')
Outputs:
{"level":"info","message":"test log"}
With 2.x.x:
const winston = require('winston')
const logger = new winston.Logger({
transports: [new winston.transports.Console()]
})
logger.info('test log', 'with a second parameter')
Outputs:
info: test log with a second parameter
What do you expect to happen instead?
It should output:
{"level":"info","message":"test log with a second parameter"}
About this issue
- Original URL
- State: open
- Created 6 years ago
- Reactions: 103
- Comments: 53 (5 by maintainers)
This is a HUGE breaking change for us. If it is intentional, it should be detailed in https://github.com/winstonjs/winston/blob/master/UPGRADE-3.0.md
I understand major versions introduce breaking changes, but my goodness…
It’s disappointing that this issue still has not been resolved, and that my related issue has been locked.
I’m working with many different teams and they all share the frustration of losing previous DX when migrating to v3.
I’ve spent a whole day trying things out.
The above solutions were close but I was missing the colorization and line breaking of extra arguments.
IMO, logging to the Console should be delightful.
Here’s my attempt to make it happen…
v2 setup for comparison
v3 setup
There are many things to handle, some of which
chalk
Current bugs with this solution
info.message
is just a string and the stack tract is in thestack
propertymessage
property as the 1st argument only printsmessage
, discarding any other propertiesinfo.message
(which is usually the value of the 1st argument), resulting in seeing the error message twicePlaying around with the
errors
formatter didn’t help.Positive enhancements
Edit:
We can handle the errors formatting but it’s hacky:
This works for me.
combineMessageAndSplat
that combines message and splat using util.format@indexzero Is this under your radar? I think this is a major breaking change. It actually prevents from moving from 2.x to 3.x as it requires us to change every log entry
I wanted a solution that supports
%d
,%o
etc, but still defaults to including any rest arguments, so thatlogger.info('hello %d %j', 42, {a:3}, 'some', 'more', 'arguments')
is rendered like this:hello 42 {"a": 3} some more arguments
My solution for this ended up using the
splat
symbol but manually invokingutil.format()
directly fromprintf
, which by default includes any rest arguments:If you don’t want
printf
you could of course instead add a transform that simply expands the args intoinfo.message
, and then format the end result the way you like:The problem with using
format.splat()
is that it consumes the matching arguments but seems to throw away the rest. By invokingutil.format()
myself I can override that behaviour.Temporary workaround:
I’ve solved it using something along these lines:
So after some more investigation, I found that you need the splat formatter in order for multiple arguments to be printed. I thought that was just for argument interpolation (i.e. stuff with %s etc. in it), but it seems you need it just to do
logger.info("something", value)
.But this is still being a bit weird for me - I’m getting something that looks like JSON in the output with a key “meta”, even though I am not using a JSON format:
Produces:
Even the example in examples doesn’t produce what it says it will:
https://github.com/winstonjs/winston/blob/master/examples/interpolation.js#L20-L21
i am exploring winston to use in my project, now wondering is it worth taking the risk as this issue is open for more than 2 years. for me this seems like a basic function for any logging framework
When I try to log with arguments I get a weird output
var s = "Hello" log.info("asdasda", s)
Getting the output
{"0":"H","1":"e","2":"l","3":"l","4":"o","service":"XXXX","level":"info","message":"asdasda","timestamp":"2019-04-15 13:58:51"}
I used the normal quick start code
Also waiting for proper way to emulate
console.log(...args)
in winston…Really upsetting that they decided to make a breaking change this large and STILL have not mentioned it in the migration guide or the documentation.
Regardless I wanted to share my solution which I found quite compact and follows how node js implements console.log using
util.format
At this point I have lost faith in winston project. I cant believe this issue is not embraced at all. I have switched from winston to pino to bunyan and back to winston and to winston 2. Winston is able to provide very important functionalities the other two cannot, however the disability to log multiple parameters and error is downright unacceptable. With pino, you cannot define a stackdriver service context and transform. With bunyan, you cannot transform the logs as well. With winston you cannot log more than 1 parameter. I am having a hard time believing these are all our ‘modern’ logger options in 2022.
To leave my bits I have put together the following winston configuration to accommodate both errors and multiple parameters in the logs. Thanks to BananaAcid’s reply above
it works for me using
info[Symbol.for('splat')]
Same issue, any update regarding this one? I love Winston, but it drives me crazy when I cannot print all arguments passed to the logger, which I can do with
console.log()
.@indexzero Was wondering if you were still planning to address this at some point?
Thanks to who posted the suggestions above. Damn I’ve thrown away one day just to integrate Winston 3 on my project 😕
Mine is a variation of @alexilyaev great suggestions:
for logs like:
It outputs like this - which is good for all my scenarios:
Hi there, huge Bumper and show stopper, trying to migrate to the 3.X, probably will keep the 2.x for a while.
A bit disappointed 😦
Related to:
https://github.com/winstonjs/winston/issues/1377
There’s just too many things that don’t work the same.
I had to conform to console.* methods, orientating on all above, and …
But: The file output should show object details.
So I ended up with:
I still don’t understand how to output multiple values in Winston.
I just wanted to replace
console.log('Hello', var1, '!')
withlogger.log('Hello', var1, '!')
.To be honest, trying to use Winston always lead to a lot of time wasted and surprising problems with logging.
I want to share my winston setup:
Here is a common workaround to allow for multiple parameters: https://github.com/rooseveltframework/roosevelt/blob/master/lib/tools/logger.js#L29
Meanwhile, I workaround this issue with the following code: Please note that I didn’t spend so much time on it so please test it carefully.
Well, patching Winston yourself as described in this thread is a viable solution. It is disappointing that something so major has to be fixed this way, but the framework is extensible enough to fix this way without forking, so there’s that.
I would like to chime in and request this feature to be added to the core Winston. Currently, I’m using the custom formatter with
splat
to achieve this functionality, which honestly feels very hacky. It would be nice to have functionality that matchesconsole.log
Hey I’m starting with Winston, never used v2, so I’m on v3.2.1
I was trying to simply do:
And hoping the string interpolation works; but nope.
When I was expecting
This issue is the same thing somehow? Or I’m forced to use the
logger.log('info', .....)
function instead?Edit
Event trying this doesn’t work.
output:
This is what worked for me:
which results in:
2019-07-04T21:30:08.455Z [myLabel] info: foo "bar" 1 [2,3] true {"name":"John"}
Basically
format.combine
sets a pipeline for aninfo
object. For each format function,transform
is called and the final log message should be written toinfo[Symbol.for('message')]
hope this helps