DEV Community

François
François

Posted on • Originally published at lepape.me on

Native logging for your NPM package

When working with nodejs, if you are coding a NPM package, you might want to keep your package light but with basic logging.

One use-case could be you want your package to have 0 dependency, but allow the package's users to enable logs only when they need it. By default, any console.* in the code will appear in the output.

There is a native nodejs way with the util package, and especially the debuglog function.

Let's have a look to a simple example:

// ./index.js
const log = require('node:util').debuglog('foo')
log('starting package!')
Enter fullscreen mode Exit fullscreen mode

This won't show any output unless you run it with the correct flag:

NODE_DEBUG=foo node index.js.

When debugging, you can add the flag NODE_DEBUG=foo to your NPM scripts (such npm run dev) to see all outputs. Make sure to let your users know, in order for them to see the logs when using/debugging the package.

There is as well a wildcard mode to match all custom logging you could create:

// index.js - node v18.11.0
const util = require('node:util')
const log = {
  network: util.debuglog('foo-network'),
  verbose: util.debuglog('foo-verbose')
  // <-- extend it to improve your logging!
}

log.verbose('starting package!')

new Promise(resolve => setTimeout(resolve, 2000))
  .then(_ => log.network('network call done'))
Enter fullscreen mode Exit fullscreen mode

With the following outputs:

~ ❯ NODE_DEBUG=foo* node index.js
FOO-VERBOSE 23347: starting package!
FOO-NETWORK 23347: network call done

~ ❯ NODE_DEBUG=foo-network node index.js
FOO-NETWORK 23400: network call done
~ ❯
Enter fullscreen mode Exit fullscreen mode

1st time was run with the wildcard on. And the 2nd time, in an imaginary scenario where the user would only need the NETWORK logs.

It is a good practice to namespace the section you pass to debuglog with your package name toallow granular debuging.

Fun fact, if you run a nodejs script with all debug logs activated (NODE_DEBUG=*), you can get more information on your script:

~ ❯ NODE_DEBUG=* node index.js
MODULE 23530: looking for "/Users/francois/index.js" in ["/Users/francois/.node_modules","/Users/francois/.node_libraries","/usr/local/Cellar/node/18.11.0/lib/node"]
MODULE 23530: load "/Users/francois/index.js" for module "."
MODULE 23530: Module._load REQUEST node:util parent: .
MODULE 23530: load built-in module node:util
FOO-VERBOSE 23530: starting package!
TIMER 23530: no 2000 list was found in insert, creating a new one
TIMER 23530: process timer lists 2087
TIMER 23530: timeout callback 2000
TIMER 23530: 2000 list empty
FOO-NETWORK 23530: network call done
Enter fullscreen mode Exit fullscreen mode

ℹ️ Tip 1: if you need more options like adding colors, have a look to the debug package.

ℹ️ Tips 2: util.debuglog has an alias with util.debug! 😎

Top comments (0)