From 2c310084453dd7b1546957e59b1fc7ef964d425b Mon Sep 17 00:00:00 2001 From: Robin Monnier Date: Mon, 5 Mar 2018 22:13:39 +0100 Subject: [PATCH 01/10] feat(bin/pm2): improve usage --- bin/pm2 | 127 +++++++++++++++++++++++++++++--------------------------- 1 file changed, 66 insertions(+), 61 deletions(-) diff --git a/bin/pm2 b/bin/pm2 index 05072f4bc..02fdce445 100755 --- a/bin/pm2 +++ b/bin/pm2 @@ -33,24 +33,29 @@ if (process.argv.indexOf('-v') > -1) { var pm2 = new PM2(); commander.version(pkg.version) - .option('-v --version', 'get version') + .option('-v --version', 'print pm2 version') .option('-s --silent', 'hide all messages', false) + .option('-n --name ', 'set a name for the process in the process list') .option('-m --mini-list', 'display a compacted list without formatting') + .option('--interpreter ', 'set a specific interpreter to use for executing app, default: node') + .option('--interpreter-args ', 'set arguments to pass to the interpreter (alias of --node-args)') + .option('--node-args ', 'space delimited arguments to pass to node') + .option('-o --output ', 'specify log file for stdout') + .option('-e --error ', 'specify log file for stderr') + .option('-l --log [path]', 'specify log file which gathers both stdout and stderr') + .option('--log-type ', 'specify log output style (raw by default, json optional)') + .option('--log-date-format ', 'add custom prefix timestamp to logs') + .option('--disable-logs', 'disable all logs storage') + .option('--env ', 'specify which set of environment variables from ecosystem file must be injected') + .option('-a --update-env', 'force an update of the environment with restart/reload (-a <=> apply)') .option('-f --force', 'force actions') - .option('--disable-logs', 'do not write logs') - .option('-n --name ', 'set a for script') .option('-i --instances ', 'launch [number] instances (for networked app)(load balanced)') .option('--parallel ', 'number of parallel actions (for restart/reload)') - .option('-l --log [path]', 'specify entire log file (error and out are both included)') - .option('-o --output ', 'specify out log file') - .option('-e --error ', 'specify error log file') .option('-p --pid ', 'specify pid file') .option('-k --kill-timeout ', 'delay before sending final SIGKILL signal to process') .option('--listen-timeout ', 'listen timeout on application reload') - .option('--max-memory-restart ', 'specify max memory amount used to autorestart (in octet or use syntax like 100M)') + .option('--max-memory-restart ', 'Restart the app if an amount of memory is exceeded (in bytes)') .option('--restart-delay ', 'specify a delay between restarts (in milliseconds)') - .option('--env ', 'specify environment to get specific env variables (for JSON declaration)') - .option('--log-type ', 'specify log output style (raw by default, json optional)') .option('-x --execute-command', 'execute a program using fork system') .option('--max-restarts [count]', 'only restart the script COUNT times') .option('-u --user ', 'define user when generating startup script') @@ -62,19 +67,14 @@ commander.version(pkg.version) .option('--service-name ', 'define service name when generating startup script') .option('-c --cron ', 'restart a running process based on a cron pattern') .option('-w --write', 'write configuration in local folder') - .option('--interpreter ', 'the interpreter pm2 should use for executing app (bash, python...)') - .option('--interpreter-args ', 'interpret options (alias of --node-args)') - .option('--log-date-format ', 'add custom prefix timestamp to logs') .option('--no-daemon', 'run pm2 daemon in the foreground if it doesn\'t exist already') - .option('-a --update-env', 'update environment on restart/reload (-a <=> apply)') .option('--source-map-support', 'force source map support') .option('--only ', 'with json declaration, allow to only act on one application') .option('--disable-source-map-support', 'force source map support') .option('--wait-ready', 'ask pm2 to wait for ready event from your app') .option('--merge-logs', 'merge logs from different instances but keep error and out separated') .option('--watch [paths]', 'watch application folder for changes', function(v, m) { m.push(v); return m;}, []) - .option('--ignore-watch ', 'folder/files to be ignored watching, should be a specific name or regex - e.g. --ignore-watch="test node_modules \"some scripts\""') - .option('--node-args ', 'space delimited arguments to pass to node in cluster mode - e.g. --node-args="--debug=7001 --trace-deprecation"') + .option('--ignore-watch ', 'List of paths to ignore (name or regex)') .option('--no-color', 'skip colors') .option('--no-vizion', 'start an app without vizion feature (versioning control)') .option('--no-autorestart', 'start an app without automatic restart') @@ -85,43 +85,46 @@ commander.version(pkg.version) .option('--disable-trace', 'disable transaction tracing with km') .option('--attach', 'attach logging after your start/restart/stop/reload') .option('--sort ', 'sort process according to field\'s name') - .option('--v8', 'enable v8 data collecting') - .option('--event-loop-inspector', 'enable event-loop-inspector dump in pmx') - .option('--deep-monitoring', 'enable all monitoring tools (equivalent to --v8 --event-loop-inspector --trace)') .usage('[cmd] app'); -commander.on('--help', function() { - console.log(' Basic Examples:'); - console.log(''); - console.log(' Start an app using all CPUs available + set a name :'); - console.log(' $ pm2 start app.js -i 0 --name "api"'); - console.log(''); - console.log(' Restart the previous app launched, by name :'); - console.log(' $ pm2 restart api'); - console.log(''); - console.log(' Stop the app :'); - console.log(' $ pm2 stop api'); - console.log(''); - console.log(' Restart the app that is stopped :'); - console.log(' $ pm2 restart api'); - console.log(''); - console.log(' Remove the app from the process list :'); - console.log(' $ pm2 delete api'); - console.log(''); - console.log(' Kill daemon pm2 :'); - console.log(' $ pm2 kill'); - console.log(''); - console.log(' Update pm2 :'); - console.log(' $ npm install pm2@latest -g ; pm2 update'); - console.log(''); - console.log(' More examples in https://github.com/Unitech/pm2#usagefeatures'); - console.log(''); - console.log(' Deployment help:'); - console.log(''); - console.log(' $ pm2 deploy help'); - console.log(''); - console.log(''); -}); + function displayUsage() { + console.log('Usage: pm2 ') + console.log(' pm2 [option(s)]'); + console.log(''); + console.log('pm2 -h, --help all commands and options available'); + console.log('pm2 quickStart display pm2 usage examples'); + console.log('pm2 -h help on '); + console.log(''); + console.log('Access pm2 files in ~/.pm2'); + } + + function displayQuickStart() { + console.log('Install pm2 auto completion:') + console.log('$> pm2 completion install') + console.log(''); + console.log('Start and add a process to the pm2 process list:') + console.log('$> pm2 start app.js --name app'); + console.log(''); + console.log('Stop and delete a process from the pm2 process list:'); + console.log('$> pm2 delete app'); + console.log(''); + console.log('Show the process list:'); + console.log('$> pm2 ls'); + console.log(''); + console.log('Stop, start and restart a process from the process list:'); + console.log('$> pm2 stop app'); + console.log('$> pm2 start app'); + console.log('$> pm2 restart app'); + console.log(''); + console.log('Clusterize an app to all CPU cores available:'); + console.log('$> pm2 start -i max'); + console.log(''); + console.log('Update pm2 :'); + console.log('$> npm install pm2 -g && pm2 update'); + console.log(''); + console.log('Check the full documentation on https://docs.pm2.io'); + console.log(''); + } if (process.argv.indexOf('-s') > -1) { for(var key in console){ @@ -312,12 +315,6 @@ commander.command('startOrReload ') pm2._startJson(file, commander, 'reloadProcessId'); }); -commander.command('pid [app_name]') - .description('return pid of [app_name] or all') - .action(function(app) { - pm2.getPID(app); - }); - commander.command('startOrGracefulReload ') .description('start or gracefully reload JSON file') .action(function(file) { @@ -464,11 +461,11 @@ commander.command('update') /** * Module specifics */ -commander.command('install [module|git:// url|json]') +commander.command('install ') .alias('module:install') .option('--v1', 'install module in v1 manner (do not use it)') .option('--safe [time]', 'keep module backup, if new module fail = restore with previous') - .description('install or update a module (or a set of modules) and run it forever') + .description('install or update a module and run it forever') .action(function(plugin_name, opts) { if (opts.v1) commander.v1 = true; @@ -919,13 +916,21 @@ commander.command('serve [path] [port]') pm2.serve(path, port, commander); }); +commander.command('quickStart') + .description('display pm2 usage examples') + .action(() => { + console.log(cst.PREFIX_MSG + '\nQuick Start:\n'); + displayQuickStart(); + process.exit(cst.SUCCESS_EXIT); + }) + // // Catch all // commander.command('*') .action(function() { - console.log(cst.PREFIX_MSG + '\nCommand not found'); - commander.outputHelp(); + console.log(cst.PREFIX_MSG + '\nCommand not found\n'); + displayUsage(); // Check if it does not forget to close fds from RPC process.exit(cst.ERROR_EXIT); }); @@ -935,7 +940,7 @@ commander.command('*') // if (process.argv.length == 2) { commander.parse(process.argv); - commander.outputHelp(); + displayUsage(); // Check if it does not forget to close fds from RPC process.exit(cst.ERROR_EXIT); } From 41c6be78e13066fd7ce7ed81c653e9807f54fca6 Mon Sep 17 00:00:00 2001 From: Robin Monnier Date: Thu, 15 Mar 2018 14:55:12 +0100 Subject: [PATCH 02/10] improve pm2 examples --- bin/pm2 | 86 ++++++++++++++++++++++++++++++--------------------------- 1 file changed, 45 insertions(+), 41 deletions(-) diff --git a/bin/pm2 b/bin/pm2 index 02fdce445..0bb033bc3 100755 --- a/bin/pm2 +++ b/bin/pm2 @@ -88,41 +88,45 @@ commander.version(pkg.version) .usage('[cmd] app'); function displayUsage() { - console.log('Usage: pm2 ') - console.log(' pm2 [option(s)]'); + console.log('usage: pm2 [options] ') console.log(''); console.log('pm2 -h, --help all commands and options available'); - console.log('pm2 quickStart display pm2 usage examples'); - console.log('pm2 -h help on '); + console.log('pm2 examples display pm2 usage examples'); + console.log('pm2 -h help on a specific command'); console.log(''); console.log('Access pm2 files in ~/.pm2'); } - function displayQuickStart() { - console.log('Install pm2 auto completion:') - console.log('$> pm2 completion install') + function displayExamples() { + console.log('- Start and add a process to the pm2 process list:') console.log(''); - console.log('Start and add a process to the pm2 process list:') - console.log('$> pm2 start app.js --name app'); + console.log(chalk.cyan(' $ pm2 start app.js --name app')); console.log(''); - console.log('Stop and delete a process from the pm2 process list:'); - console.log('$> pm2 delete app'); + console.log('- Show the process list:'); console.log(''); - console.log('Show the process list:'); - console.log('$> pm2 ls'); + console.log(chalk.cyan(' $ pm2 ls')); console.log(''); - console.log('Stop, start and restart a process from the process list:'); - console.log('$> pm2 stop app'); - console.log('$> pm2 start app'); - console.log('$> pm2 restart app'); + console.log('- Stop and delete a process from the pm2 process list:'); console.log(''); - console.log('Clusterize an app to all CPU cores available:'); - console.log('$> pm2 start -i max'); + console.log(chalk.cyan(' $ pm2 delete app')); console.log(''); - console.log('Update pm2 :'); - console.log('$> npm install pm2 -g && pm2 update'); + console.log('- Stop, start and restart a process from the process list:'); console.log(''); - console.log('Check the full documentation on https://docs.pm2.io'); + console.log(chalk.cyan(' $ pm2 stop app')); + console.log(chalk.cyan(' $ pm2 start app')); + console.log(chalk.cyan(' $ pm2 restart app')); + console.log(''); + console.log('- Clusterize an app to all CPU cores available:'); + console.log(chalk.cyan(' $ pm2 start -i max')); + console.log(''); + console.log('- Update pm2 :'); + console.log(chalk.cyan(' $ npm install pm2 -g && pm2 update')); + console.log(''); + console.log('- Install pm2 auto completion:') + console.log(''); + console.log(chalk.cyan(' $ pm2 completion install')) + console.log(''); + console.log('Check the full documentation on https://pm2.io/doc'); console.log(''); } @@ -256,7 +260,7 @@ function patchCommanderArg(cmd) { // // Start command // -commander.command('start ') +commander.command('start ') .option('--watch', 'Watch folder for changes') .option('--fresh', 'Rebuild Dockerfile') .option('--daemon', 'Run container in Daemon mode (debug purposes)') @@ -326,7 +330,7 @@ commander.command('startOrGracefulReload ') // commander.command('stop ') .option('--watch', 'Stop watching folder for changes') - .description('stop a process (to start it again, do pm2 restart )') + .description('stop a process') .action(function(param) { async.forEachLimit(param, 1, function(script, next) { pm2.stop(script, next); @@ -550,41 +554,41 @@ commander.command('report') commander.command('link [secret] [public] [name]') .alias('interact') .option('--info-node [url]', 'set url info node') - .description('linking action to keymetrics.io - command can be stop|info|delete|restart') + .description('link with the pm2 monitoring dashboard') .action(pm2._pre_interact.bind(pm2)); commander.command('unlink') - .description('linking action to keymetrics.io - command can be stop|info|delete|restart') + .description('unlink with the pm2 monitoring dashboard') .action(function() { pm2.unlink(); }); -commander.command('unmonitor [name]') - .description('unmonitor target process') - .action(function(name) { - pm2.monitorState('unmonitor', name); - }); - commander.command('monitor [name]') .description('monitor target process') .action(function(name) { pm2.monitorState('monitor', name); }); +commander.command('unmonitor [name]') + .description('unmonitor target process') + .action(function(name) { + pm2.monitorState('unmonitor', name); + }); + commander.command('open') - .description('open dashboard in browser') + .description('open the pm2 monitoring dashboard') .action(function(name) { pm2.openDashboard(); }); commander.command('register') - .description('create an account on keymetrics') + .description('register on pm2 monitoring') .action(function(name) { pm2.registerToKM(); }); commander.command('login') - .description('login to keymetrics and link current PM2') + .description('use login to link with the pm2 monitoring dashboard') .action(function(name) { pm2.loginToKM(); }); @@ -642,7 +646,7 @@ commander.command('resurrect') // Set pm2 to startup // commander.command('unstartup [platform]') - .description('disable and clear auto startup - [platform]=systemd,upstart,launchd,rcd') + .description('disable the pm2 startup hook') .action(function(platform) { pm2.uninstallStartup(platform, commander); }); @@ -651,7 +655,7 @@ commander.command('unstartup [platform]') // Set pm2 to startup // commander.command('startup [platform]') - .description('setup script for pm2 at boot - [platform]=systemd,upstart,launchd,rcd') + .description('enable the pm2 startup hook') .action(function(platform) { pm2.startup(platform, commander); }); @@ -916,11 +920,11 @@ commander.command('serve [path] [port]') pm2.serve(path, port, commander); }); -commander.command('quickStart') +commander.command('examples') .description('display pm2 usage examples') .action(() => { - console.log(cst.PREFIX_MSG + '\nQuick Start:\n'); - displayQuickStart(); + console.log(cst.PREFIX_MSG + chalk.grey('pm2 usage examples:\n')); + displayExamples(); process.exit(cst.SUCCESS_EXIT); }) @@ -929,7 +933,7 @@ commander.command('quickStart') // commander.command('*') .action(function() { - console.log(cst.PREFIX_MSG + '\nCommand not found\n'); + console.log(cst.PREFIX_MSG + 'Command not found\n'); displayUsage(); // Check if it does not forget to close fds from RPC process.exit(cst.ERROR_EXIT); From 42bcc02a512f2128e2e8f7743bf79c3f80284cac Mon Sep 17 00:00:00 2001 From: Robin Monnier Date: Thu, 15 Mar 2018 14:59:03 +0100 Subject: [PATCH 03/10] correct bad english --- bin/pm2 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bin/pm2 b/bin/pm2 index 0bb033bc3..18a1f81ea 100755 --- a/bin/pm2 +++ b/bin/pm2 @@ -90,7 +90,7 @@ commander.version(pkg.version) function displayUsage() { console.log('usage: pm2 [options] ') console.log(''); - console.log('pm2 -h, --help all commands and options available'); + console.log('pm2 -h, --help all available commands and options'); console.log('pm2 examples display pm2 usage examples'); console.log('pm2 -h help on a specific command'); console.log(''); From 3524617606ac2d262d9a278603f221b22e30bf48 Mon Sep 17 00:00:00 2001 From: Robin Monnier Date: Thu, 15 Mar 2018 15:48:26 +0100 Subject: [PATCH 04/10] add unwanted deletion --- bin/pm2 | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/bin/pm2 b/bin/pm2 index 18a1f81ea..c15b9a565 100755 --- a/bin/pm2 +++ b/bin/pm2 @@ -85,6 +85,9 @@ commander.version(pkg.version) .option('--disable-trace', 'disable transaction tracing with km') .option('--attach', 'attach logging after your start/restart/stop/reload') .option('--sort ', 'sort process according to field\'s name') + .option('--v8', 'enable v8 data collecting') + .option('--event-loop-inspector', 'enable event-loop-inspector dump in pmx') + .option('--deep-monitoring', 'enable all monitoring tools (equivalent to --v8 --event-loop-inspector --trace)') .usage('[cmd] app'); function displayUsage() { @@ -319,6 +322,12 @@ commander.command('startOrReload ') pm2._startJson(file, commander, 'reloadProcessId'); }); +commander.command('pid [app_name]') + .description('return pid of [app_name] or all') + .action(function(app) { + pm2.getPID(app); + }); + commander.command('startOrGracefulReload ') .description('start or gracefully reload JSON file') .action(function(file) { From 0914e2a7bcca68466ad64b52d94ef096cde4505f Mon Sep 17 00:00:00 2001 From: Robin Monnier Date: Thu, 15 Mar 2018 15:52:23 +0100 Subject: [PATCH 05/10] add spacing to examples --- bin/pm2 | 2 ++ 1 file changed, 2 insertions(+) diff --git a/bin/pm2 b/bin/pm2 index c15b9a565..1e19ead73 100755 --- a/bin/pm2 +++ b/bin/pm2 @@ -120,9 +120,11 @@ commander.version(pkg.version) console.log(chalk.cyan(' $ pm2 restart app')); console.log(''); console.log('- Clusterize an app to all CPU cores available:'); + console.log(''); console.log(chalk.cyan(' $ pm2 start -i max')); console.log(''); console.log('- Update pm2 :'); + console.log(''); console.log(chalk.cyan(' $ npm install pm2 -g && pm2 update')); console.log(''); console.log('- Install pm2 auto completion:') From 799c48e77378c35233b14fdea4d0888eb4033b0a Mon Sep 17 00:00:00 2001 From: Robin Monnier Date: Fri, 16 Mar 2018 16:29:13 +0100 Subject: [PATCH 06/10] start ecosystem file with pm2 start by default --- bin/pm2 | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/bin/pm2 b/bin/pm2 index 05072f4bc..1f989a229 100755 --- a/bin/pm2 +++ b/bin/pm2 @@ -253,7 +253,7 @@ function patchCommanderArg(cmd) { // // Start command // -commander.command('start ') +commander.command('start [file|json|stdin|app_name|pm_id...]') .option('--watch', 'Watch folder for changes') .option('--fresh', 'Rebuild Dockerfile') .option('--daemon', 'Run container in Daemon mode (debug purposes)') @@ -280,6 +280,9 @@ commander.command('start ') else { // Commander.js patch cmd = patchCommanderArg(cmd); + if (cmd.length === 0) { + cmd = [cst.APP_CONF_DEFAULT_FILE]; + } async.forEachLimit(cmd, 1, function(script, next) { pm2.start(script, commander, next); }, function(err) { From d9df60eb97ab4afbf9f4e35d3ea64d6364615a6b Mon Sep 17 00:00:00 2001 From: Robin Monnier Date: Fri, 16 Mar 2018 18:44:00 +0100 Subject: [PATCH 07/10] change all ecosystem.json to ecosystem.config.js --- ADVANCED_README.md | 2 +- constants.js | 2 +- lib/API/Modules/Modularizer.js | 2 +- lib/Common.js | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/ADVANCED_README.md b/ADVANCED_README.md index 8c6931d93..1de13ee09 100644 --- a/ADVANCED_README.md +++ b/ADVANCED_README.md @@ -32,7 +32,7 @@ - [Without Keymetrics](#without-keymetrics) - [With Keymetrics](#with-keymetrics) -### Deployment - ecosystem.json +### Deployment - ecosystem.config.js - [Getting started with deployment](#deployment) - [Deployment options](#deployment-help) diff --git a/constants.js b/constants.js index c86f87720..3c21e4c08 100644 --- a/constants.js +++ b/constants.js @@ -28,7 +28,7 @@ var csts = { TEMPLATE_FOLDER : p.join(__dirname, 'lib/templates'), - APP_CONF_DEFAULT_FILE : 'ecosystem.json', + APP_CONF_DEFAULT_FILE : 'ecosystem.config.js', APP_CONF_TPL : 'ecosystem.tpl', APP_CONF_TPL_SIMPLE : 'ecosystem-simple.tpl', SAMPLE_CONF_FILE : 'sample-conf.js', diff --git a/lib/API/Modules/Modularizer.js b/lib/API/Modules/Modularizer.js index 7093324bf..f2189fbaf 100644 --- a/lib/API/Modules/Modularizer.js +++ b/lib/API/Modules/Modularizer.js @@ -47,7 +47,7 @@ var KNOWN_MODULES = { * - Generate sample module via pm2 module:generate */ Modularizer.install = function (CLI, moduleName, opts, cb) { - // if user want to install module from ecosystem.json file + // if user want to install module from ecosystem.config.js file // it can also be a custom json file's name if (!moduleName || moduleName.length === 0 || moduleName.indexOf('.json') > 0) { var file = moduleName || cst.APP_CONF_DEFAULT_FILE; diff --git a/lib/Common.js b/lib/Common.js index 2dd053aab..c4226f3e6 100644 --- a/lib/Common.js +++ b/lib/Common.js @@ -260,7 +260,7 @@ Common.isConfigFile = function(filename) { }; /** - * Parses a config file like ecosystem.json. Supported formats: JS, JSON, JSON5, YAML. + * Parses a config file like ecosystem.config.js. Supported formats: JS, JSON, JSON5, YAML. * @param {string} confString contents of the config file * @param {string} filename path to the config file * @return {Object} config object From 8e96ab360e04e056a0f75844d4c4d44ebf1261fb Mon Sep 17 00:00:00 2001 From: abluchet Date: Mon, 19 Mar 2018 14:01:20 +0100 Subject: [PATCH 08/10] Improve monitoring performances --- lib/God.js | 3 - lib/God/ActionMethods.js | 113 +++++++++++++++++++++------------ package.json | 2 +- test/programmatic/god.mocha.js | 48 ++++++++++++++ 4 files changed, 121 insertions(+), 45 deletions(-) diff --git a/lib/God.js b/lib/God.js index dc0019972..3e4c1d541 100644 --- a/lib/God.js +++ b/lib/God.js @@ -291,9 +291,6 @@ God.handleExit = function handleExit(clu, exit_code, kill_signal) { return false; } - if (proc.process.pid) - pidusage.unmonitor(proc.process.pid); - var stopping = (proc.pm2_env.status == cst.STOPPING_STATUS || proc.pm2_env.status == cst.STOPPED_STATUS || proc.pm2_env.status == cst.ERRORED_STATUS) || (proc.pm2_env.autorestart === false || diff --git a/lib/God/ActionMethods.js b/lib/God/ActionMethods.js index 1556a1652..092b7df38 100644 --- a/lib/God/ActionMethods.js +++ b/lib/God/ActionMethods.js @@ -41,55 +41,63 @@ module.exports = function(God) { */ God.getMonitorData = function getMonitorData(env, cb) { var processes = God.getFormatedProcesses(); + var pids = processes.filter(filterBadProcess) + .map(function(pro, i) { + var pid = getProcessId(pro) + return pid; + }) + + // No pids, return empty statistics + if (pids.length === 0) { + return cb(null, processes.map(function(pro) { + pro['monit'] = { + memory : 0, + cpu : 0 + }; - async.eachSeries(processes, function computeMonitor(pro, next) { - if (pro.pm2_env.status == cst.ONLINE_STATUS) { - var pid = pro.pid; - - if (pro.pm2_env.axm_options && pro.pm2_env.axm_options.pid) { - if (isNaN(pro.pm2_env.axm_options.pid)) { - pro['monit'] = { - memory : 0, - cpu : 0 - }; - return process.nextTick(next); - } - pid = pro.pm2_env.axm_options.pid; + return pro + })) + } + + pidusage(pids, function retPidUsage(err, statistics) { + // Just log, we'll set empty statistics + if (err) { + console.error('Error caught while calling pidusage'); + console.error(err); + } + + processes = processes.map(function(pro) { + if (filterBadProcess(pro) === false) { + pro['monit'] = { + memory : 0, + cpu : 0 + }; + + return pro; } - pidusage.stat(pid, function retPidUsage(err, res) { - if (err) { - // Do not log, some time modules does not retrieve PID - // console.error('Error caught while calling pidusage'); - // console.error(err); - pro['monit'] = { - memory : 0, - cpu : 0 - }; - return next(); - } + var pid = getProcessId(pro); + var stat = statistics[pid]; + if (!stat) { pro['monit'] = { - memory : Math.floor(res.memory), - cpu : Math.floor(res.cpu) + memory : 0, + cpu : 0 }; - res = null; - pid = null; - return next(); - }); - } - else { + + return pro; + } + pro['monit'] = { - memory : 0, - cpu : 0 + memory: stat.memory, + cpu: stat.cpu }; - return next(); - } - }, function retMonitor(err, res) { - if (err) return cb(God.logAndGenerateError(err), null); - return cb(null, processes); - }); + return pro; + }); + + cb(null, processes); + }); }; /** @@ -304,7 +312,6 @@ module.exports = function(God) { God.killProcess(proc.process.pid, proc.pm2_env, function(err) { proc.pm2_env.status = cst.STOPPED_STATUS; - pidusage.unmonitor(proc.process.pid); God.notify('exit', proc); @@ -841,3 +848,27 @@ module.exports = function(God) { }); }; }; + +function filterBadProcess(pro) { + if (pro.pm2_env.status !== cst.ONLINE_STATUS) { + return false; + } + + if (pro.pm2_env.axm_options && pro.pm2_env.axm_options.pid) { + if (isNaN(pro.pm2_env.axm_options.pid)) { + return false; + } + } + + return true; +} + +function getProcessId(pro) { + var pid = pro.pid + + if (pro.pm2_env.axm_options && pro.pm2_env.axm_options.pid) { + pid = pro.pm2_env.axm_options.pid; + } + + return pid +} diff --git a/package.json b/package.json index 3702dbaec..8e9a96084 100644 --- a/package.json +++ b/package.json @@ -174,7 +174,7 @@ "moment": "^2.19", "needle": "^2.2.0", "nssocket": "0.6.0", - "pidusage": "^2.0.0", + "pidusage": "^2.0.5", "pm2-axon": "3.1.0", "pm2-axon-rpc": "0.5.0", "pm2-deploy": "^0.3.9", diff --git a/test/programmatic/god.mocha.js b/test/programmatic/god.mocha.js index 887a15f34..5c22cd533 100644 --- a/test/programmatic/god.mocha.js +++ b/test/programmatic/god.mocha.js @@ -256,4 +256,52 @@ describe('God', function() { }); }); + it('should get monitor data', function(done) { + var f = require('child_process').fork('../fixtures/echo.js') + + var processes = [ + // stopped status + { + pm2_env: {status: cst.STOPPED_STATUS} + }, + // axm pid + { + pm2_env: { + status: cst.ONLINE_STATUS, axm_options: {pid: process.pid} + } + }, + // axm pid is NaN + { + pm2_env: { + status: cst.ONLINE_STATUS, axm_options: {pid: 'notanumber'} + } + }, + { + pm2_env: { + status: cst.ONLINE_STATUS + }, + pid: f.pid + } + ] + + // mock + var g = { + getFormatedProcesses: function() { + return processes + } + } + + require('../../lib/God/ActionMethods.js')(g) + + g.getMonitorData({}, function(err, procs) { + should(err).be.null(); + procs.length.should.be.equal(processes.length); + procs[0].monit.should.be.deepEqual({memory: 0, cpu: 0}); + procs[1].monit.memory.should.be.greaterThan(0); + procs[2].monit.should.be.deepEqual({memory: 0, cpu: 0}); + procs[3].monit.memory.should.be.greaterThan(0); + f.kill() + done() + }) + }); }); From e0be81c86c7defb5e7a271edd5cc37f960c6aa69 Mon Sep 17 00:00:00 2001 From: Eywek Date: Mon, 19 Mar 2018 14:09:48 +0100 Subject: [PATCH 09/10] fix: remove useless tests from .sh --- test/pm2_programmatic_tests.sh | 26 -------------------------- 1 file changed, 26 deletions(-) diff --git a/test/pm2_programmatic_tests.sh b/test/pm2_programmatic_tests.sh index 695c622f6..97f203f3b 100644 --- a/test/pm2_programmatic_tests.sh +++ b/test/pm2_programmatic_tests.sh @@ -95,37 +95,11 @@ cd ../interface echo $PM2_HOME -mocha --opts ./mocha.opts ./exception.e2e.mocha.js -spec "E2E exception system checking" -mocha --opts ./mocha.opts ./interactor.connect.mocha.js -spec "Interactor test #1 with password setting" -mocha --opts ./mocha.opts ./interactor.daemonizer.mocha.js -spec "Remote interactor keys save verification" -mocha --opts ./mocha.opts ./scoped_pm2_actions.mocha.js -spec "Scoped PM2 Remote interactions test" -mocha --opts ./mocha.opts ./remote.mocha.js -spec "Remote interactions test" -mocha --opts ./mocha.opts ./password.mocha.js -spec "Password library checking" -mocha --opts ./mocha.opts ./custom-actions.mocha.js -spec "Custom actions test" mocha --opts ./mocha.opts ./bus.spec.mocha.js spec "Protocol communication test" mocha --opts ./mocha.opts ./bus.fork.spec.mocha.js spec "Protocol communication test" -mocha --opts ./mocha.opts ./request.mocha.js -spec "Protocol communication test" -mocha --opts ./mocha.opts ./aggregator.mocha.js -spec "Transaction trace aggregator test" -mocha --opts ./mocha.opts ./stacktrace.mocha.js -spec "Stacktrace Utility" -mocha --opts ./mocha.opts ./cache.mocha.js -spec "Cache Utility" -mocha --opts ./mocha.opts ./filter.mocha.js -spec "Filter Utility" mocha --opts ./mocha.opts ./utility.mocha.js spec "PM2 Utility" mocha --opts ./mocha.opts ./pm2.link.check.mocha.js spec "Transaction option enablement" -mocha --opts ./mocha.opts ./monitor.mocha.js -spec "Monitor / Unmonitor commands" From fc5adf36d5a77ac6cb1a8b84719afb1336563f83 Mon Sep 17 00:00:00 2001 From: Eywek Date: Mon, 19 Mar 2018 15:54:13 +0100 Subject: [PATCH 10/10] remove useless test --- test/interface/pm2.link.check.mocha.js | 86 -------------------------- test/pm2_programmatic_tests.sh | 2 - 2 files changed, 88 deletions(-) delete mode 100644 test/interface/pm2.link.check.mocha.js diff --git a/test/interface/pm2.link.check.mocha.js b/test/interface/pm2.link.check.mocha.js deleted file mode 100644 index 6bc24e6b2..000000000 --- a/test/interface/pm2.link.check.mocha.js +++ /dev/null @@ -1,86 +0,0 @@ -process.env.NODE_ENV = 'local_test'; -process.env.TRAVIS = true; - -var PM2 = require('../..'); -var should = require('should'); - -describe('PM2 link variable checks', function() { - var server; - this.timeout(5000); - - describe('km_link false', function() { - var pm2 = new PM2.custom({ - cwd : __dirname + '/../fixtures' - }); - - before(function(done) { - pm2.connect(function(err, data) { - done(); - }); - }); - - after(function(done) { - pm2.kill(done); - }); - - it('should start an app and app km_link to false', function(done) { - pm2.start({ - trace : true, - script : 'http.js' - }, function(err) { - done(); - }) - }); - - it('should have km_link to false', function(done) { - // Wait for process initialization - setTimeout(function() { - pm2.list(function(err, dt) { - dt[0].pm2_env.km_link.should.be.false(); - dt[0].pm2_env.axm_options.transactions.should.be.false(); - done(); - }); - }, 500); - }); - }); - - describe('km_link true', function() { - var pm2; - - before(function(done) { - pm2 = new PM2.custom({ - cwd : __dirname + '/../fixtures', - secret_key : 'osef', - public_key : 'osef', - machine_name : 'osef', - daemon_mode: true - }); - - pm2.connect(done); - }); - - after(function(done) { - pm2.kill(done); - }); - - it('should start an app and app km_link to false', function(done) { - pm2.start({ - script : 'http.js', - trace : true - }, done) - }); - - it('should have km_link to false', function(done) { - // Wait for process initialization - setTimeout(function() { - pm2.list(function(err, dt) { - dt[0].pm2_env.km_link.should.be.true(); - //dt[0].pm2_env.axm_options.transactions.should.be.true(); - dt[0].pm2_env.axm_options.tracing_enabled.should.be.true(); - done(); - }); - }, 1000); - }); - }); - -}); diff --git a/test/pm2_programmatic_tests.sh b/test/pm2_programmatic_tests.sh index 97f203f3b..c99dac233 100644 --- a/test/pm2_programmatic_tests.sh +++ b/test/pm2_programmatic_tests.sh @@ -101,5 +101,3 @@ mocha --opts ./mocha.opts ./bus.fork.spec.mocha.js spec "Protocol communication test" mocha --opts ./mocha.opts ./utility.mocha.js spec "PM2 Utility" -mocha --opts ./mocha.opts ./pm2.link.check.mocha.js -spec "Transaction option enablement"