diff --git a/ADVANCED_README.md b/ADVANCED_README.md index bde5b903..0645e9cc 100644 --- a/ADVANCED_README.md +++ b/ADVANCED_README.md @@ -12,7 +12,7 @@ - [Options](#a987) - [Schema](#schema) - [How to update PM2?](#update-pm2) -- [PM2 auto-completion](#auto-completion) +- [PM2 tab-completion](#tab-completion) - [Allow PM2 to bind apps on port 80/443 without root](#authbind-pm2) ### Features @@ -266,27 +266,34 @@ Then update the in-memory PM2 : $ pm2 update ``` - -## PM2 auto-completion + +## PM2 tab-completion + +Tab-completion for pm2. Append pm2 completion script to your .bashrc or .zshrc file: ```bash $ pm2 completion install ``` +Or manually append completion script to your ~/.bashrc or ~/.zshrc file: -Add pm2 completion to your current session: +```bash +$ pm2 completion >> ~/.bashrc # or ~/.zshrc +``` + +Then source your .bashrc or .zshrc file for current session: + +```bash +$ source ~/.bashrc # or ~/.zshrc +``` + +You can add pm2 completion to your current session this way: ```bash $ . <(pm2 completion) ``` -Manually append completion script to your ~/.bashrc or ~/.zshrc file: - -```bash -$ pm2 completion >> ~/.bashrc -``` - ## Allow PM2 to bind applications on ports 80/443 without root diff --git a/CHANGELOG.md b/CHANGELOG.md index c5d1225f..6b7a9648 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,13 +1,18 @@ -# 0.14.3 +# 0.14.4 + +- New command : `pm2 iprobe [app_name|app_id|'ALL']` + +# 0.14.3 (Current Stable) - `pm2 flush` now flushes pm2.log as well - New flag : `--no-treekill` : when used PM2 won't kill children processes -- New flags : `pm2 logs [ 'all' | 'PM2' | app_name | app_id] [--err | --out] [--lines ] [--raw] [--timestamp [format]]` -- Enhancement: Module installable via Github: `pm2 install username/repository` +- New flags : `pm2 logs ['all'|'PM2'|app_name|app_id] [--err|--out] [--lines ] [--raw] [--timestamp [format]]` +- Enhancement: Modules installable via Github: `pm2 install username/repository` - Feature: PMX has *scoped function* -> pm2 stores temporary output from custom functions - Fix: Interactor issue when doing an heapdump +- Feature: PM2 CLI autocompletion -# 0.14.2 (Current Stable) +# 0.14.2 - Improved pm2-dev - Now when apps list is empty, the `id` counter is set to 0 diff --git a/bin/pm2 b/bin/pm2 index 0a98dbd2..deeb7443 100755 --- a/bin/pm2 +++ b/bin/pm2 @@ -126,7 +126,7 @@ function checkCompletion(){ return data.short; }), data); // array containing commands after which process name should be listed - var cmdProcess = ['stop', 'restart', 'scale', 'reload', 'gracefulReload', 'delete', 'reset', 'pull', 'forward', 'backward']; + var cmdProcess = ['stop', 'restart', 'scale', 'reload', 'gracefulReload', 'delete', 'reset', 'pull', 'forward', 'backward', 'logs', 'describe', 'desc', 'show']; if(cmdProcess.indexOf(data.prev) > -1) { CLI.connect(function() { CLI.list(function(err, list){ @@ -688,6 +688,16 @@ commander.command('gc') CLI.forceGc(); }); +// +// Display probes in a graphical way +// +commander.command('iprobe [app_name|app_id]') + .description('displays probes in a graphical way') + .action(function(pm2_id) { + pm2_id = pm2_id || 'ALL'; + CLI.IProbe(pm2_id); + }); + // // Catch all // diff --git a/lib/CLI.js b/lib/CLI.js index 2c3a4a52..311e2e9d 100644 --- a/lib/CLI.js +++ b/lib/CLI.js @@ -1484,6 +1484,61 @@ CLI.describe = function(pm2_id, cb) { }); }; + +/** + * Description + * @method IProbe + * @param {} pm2_id + * @return + */ +CLI.IProbe = function(pm2_id) { + + var getProbeData = function(pm2_id, cb) { + Satan.executeRemote('getMonitorData', {}, function(err, list) { + if (err) { + printError('Error retrieving process list: ' + err); + exitCli(cst.ERROR_EXIT); + } + + var found_proc = []; + + list.forEach(function(proc) { + if ((!isNaN(parseInt(pm2_id)) && proc.pm_id == pm2_id) + || (typeof(pm2_id) === 'string' && proc.name == pm2_id) + || pm2_id === 'ALL') { + found_proc.push(proc); + } + }); + + if (found_proc.length === 0) { + return cb(['{bold}No probes to display{/bold}']); + } + + var content = []; + + found_proc.forEach(function(proc) { + content.push('{bold}' + proc.pm2_env.name + ' (id:' + proc.pm2_env.pm_id + ')' + '{/bold}'); + + var monit = proc.pm2_env.axm_monitor; + for (var k in monit) + content.push(k + ' : ' + monit[k].value); + + content.push('\n'); + }); + + return cb(content); + }); + }; + + var iprobe = new require('./IProbe.js')(); + + setInterval(function() { + getProbeData(pm2_id, function(content) { + iprobe.refresh(content); + }); + }, 300); +}; + /** * Description * @method reloadLogs diff --git a/lib/IProbe.js b/lib/IProbe.js new file mode 100644 index 00000000..b2d6e080 --- /dev/null +++ b/lib/IProbe.js @@ -0,0 +1,60 @@ +var blessed = require('blessed'); + +var IProbe = function() { + if (!(this instanceof IProbe)) + return new IProbe(); + + this.screen = blessed.screen({ + autoPadding: true, + smartCSR: true + }); + + this.screen.title = 'PM2 realtime probes'; + + this.box = blessed.box({ + scrollable: true, + alwaysScroll: true, + keys: true, + scrollbar: { + fg: 'red', + ch: '|' + }, + + top: 'center', + left: 'center', + width: '100%', + height: '100%', + content: 'Fetching probes...', + align : "center", + valign : "middle", + tags: true, + border: { + type: 'line' + }, + style: { + fg: '#33ffff', + bg: 'black', + border: { + fg: '#33ffff' + }, + }, + }); + + this.screen.append(this.box); + + this.screen.key(['escape', 'q', 'C-c'], function(ch, key) { + return process.exit(0); + }); + this.box.focus(); + this.screen.render(); +}; + +IProbe.prototype.refresh = function(content) { + if (!content || !content.length) + return; + + this.box.setContent(content.join('\n')); + this.screen.render(); +}; + +module.exports = IProbe; diff --git a/lib/completion.js b/lib/completion.js index 58ca5fdc..a465c7cd 100644 --- a/lib/completion.js +++ b/lib/completion.js @@ -141,7 +141,7 @@ function install(name, completer, cb) { var part = file.split(markerIn)[1]; if(part) { - return cb(null, ' ✗ ' + completer + ' has been already installed. Do nothing.'); + return cb(null, ' ✗ ' + completer + ' tab-completion has been already installed. Do nothing.'); } rc = file; @@ -158,7 +158,7 @@ function install(name, completer, cb) { writeRc(rc + scriptOutput, function(err) { if(err) return cb(err); - return cb(null, ' ✓ ' + completer + ' installed.'); + return cb(null, ' ✓ ' + completer + ' tab-completion installed.'); }); } } @@ -172,13 +172,13 @@ function uninstall(name, completer, cb) { var part = file.split(markerIn)[1]; if(!part) { - return cb(null, ' ✗ ' + completer + ' has been already uninstalled. Do nothing.'); + return cb(null, ' ✗ ' + completer + ' tab-completion has been already uninstalled. Do nothing.'); } part = markerIn + part.split(markerOut)[0] + markerOut; writeRc(file.replace(part, ''), function(err) { if(err) return cb(err); - return cb(null, ' ✓ ' + completer + ' uninstalled.'); + return cb(null, ' ✓ ' + completer + ' tab-completion uninstalled.'); }); }); } diff --git a/lib/completion.sh b/lib/completion.sh index c71df32b..7ec05e14 100644 --- a/lib/completion.sh +++ b/lib/completion.sh @@ -1,5 +1,5 @@ ###-begin-pm2-completion-### -### credits to for the completion file model +### credits to npm for the completion file model # # Installation: pm2 completion >> ~/.bashrc (or ~/.zshrc) # @@ -35,6 +35,6 @@ elif type compctl &>/dev/null; then 2>/dev/null)) || return $? IFS="$si" } - compctl -K _pm2_completion pm2 + compctl -K _pm2_completion + -f + pm2 fi ###-end-pm2-completion-### diff --git a/package.json b/package.json index efd597c2..c1571590 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "pm2", "preferGlobal": "true", - "version": "0.14.2", + "version": "0.14.3", "engines": { "node": ">=0.10" }, @@ -173,6 +173,7 @@ "shelljs" : "0.5.1", "isbinaryfile" : "^2.0.3", + "blessed" : "0.1.61", "semver" : "4.3.6" }, "devDependencies": {