To run NodeJS scripts and apps constantly, we usually use pm2 (some prefer forever). However, some scripts require a brute force restart from time to time as they do not fare better in uninterrupted longer runs. Mostly, the reason is memory leaks of packages you are bound to use but have no control over. There could be other reasons too.
There must surely be other and more elegant ways to do this, but a simple node script that also shows you the log of all previous restarts is what I have used when I needed one.
For this you need to install cron module. Then paste and save the below script in a file, and run it either with pm2 or node.
const { exec } = require('child_process');
const CronJob = require('cron').CronJob;
const restartCommand = "pm2 restart 0";
const listCommand = "pm2 list";
console.log("Starting App Restarter");
const restartApp = function () {
exec(restartCommand, (err, stdout, stderr) => {
if (!err && !stderr) {
console.log(new Date(), `App restarted!!!`);
listApps();
}
else if (err || stderr) {
console.log(new Date(), `Error in executing ${restartCommand}`, err || stderr);
}
});
}
function listApps() {
exec(listCommand, (err, stdout, stderr) => {
// handle err if you like!
console.log(`pm2 list`);
console.log(`${stdout}`);
});
}
new CronJob('0 0 2 * * *', function() {
console.log('2 am Los_Angeles time, restarting the zombieApp');
restartApp();
}, null, true, 'America/Los_Angeles');
- We need
exec
fromchild_process
(child_process comes with node) CronJob
will run our given function at the given time- “pm2 restart 0” is our
restartCommand
. 0 is the id of the process. Change it with the id you have listCommand
is to list the pm2 processes after restart, just for our reference- With
new CronJob
we actually set up a cron job that is supposed to run at 2 am, Los Angeles time each day. It callsrestartApp()
restartApp
executes therestartCommand
, and on success callslistApps()
- Lastly,
listApps
executes thelistCommand
and we get to see the running processes after the restart
3 day logs of the above cronjob will look something like this:
2 am Los_Angeles time, restarting the zombieApp
2019-11-09T10:00:00.945Z 'App restarted!!!'
pm2 list
┌──────────────┬────┬──────┬──────┬────────┬─────────┬────────┬─────┬───────────┬──────────┐
│ App name │ id │ mode │ pid │ status │ restart │ uptime │ cpu │ mem │ watching │
├──────────────┼────┼──────┼──────┼────────┼─────────┼────────┼─────┼───────────┼──────────┤
│ zombieApp │ 0 │ fork │ 5011 │ online │ 146 │ 1s │ 33% │ 37.6 MB │ disabled │
│ someOtherApp │ 1 │ fork │ 5351 │ online │ 0 │ 4M │ 0% │ 19.5 MB │ disabled │
└──────────────┴────┴──────┴──────┴────────┴─────────┴────────┴─────┴───────────┴──────────┘
Use `pm2 show <id|name>` to get more details about an app
2 am Los_Angeles time, restarting the zombieApp
2019-11-10T10:00:00.775Z 'App restarted!!!'
pm2 list
┌──────────────┬────┬──────┬───────┬────────┬─────────┬────────┬─────┬───────────┬──────────┐
│ App name │ id │ mode │ pid │ status │ restart │ uptime │ cpu │ mem │ watching │
├──────────────┼────┼──────┼───────┼────────┼─────────┼────────┼─────┼───────────┼──────────┤
│ zombieApp │ 0 │ fork │ 32700 │ online │ 147 │ 1s │ 0% │ 33.9 MB │ disabled │
│ someOtherApp │ 1 │ fork │ 5351 │ online │ 0 │ 4M │ 0% │ 14.9 MB │ disabled │
└──────────────┴────┴──────┴───────┴────────┴─────────┴────────┴─────┴───────────┴──────────┘
Use `pm2 show <id|name>` to get more details about an app
2 am Los_Angeles time, restarting the zombieApp
2019-11-11T10:00:02.586Z 'App restarted!!!'
pm2 list
┌──────────────┬────┬──────┬──────┬────────┬─────────┬────────┬──────┬───────────┬──────────┐
│ App name │ id │ mode │ pid │ status │ restart │ uptime │ cpu │ mem │ watching │
├──────────────┼────┼──────┼──────┼────────┼─────────┼────────┼──────┼───────────┼──────────┤
│ zombieApp │ 0 │ fork │ 3105 │ online │ 148 │ 0s │ 100% │ 35.1 MB │ disabled │
│ someOtherApp │ 1 │ fork │ 5351 │ online │ 0 │ 4M │ 0% │ 18.8 MB │ disabled │
└──────────────┴────┴──────┴──────┴────────┴─────────┴────────┴──────┴───────────┴──────────┘
Use `pm2 show <id|name>` to get more details about an app
See also
- JavaScript Rollbar: Unknown Unhandled Rejection Error Getting Reason From Event
- Remove Eslint Warnings For Dynamic Imports
- Nodejs Script to Add Rows in CSV File Through Terminal
- How to Run Nightmare JS On Remote Linux Server
- How to Deal With Nightmare JS Zombie Electron Processes
- Trace Redirect Urls NPM Request
- Clean Up MongoDB Of Old Inactive Users And Their Data With Node Js Script