winston version?_winston@2winston@3 node -v outputs:_ 11.6.0Seems like #1579 did not fully fix the _addDefaultMeta bug. After upgrading to winston 3.2.1 I still get this error in my app at https://github.com/winstonjs/winston/blob/efd7baf65da13edaba7829aa4339757eed4322eb/lib/winston/create-logger.js#L80
Full stack trace:
TypeError: self._addDefaultMeta is not a function
at Object.DerivedLogger.(anonymous function) [as log] (/path/to/project/node_modules/winston/lib/winston/create-logger.js:80:14)
at module.exports.<anonymous> (/path/to/project/node_modules/sequelize-fixtures/lib/writer.js:39:16)
at module.exports.tryCatcher (/path/to/project/node_modules/bluebird/js/release/util.js:16:23)
at module.exports.writeFile (/path/to/project/node_modules/bluebird/js/release/method.js:15:34)
at updateReferences (/path/to/project/services/sample_data/index.js:919:6)
at Object.import (/path/to/project/services/sample_data/index.js:961:13)
That my app does not crash with the above error
Could you please provide reproduction code? Ideally a complete test that fails, e. g. based on https://github.com/winstonjs/winston/blob/master/test/logger.test.js
Yeah, I was going to try to narrow it down and follow up with that, but wanted to raise the issue as fast as possible in case someone could figure it out :)
Seems to boil down to:
const winston = require('winston');
const logger = winston.createLogger({
transports: [
new winston.transports.Console()
]
});
const logHelper = {
log: logger.info
};
logHelper.log('Hello');
Works in 3.1.0, but fails in 3.2.1 with:
TypeError: self._addDefaultMeta is not a function
at Object.DerivedLogger.(anonymous function) [as log] (/Users/andreaslind/work/api/node_modules/winston/lib/winston/create-logger.js:80:14)
It feels like a misuse of the API as it's not really fair game to pick out a method and call it on another object. Still, it used to work, so gray area :)
Thanks for reporting this bug, but yes: the failure is by design. If you would like to create another object with it's own properties that is still a logger, use Object.create (logger, extraProps)
Another way I found that works is to bind:
const logHelper = {
log: logger.info.bind(logger)
};
@indexzero I dont understand how I can create a log helper like wished for here with the sentence you provided?
What @tizmagik did mention, works, but I want to avoid binding stuff
`const winston = require('winston');
const logger = winston.createLogger({
transports: [
new winston.transports.Console()
]
});
const logHelper = {
log: logger.info.bind(logger)
};
module.exports.log = {
custom:logHelper,
inspect:false,
level: process.env.SAILS_LOG_LEVEL || 'debug'
};`
I am trying to configure sails.log in config/log.js using the above code.
But it's not logging out anything.
Can someone please guide on the above problem.
@indexzero @tizmagik @vongohren
So this logger.info.bind(logger) works for me. But I cannot say why.
Can anyone tell me why this is not documented anywhere or why.
Is this bad design by us developers who end up doing bind?
Or @indexzero
Binding somehow solved my issues with maximum call stack. Would love a good explanation on why this works or an actual solution... but thanks!
@ionizer me too, just didnt get the stackoverflow posted earlier. maybe @indexzero can chime in?
@vongohren I think I get it now, though it's a bit hard for me to explain. In some cases where we wrap the logger in an object like so:
const logHelper = {
log: logger.info
};
...the logger.info function is almost like it's scope is being isolated inside the logHelper object because it's not bound.
The exact explanation according to the SO answer is that outside the logHelper object, logHelper.log() fails because logger.info's context is lost outside of the wrapping object. So binding works because it binds the wrapped logger's context in a way that it's also available outside the object.
EDIT: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/bind
I feel my explanation is somewhat correct, but not exactly accurate. So what happens in the MDN example is that the reference to this is lost when a function that refers to this is being called outside of the object.
@ionizer ah ok! Did not now the context inside the object dissapeard
Most helpful comment
Another way I found that works is to bind: