I'm looking into using winston in a project. From looking at the docs, I see that I first create a logger, and then I can require winston in other modules and the logger will be already configured. I'm new to NodeJS, and I'm trying to figure out how createLogger can store information that is stored and then available whenever winston in included. I don't see where winston could be storing an instance globally.
I'm pretty sure winston has containers for this. With containers you can configure a logger with it and add it to a container for later use. I believe the documentation in the REAME for containers is for [email protected], but I managed to get them working with the latest [email protected].
index.js
//
// `logger` is the default container in winston, but you can also create your
// own containers.
//
const { format, loggers, transports } = require('winston')
//
// The `add` method takes a string as a unique id we can later use to retrieve
// the logger we configured. As a second argument it takes an object to
// configure your logger the same way we do with the `createLogger` function.
//
loggers.add('my-logger', {
transports: [
new transports.Console()
]
})
require('./file1') // Log something in a file.
require('./file2') // Log something in a nother file.
file1.js
// Get the default container from winston.
const { loggers } = require('winston')
// Get the logger we configured with the id from the container.
const logger = loggers.get('my-logger')
// Now we can use the logger we got from the container.
logger.info('Logging something in file1.js')
file2.js
// Do the same for file2.js
const { loggers } = require('winston')
const logger = loggers.get('my-logger')
logger.info('Logging another thing in file2.js')
result:
{"message":"Logging something in file1.js","level":"info"}
{"message":"Logging another thing in file2.js","level":"info"}
Hope this helps.
Thank you for this. I was able to get it working, but did it with the default logger. But my question was really about how does winston do this? Where does winston store information when it is configured in index.js so that those settings are available in the other files when those files only requires winston? I looked through the code and was unable to figure out how this works. Thank you for taking the time to answer. I'll be updating my code based on your suggestion.
If you want to reconfiure your logger you can get your logger via the requre('winston').loggers.get('my-logger'); function. And if you want to reconfigure the transports you can do this by removing and adding a reconfigured transport. The example for removing a transport is show here. Adding a transport could be done by logger.add(new Transport(opts));.
Hope this helps.
Thanks again for taking time to answer. My question is really about how does winston persist the configuration I make to a logger. For example, the default logger. I can configure it to include other transports. Then later, I can require only the winston package, and it still knows the transports from the first time when I configured it. Is winston using globals? How does it persist this information between requires of the winston package?
The configuration is stored in memory in each Logger and Transporter instance, it is currently not possible to configure winston with pure data (seet #1105 and #1218). You can however create a module with a wrapper function which configures a winston logger to your liking. Then your packages can require your created module with the wrapper function.
As @3cooper says to be new to NodeJS, I suppose he is new to Javascript modules. If I understand his question well, it is not related to winston, but to module management in NodeJS (would have been better asked on StackOverflow).
So, to quickly answer, when you write a file in NodeJS, this file becomes a module. You can have global variables in this module, at least global to the module (readable only by the module). Each time you require (or import) the same module, you will get the same “instance” of the module, which can access the same instances of the variables (and may export them). So you can share those variables across all files where you require the module.
Your answer makes since to me, but I was unable to find where in the source
code of Winston it created these global values that would be shared amongst
the various instances of winston.
On Tue, May 15, 2018 at 9:11 AM, Stéphane Veyret notifications@github.com
wrote:
As @3cooper https://github.com/3cooper says to be new to NodeJS, I
suppose he is new to Javascript modules. If I understand his question well,
it is not related to winston, but to module management in NodeJS (would
have been better asked on StackOverflow).
So, to quickly answer, when you write a file in NodeJS, this file becomes
a module. You can have global variables in this module, at least global to
the module (readable only by the module). Each time you require (or import)
the same module, you will get the same “instance” of the module, which can
access the same instances of the variables (and may export them). So you
can share those variables across all files where you require the module.—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
https://github.com/winstonjs/winston/issues/1275#issuecomment-389161117,
or mute the thread
https://github.com/notifications/unsubscribe-auth/ABiqZxF1P6sq3n_B0LbjSvJwmpt4i9zaks5tytQfgaJpZM4TZTM9
.
This is this line: https://github.com/winstonjs/winston/blob/master/lib/winston.js#L17
It makes the constant winston object to be the exported one. The default logger is instanciated in the file and used when you call methods directly on exported object. This is done at https://github.com/winstonjs/winston/blob/master/lib/winston.js#L101
As a side note, one can be _reasonably_ certain that a node module is a singleton (ie, that the second time it is required, the same instance of the module will be retrieved), but it's not guaranteed. In most regular cases it will be true, though.
I just finished migrating from v2 to v3 and at first I was also confused as how to handle the lack of a global configuration as well, but then it dawned on me... just export it from a file.
// logger.js
const winston = require('winston');
module.exports = winston.createLogger({...});
// any_file.js
const logger = require('./logger');
logger.warn('tada!');
// any_other_file.js
const logger = require('./logger');
logger.error('tada!');
Hope this helps others running into this ticket.
@EvHaus you can also use the containers, especially the predefined one winston.loggers. See https://github.com/winstonjs/winston#working-with-multiple-loggers-in-winston
Has anyone used winston with an IOC container (e.g. inversify). Seems would be easier to mock during testing.
Most helpful comment
I just finished migrating from v2 to v3 and at first I was also confused as how to handle the lack of a global configuration as well, but then it dawned on me... just export it from a file.
Hope this helps others running into this ticket.