5
\$\begingroup\$

In my Node.js applications, I often find it helpful to have an application log so that should something go wrong in production, I can have more information than I get from a crash stack trace to track down problems.

To facilitate this, I use a global instance of Winston which is set up as one of the first things in my code:

var winston = require('winston');

global.applog = new (winston.Logger)({
  transports: [
    new (winston.transports.Console)({
      timestamp: true,
      level: 'debug'
    })
  ]
});

I then call applog.debug(), applog.info(), applog.warn(), and applog.error() as appropriate throughout my code. Even if I am in a class included from the main application, I will often send debug messages.

For my purposes, this works great. I get the information I need to keep things running smoothly, and handle unexpected behaviors. However:

  • This reduces the reuse of any lib code as it cannot stand on its own without having a reference to applog.
  • It doesn't feel like a best practice to have global references used inside modular object-oriented code.
  • I don't think I would ever use a log utility that didn't have the standard methods (debug, info, warn, error), but if I did switch away from Winston it's possible that all my code would need to be updated.

Is there a more appropriate pattern I should be following for logging?

\$\endgroup\$
1
\$\begingroup\$

Having a log for a production application is an excellent idea. Some quick notes on logging web applications in general:

Application logging should be always be included for security events.

...

Each log entry needs to include sufficient information for the intended subsequent monitoring and analysis. It could be full content data, but is more likely to be an extract or just summary properties. The application logs must record "when, where, who and what" for each event.

With that in mind, winston is generally considered a good choice for Node.js logging. It's dependencies are a little dated, and support is minimal. Another option is Scribe.js (lightweight, but also minimal support).


This reduces the reuse of any lib code as it cannot stand on its own without having a reference to applog.

Not necessarily something bad. What you have is compact and easy to transport. You could consider pulling this snippet into it's own file and then require-ing that file in each JS script as needed.

I'm not aware of anything you can do to overcome this.

It doesn't feel like a best practice to have global references used inside modular object-oriented code.

You're right, global variables/functions in general aren't the best. They can cause issues with naming and referencing in the global scope. There are a few solutions to this, w3 has a section devote to avoiding globals.

If your snippet can be placed inside a class (ES6 only) or an app object, I suggest that.

if I did switch away from Winston it's possible that all my code would need to be updated.

Certainly something to think about. With a "find and replace all" command (using a regex perhaps in your IDE) though, much of the hassle could easily be taken care of.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.