My problem is, if I'm gonna use function 'log' alone, like passing function 'log' to some other object, am I suppose to write object.log = logger.log.bind(logger) instead of object.log = logger.log, or should winston take care of the binding?
const winston = require('winston');
/* Either way of declaring logger instance is not working
let logger = winston.loggers.get('some_name');
logger.configure({
level: 'info',
transports: [
new (winston.transports.File)({filename: './some_log_file.log'})
]
});
*/
let logger = new (winston.Logger)({
level: 'info',
transports: [
new (winston.transports.File)({filename: './some_log_file.log'})
]
})
let log = logger.log;
log('info', 'hello world');
Running the code above will result in the following error
/home/darren/projects/sp/node_modules/winston/lib/winston/logger.js:140
if (this._names.length === 0) {
^
TypeError: Cannot read property 'length' of undefined
at Logger.log (/home/darren/projects/sp/node_modules/winston/lib/winston/logger.js:140:18)
at Object.<anonymous> (/home/darren/projects/sp/testwinston.js:23:1)
at Module._compile (module.js:541:32)
at Object.Module._extensions..js (module.js:550:10)
at Module.load (module.js:458:32)
at tryModuleLoad (module.js:417:12)
at Function.Module._load (module.js:409:3)
at Module.runMain (module.js:575:10)
at run (bootstrap_node.js:352:7)
at startup (bootstrap_node.js:144:9)
However, if we use the default logger, everything works just fine.
// outputs "info: hello world" to the console
const winston = require('winston');
let log = winston.log;
log('info', 'hello world');
@chilts @indexzero @FotoVerite @nanek @npeeples Sorry for my being rude guys, but I really need your help.
I use meteor-react framework, and even the default logger example does not work for me. The error is more-or-less the same:
Uncaught TypeError: Cannot read property 'write' of undefined
It looks that this software has rotten.
With a custom logger:
let log = logger.log;
log('info', 'hello world');
will error as the issue description states, the callee is changing. That is this is different. If you execute from the logger object, it works as expected:
logger.log('info', 'hello world');
I can confirm this is how the library currently behaves. I'm not able to comment on whether this is by design or something the library wants to fix.
@WarShoe Your issue might be different. Please confirm you are passing the logger object, not the log function around when using a custom logger. If the issue persists, I recommend creating a new issue.
Why not pass around the logger and use logger.info('message') logger.error('My error message')? This is just how javascript works. You plucked a function without preserving its context. If you want to pass around the log function rather than the logger you should bind it yourself. I just think it makes more sense to pass around the logger as thats the point
@nanek @jcrugzz Thank you. I should be passing around the logger.
We found a quick fix for this. Simply bind the logger to the log function:
var boundLogger = logger.log.bind(logger);
Then just use the boundLogger in place of logger.log.
The reason for doing it this way is to remain logger agnostic - not all loggers will have methods: info, error, and so-forth. Using just one method, log, keeps it simple.
If this is by design that's fine, but the package should throw a descriptive error.
@jcrugzz has a point in that, "that's how javascript works", however in this particular case I think lots of consumers will give it a try because logger.log seems so redundant.
As in, a common pattern is to have a module to instantiate and configure a winston instance, and looking at the readme it's reasonable to conclude that once your logger is configured you don't need to expose it to the rest of your app.
Most helpful comment
We found a quick fix for this. Simply bind the logger to the log function:
var boundLogger = logger.log.bind(logger);Then just use the boundLogger in place of logger.log.
The reason for doing it this way is to remain logger agnostic - not all loggers will have methods: info, error, and so-forth. Using just one method, log, keeps it simple.