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!')
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'))
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
~ ❯
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
ℹ️ Tip 1: if you need more options like adding colors, have a look to the debug package.
ℹ️ Tips 2:
util.debuglog
has an alias withutil.debug
! 😎
Top comments (0)