Winston Logger in NodeJS - Chiiillll Winston, I'm Just Blogging on Logging

image-post maskWinston logger is becoming the defacto way of logging information from NodeJS applications. Mainly because its easy to setup, has all the appenders needed, and can be used in any module you require it in. Ill go over an simple NodeJS application using Winston 'globally' using two of its 13 transports (coming from log4j Java Background I associate transports with log4j Appenders). That transport number of 13 was not a typo. Winston has all sorts of transports. Transports from logging to the Console to using Loggly or Redis to aggregate the generated logs. For today I just plan on demonstrating just the Console and File transports. Now the structure I have for my Winston logger is as follows:

  1. A logger.js file which resides in a root folder named log.
  2. Modify my server.js file to include the above logger.js file
  3. include winston in any JS module that I want to log in.

File - logger.js file

We start first with the logger.js file. I usually put this file in a utils directory off of the root directory(i.e. - /utils/logger.js) This file is just a start and configure file for Winston with the following content:

var winston = require('winston');

var winston = new (winston.Logger)({  
    transports: [
        new (winston.transports.Console)({ level: 'debug' }),
        new (winston.transports.File)({ filename: __dirname + '/../logs/reggie_node.log', level: 'debug' })
    ]
});

winston.info('Chill Winston, the logs are being captured 2 ways - console and file')

module.exports = winston;  

This file is sort of like the configuration file for Winston. It informs Winston what you want to log to . This file can be synonymous with log4j's logging.properties file in Java. The main things to note in the above file is that I only needed to declare the one transport and supply it with a file path for a file that already exists. As for the Console transport this is added by Winston by default. Now if you would like to remove any transport including the Console one you can add this line for example:

    logger.remove(winston.transports.Console);

This will remove the Console logger from the transports Winston is logging to. For your reference, the other transports and documentation can be found here.


File - server.js

Now that we have the configuration file (logger.js) it needs to be required in your NodeJS' application file. I have gotten used to just calling this file server.js, however, I have seen other names too (ie- app.js). Basically, this is the file in NodeJS that tells express to create an http server and listen on some IP and port. So just add this line to the top:

        var logger = require('./utils/Logger')

This just requires the Winston configuration file we created and makes it available to all modules that want to use Winston. Thats all we need to include in the server.js file

Other Modules/JS Files

Since we used the default Winston logger and required it in our server.js file any subsequent logger = require('./utils/Logger') will contain those configurations making it a file by file configuration for all logging. To include Winston in another JS module we can just require it within the file you want to use it in then use the functions available.

For example:

logger = require('./utils/Logger')

logger.info('This is Cool, Right?', document);


Setting Log Levels

As one can see my logger.js file contains a level property when logging to both the console and log file.

    new (winston.transports.Console)({ level: 'debug' }),
    new (winston.transports.File)({ filename: __dirname + '/../logs/reggie_node.log', level: 'debug' })

This is where you would set your logging levels globally. The main reason for setting log levels is because you wouldn't want your production server to log debug statements, which should only happen when your debugging a problem or testing your code.

Conclusion

Doesn't this make logging simple? I have only touched the tip of the iceberg in terms of other use cases for Winston. For example, using the Redis transport to automatically log to a Redis DB which logstash/loggly is using, or maybe use the CouchDB transport to log to. The logging posibilities are great, and learning curve so small. Thats my type of JS library. Simple yet powerful.

Hope this helps.


Up Next

Compiling HTML on the Fly via $compileProvider Directive
Create a Dynamic Modal Directive in Minutes using Angular and UI Bootstrap
NPM/Bower Link - Make Friends with Your Current Dev Node Modules and Bower Components Today