What is why-is-node-running?
The why-is-node-running package is a Node.js module that helps developers diagnose why a Node.js process hasn't exited on its own. It provides insights into what operations are keeping the event loop busy, such as open handles, active timers, and other system tasks that may prevent the process from exiting.
What are why-is-node-running's main functionalities?
Logging active handles
This feature allows you to log all active handles that are currently preventing Node.js from exiting. It's useful for identifying potential sources of memory leaks or unintended behavior.
const log = require('why-is-node-running');
// somewhere in your long-running program
log(); // logs out active handles that are keeping node running
Logging with a delay
This feature is similar to the previous one, but it allows you to set a delay before logging the active handles. This can be useful when you want to give your application some time to settle before checking what is still running.
const log = require('why-is-node-running');
setTimeout(function () {
log(); // logs out active handles after a delay
}, 10000);
Other packages similar to why-is-node-running
wtfnode
WTFNode is similar to why-is-node-running in that it helps to diagnose what is keeping a Node.js process running. It provides detailed output about timers, sockets, and other resources. It differs in its output format and the level of detail provided.
node-report
Node-report is an npm package that provides a diagnostic report on demand or when certain events occur. It's more comprehensive than why-is-node-running, offering information about the system, resource usage, and JavaScript stack trace, but it's not as focused on the reasons why a Node.js process is still running.
why-is-node-running
Node.js is running but you don't know why? why-is-node-running
is here to help you.
Installation
If you want to use why-is-node-running
in your code, you can install it as a local dependency of your project. If you want to use it as a CLI, you can install it globally, or use npx
to run it without installing it.
As a local dependency
Node.js 20.11 and above (ECMAScript modules):
npm install --save-dev why-is-node-running
Node.js 8 or higher (CommonJS):
npm install --save-dev why-is-node-running@v2.x
As a global package
npm install --global why-is-node-running
why-is-node-running /path/to/some/file.js
Alternatively if you do not want to install the package globally, you can run it with npx
:
npx why-is-node-running /path/to/some/file.js
Usage (as a dependency)
import whyIsNodeRunning from 'why-is-node-running'
import { createServer } from 'node:net'
function startServer () {
const server = createServer()
setInterval(() => {}, 1000)
server.listen(0)
}
startServer()
startServer()
setImmediate(() => whyIsNodeRunning())
Save the file as example.js
, then execute:
node ./example.js
Here's the output:
There are 4 handle(s) keeping the process running
# Timeout
example.js:6 - setInterval(() => {}, 1000)
example.js:10 - startServer()
# TCPSERVERWRAP
example.js:7 - server.listen(0)
example.js:10 - startServer()
# Timeout
example.js:6 - setInterval(() => {}, 1000)
example.js:11 - startServer()
# TCPSERVERWRAP
example.js:7 - server.listen(0)
example.js:11 - startServer()
Usage (as a CLI)
You can run why-is-node-running
as a standalone if you don't want to include it inside your code. Sending SIGUSR1
/SIGINFO
signal to the process will produce the log. (Ctrl + T
on macOS and BSD systems)
why-is-node-running /path/to/some/file.js
probing module /path/to/some/file.js
kill -SIGUSR1 31115 for logging
To trigger the log:
kill -SIGUSR1 31115
Usage (with Node.js' --import
option)
You can also use Node's --import
option to preload why-is-node-running
:
node --import why-is-node-running/include /path/to/some/file.js
The steps are otherwise the same as the above CLI section
License
MIT