Extra.js 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775
  1. /***************************
  2. *
  3. * Extra methods
  4. *
  5. **************************/
  6. var cst = require('../../constants.js');
  7. var Common = require('../Common.js');
  8. var UX = require('./UX');
  9. var chalk = require('chalk');
  10. var path = require('path');
  11. var fs = require('fs');
  12. var fmt = require('../tools/fmt.js');
  13. var dayjs = require('dayjs');
  14. var pkg = require('../../package.json');
  15. const copyDirSync = require('../tools/copydirSync.js')
  16. module.exports = function(CLI) {
  17. /**
  18. * Get version of the daemonized PM2
  19. * @method getVersion
  20. * @callback cb
  21. */
  22. CLI.prototype.getVersion = function(cb) {
  23. var that = this;
  24. that.Client.executeRemote('getVersion', {}, function(err) {
  25. return cb ? cb.apply(null, arguments) : that.exitCli(cst.SUCCESS_EXIT);
  26. });
  27. };
  28. /**
  29. * Install pm2-sysmonit
  30. */
  31. CLI.prototype.launchSysMonitoring = function(cb) {
  32. if ((this.pm2_configuration && this.pm2_configuration.sysmonit != 'true') ||
  33. process.env.TRAVIS ||
  34. global.it === 'function' ||
  35. cst.IS_WINDOWS === true)
  36. return cb ? cb(null) : null
  37. var filepath
  38. try {
  39. filepath = path.dirname(require.resolve('pm2-sysmonit'))
  40. } catch(e) {
  41. return cb ? cb(null) : null
  42. }
  43. this.start({
  44. script: filepath
  45. }, {
  46. started_as_module : true
  47. }, (err, res) => {
  48. if (err) {
  49. Common.printError(cst.PREFIX_MSG_ERR + 'Error while trying to serve : ' + err.message || err);
  50. return cb ? cb(err) : this.speedList(cst.ERROR_EXIT);
  51. }
  52. return cb ? cb(null) : this.speedList();
  53. });
  54. };
  55. /**
  56. * Show application environment
  57. * @method env
  58. * @callback cb
  59. */
  60. CLI.prototype.env = function(app_id, cb) {
  61. var procs = []
  62. var printed = 0
  63. this.Client.executeRemote('getMonitorData', {}, (err, list) => {
  64. list.forEach(l => {
  65. if (app_id == l.pm_id) {
  66. printed++
  67. var env = Common.safeExtend({}, l.pm2_env)
  68. Object.keys(env).forEach(key => {
  69. console.log(`${key}: ${chalk.green(env[key])}`)
  70. })
  71. }
  72. })
  73. if (printed == 0) {
  74. Common.err(`Modules with id ${app_id} not found`)
  75. return cb ? cb.apply(null, arguments) : this.exitCli(cst.ERROR_EXIT);
  76. }
  77. return cb ? cb.apply(null, arguments) : this.exitCli(cst.SUCCESS_EXIT);
  78. })
  79. };
  80. /**
  81. * Get version of the daemonized PM2
  82. * @method getVersion
  83. * @callback cb
  84. */
  85. CLI.prototype.report = function() {
  86. var that = this;
  87. var Log = require('./Log');
  88. that.Client.executeRemote('getReport', {}, function(err, report) {
  89. console.log()
  90. console.log()
  91. console.log()
  92. console.log('```')
  93. fmt.title('PM2 report')
  94. fmt.field('Date', new Date());
  95. fmt.sep();
  96. if (report && !err) {
  97. fmt.title(chalk.bold.blue('Daemon'));
  98. fmt.field('pm2d version', report.pm2_version);
  99. fmt.field('node version', report.node_version);
  100. fmt.field('node path', report.node_path);
  101. fmt.field('argv', report.argv);
  102. fmt.field('argv0', report.argv0);
  103. fmt.field('user', report.user);
  104. fmt.field('uid', report.uid);
  105. fmt.field('gid', report.gid);
  106. fmt.field('uptime', dayjs(new Date()).diff(report.started_at, 'minute') + 'min');
  107. }
  108. fmt.sep();
  109. fmt.title(chalk.bold.blue('CLI'));
  110. fmt.field('local pm2', pkg.version);
  111. fmt.field('node version', process.versions.node);
  112. fmt.field('node path', process.env['_'] || 'not found');
  113. fmt.field('argv', process.argv);
  114. fmt.field('argv0', process.argv0);
  115. fmt.field('user', process.env.USER || process.env.LNAME || process.env.USERNAME);
  116. if (cst.IS_WINDOWS === false && process.geteuid)
  117. fmt.field('uid', process.geteuid());
  118. if (cst.IS_WINDOWS === false && process.getegid)
  119. fmt.field('gid', process.getegid());
  120. var os = require('os');
  121. fmt.sep();
  122. fmt.title(chalk.bold.blue('System info'));
  123. fmt.field('arch', os.arch());
  124. fmt.field('platform', os.platform());
  125. fmt.field('type', os.type());
  126. fmt.field('cpus', os.cpus()[0].model);
  127. fmt.field('cpus nb', Object.keys(os.cpus()).length);
  128. fmt.field('freemem', os.freemem());
  129. fmt.field('totalmem', os.totalmem());
  130. fmt.field('home', os.homedir());
  131. that.Client.executeRemote('getMonitorData', {}, function(err, list) {
  132. fmt.sep();
  133. fmt.title(chalk.bold.blue('PM2 list'));
  134. UX.list(list, that.gl_interact_infos);
  135. fmt.sep();
  136. fmt.title(chalk.bold.blue('Daemon logs'));
  137. Log.tail([{
  138. path : cst.PM2_LOG_FILE_PATH,
  139. app_name : 'PM2',
  140. type : 'PM2'
  141. }], 20, false, function() {
  142. console.log('```')
  143. console.log()
  144. console.log()
  145. console.log(chalk.bold.green('Please copy/paste the above report in your issue on https://github.com/Unitech/pm2/issues'));
  146. console.log()
  147. console.log()
  148. that.exitCli(cst.SUCCESS_EXIT);
  149. });
  150. });
  151. });
  152. };
  153. CLI.prototype.getPID = function(app_name, cb) {
  154. var that = this;
  155. if (typeof(app_name) === 'function') {
  156. cb = app_name;
  157. app_name = null;
  158. }
  159. this.Client.executeRemote('getMonitorData', {}, function(err, list) {
  160. if (err) {
  161. Common.printError(cst.PREFIX_MSG_ERR + err);
  162. return cb ? cb(Common.retErr(err)) : that.exitCli(cst.ERROR_EXIT);
  163. }
  164. var pids = [];
  165. list.forEach(function(app) {
  166. if (!app_name || app_name == app.name)
  167. pids.push(app.pid);
  168. })
  169. if (!cb) {
  170. Common.printOut(pids.join("\n"))
  171. return that.exitCli(cst.SUCCESS_EXIT);
  172. }
  173. return cb(null, pids);
  174. })
  175. }
  176. /**
  177. * Create PM2 memory snapshot
  178. * @method getVersion
  179. * @callback cb
  180. */
  181. CLI.prototype.profile = function(type, time, cb) {
  182. var that = this;
  183. var dayjs = require('dayjs');
  184. var cmd
  185. if (type == 'cpu') {
  186. cmd = {
  187. ext: '.cpuprofile',
  188. action: 'profileCPU'
  189. }
  190. }
  191. if (type == 'mem') {
  192. cmd = {
  193. ext: '.heapprofile',
  194. action: 'profileMEM'
  195. }
  196. }
  197. var file = path.join(process.cwd(), dayjs().format('dd-HH:mm:ss') + cmd.ext);
  198. time = time || 10000
  199. console.log(`Starting ${cmd.action} profiling for ${time}ms...`)
  200. that.Client.executeRemote(cmd.action, {
  201. pwd : file,
  202. timeout: time
  203. }, function(err) {
  204. if (err) {
  205. console.error(err);
  206. return that.exitCli(1);
  207. }
  208. console.log(`Profile done in ${file}`)
  209. return cb ? cb.apply(null, arguments) : that.exitCli(cst.SUCCESS_EXIT);
  210. });
  211. };
  212. function basicMDHighlight(lines) {
  213. console.log('\n\n+-------------------------------------+')
  214. console.log(chalk.bold('README.md content:'))
  215. lines = lines.split('\n')
  216. var isInner = false
  217. lines.forEach(l => {
  218. if (l.startsWith('#'))
  219. console.log(chalk.bold.green(l))
  220. else if (isInner || l.startsWith('```')) {
  221. if (isInner && l.startsWith('```'))
  222. isInner = false
  223. else if (isInner == false)
  224. isInner = true
  225. console.log(chalk.grey(l))
  226. }
  227. else if (l.startsWith('`'))
  228. console.log(chalk.grey(l))
  229. else
  230. console.log(l)
  231. })
  232. console.log('+-------------------------------------+')
  233. }
  234. /**
  235. * pm2 create command
  236. * create boilerplate of application for fast try
  237. * @method boilerplate
  238. */
  239. CLI.prototype.boilerplate = function(cb) {
  240. var i = 0
  241. var projects = []
  242. var enquirer = require('enquirer')
  243. const forEach = require('async/forEach')
  244. fs.readdir(path.join(__dirname, '../templates/sample-apps'), (err, items) => {
  245. forEach(items, (app, next) => {
  246. var fp = path.join(__dirname, '../templates/sample-apps', app)
  247. fs.readFile(path.join(fp, 'package.json'), (err, dt) => {
  248. var meta = JSON.parse(dt)
  249. meta.fullpath = fp
  250. meta.folder_name = app
  251. projects.push(meta)
  252. next()
  253. })
  254. }, () => {
  255. const prompt = new enquirer.Select({
  256. name: 'boilerplate',
  257. message: 'Select a boilerplate',
  258. choices: projects.map((p, i) => {
  259. return {
  260. message: `${chalk.bold.blue(p.name)} ${p.description}`,
  261. value: `${i}`
  262. }
  263. })
  264. });
  265. prompt.run()
  266. .then(answer => {
  267. var p = projects[parseInt(answer)]
  268. basicMDHighlight(fs.readFileSync(path.join(p.fullpath, 'README.md')).toString())
  269. console.log(chalk.bold(`>> Project copied inside folder ./${p.folder_name}/\n`))
  270. copyDirSync(p.fullpath, path.join(process.cwd(), p.folder_name));
  271. this.start(path.join(p.fullpath, 'ecosystem.config.js'), {
  272. cwd: p.fullpath
  273. }, () => {
  274. return cb ? cb.apply(null, arguments) : this.speedList(cst.SUCCESS_EXIT);
  275. })
  276. })
  277. .catch(e => {
  278. return cb ? cb.apply(null, arguments) : this.speedList(cst.SUCCESS_EXIT);
  279. });
  280. })
  281. })
  282. }
  283. /**
  284. * Description
  285. * @method sendLineToStdin
  286. */
  287. CLI.prototype.sendLineToStdin = function(pm_id, line, separator, cb) {
  288. var that = this;
  289. if (!cb && typeof(separator) == 'function') {
  290. cb = separator;
  291. separator = null;
  292. }
  293. var packet = {
  294. pm_id : pm_id,
  295. line : line + (separator || '\n')
  296. };
  297. that.Client.executeRemote('sendLineToStdin', packet, function(err, res) {
  298. if (err) {
  299. Common.printError(cst.PREFIX_MSG_ERR + err);
  300. return cb ? cb(Common.retErr(err)) : that.exitCli(cst.ERROR_EXIT);
  301. }
  302. return cb ? cb(null, res) : that.speedList();
  303. });
  304. };
  305. /**
  306. * Description
  307. * @method attachToProcess
  308. */
  309. CLI.prototype.attach = function(pm_id, separator, cb) {
  310. var that = this;
  311. var readline = require('readline');
  312. if (isNaN(pm_id)) {
  313. Common.printError('pm_id must be a process number (not a process name)');
  314. return cb ? cb(Common.retErr('pm_id must be number')) : that.exitCli(cst.ERROR_EXIT);
  315. }
  316. if (typeof(separator) == 'function') {
  317. cb = separator;
  318. separator = null;
  319. }
  320. var rl = readline.createInterface({
  321. input: process.stdin,
  322. output: process.stdout
  323. });
  324. rl.on('close', function() {
  325. return cb ? cb() : that.exitCli(cst.SUCCESS_EXIT);
  326. });
  327. that.Client.launchBus(function(err, bus, socket) {
  328. if (err) {
  329. Common.printError(err);
  330. return cb ? cb(Common.retErr(err)) : that.exitCli(cst.ERROR_EXIT);
  331. }
  332. bus.on('log:*', function(type, packet) {
  333. if (packet.process.pm_id !== parseInt(pm_id))
  334. return;
  335. process.stdout.write(packet.data);
  336. });
  337. });
  338. rl.on('line', function(line) {
  339. that.sendLineToStdin(pm_id, line, separator, function() {});
  340. });
  341. };
  342. /**
  343. * Description
  344. * @method sendDataToProcessId
  345. */
  346. CLI.prototype.sendDataToProcessId = function(proc_id, packet, cb) {
  347. var that = this;
  348. if (typeof proc_id === 'object' && typeof packet === 'function') {
  349. // the proc_id is packet.
  350. cb = packet;
  351. packet = proc_id;
  352. } else {
  353. packet.id = proc_id;
  354. }
  355. that.Client.executeRemote('sendDataToProcessId', packet, function(err, res) {
  356. if (err) {
  357. Common.printError(err);
  358. return cb ? cb(Common.retErr(err)) : that.exitCli(cst.ERROR_EXIT);
  359. }
  360. Common.printOut('successfully sent data to process');
  361. return cb ? cb(null, res) : that.speedList();
  362. });
  363. };
  364. /**
  365. * Used for custom actions, allows to trigger function inside an app
  366. * To expose a function you need to use keymetrics/pmx
  367. *
  368. * @method msgProcess
  369. * @param {Object} opts
  370. * @param {String} id process id
  371. * @param {String} action_name function name to trigger
  372. * @param {Object} [opts.opts] object passed as first arg of the function
  373. * @param {String} [uuid] optional unique identifier when logs are emitted
  374. *
  375. */
  376. CLI.prototype.msgProcess = function(opts, cb) {
  377. var that = this;
  378. that.Client.executeRemote('msgProcess', opts, cb);
  379. };
  380. /**
  381. * Trigger a PMX custom action in target application
  382. * Custom actions allows to interact with an application
  383. *
  384. * @method trigger
  385. * @param {String|Number} pm_id process id or application name
  386. * @param {String} action_name name of the custom action to trigger
  387. * @param {Mixed} params parameter to pass to target action
  388. * @param {Function} cb callback
  389. */
  390. CLI.prototype.trigger = function(pm_id, action_name, params, cb) {
  391. if (typeof(params) === 'function') {
  392. cb = params;
  393. params = null;
  394. }
  395. var cmd = {
  396. msg : action_name
  397. };
  398. var counter = 0;
  399. var process_wait_count = 0;
  400. var that = this;
  401. var results = [];
  402. if (params)
  403. cmd.opts = params;
  404. if (isNaN(pm_id))
  405. cmd.name = pm_id;
  406. else
  407. cmd.id = pm_id;
  408. this.launchBus(function(err, bus) {
  409. bus.on('axm:reply', function(ret) {
  410. if (ret.process.name == pm_id || ret.process.pm_id == pm_id || ret.process.namespace == pm_id || pm_id == 'all') {
  411. results.push(ret);
  412. Common.printOut('[%s:%s:%s]=%j', ret.process.name, ret.process.pm_id, ret.process.namespace, ret.data.return);
  413. if (++counter == process_wait_count)
  414. return cb ? cb(null, results) : that.exitCli(cst.SUCCESS_EXIT);
  415. }
  416. });
  417. that.msgProcess(cmd, function(err, data) {
  418. if (err) {
  419. Common.printError(err);
  420. return cb ? cb(Common.retErr(err)) : that.exitCli(cst.ERROR_EXIT);
  421. }
  422. if (data.process_count == 0) {
  423. Common.printError('Not any process has received a command (offline or unexistent)');
  424. return cb ? cb(Common.retErr('Unknown process')) : that.exitCli(cst.ERROR_EXIT);
  425. }
  426. process_wait_count = data.process_count;
  427. Common.printOut(chalk.bold('%s processes have received command %s'),
  428. data.process_count, action_name);
  429. });
  430. });
  431. };
  432. /**
  433. * Description
  434. * @method sendSignalToProcessName
  435. * @param {} signal
  436. * @param {} process_name
  437. * @return
  438. */
  439. CLI.prototype.sendSignalToProcessName = function(signal, process_name, cb) {
  440. var that = this;
  441. that.Client.executeRemote('sendSignalToProcessName', {
  442. signal : signal,
  443. process_name : process_name
  444. }, function(err, list) {
  445. if (err) {
  446. Common.printError(err);
  447. return cb ? cb(Common.retErr(err)) : that.exitCli(cst.ERROR_EXIT);
  448. }
  449. Common.printOut('successfully sent signal %s to process name %s', signal, process_name);
  450. return cb ? cb(null, list) : that.speedList();
  451. });
  452. };
  453. /**
  454. * Description
  455. * @method sendSignalToProcessId
  456. * @param {} signal
  457. * @param {} process_id
  458. * @return
  459. */
  460. CLI.prototype.sendSignalToProcessId = function(signal, process_id, cb) {
  461. var that = this;
  462. that.Client.executeRemote('sendSignalToProcessId', {
  463. signal : signal,
  464. process_id : process_id
  465. }, function(err, list) {
  466. if (err) {
  467. Common.printError(err);
  468. return cb ? cb(Common.retErr(err)) : that.exitCli(cst.ERROR_EXIT);
  469. }
  470. Common.printOut('successfully sent signal %s to process id %s', signal, process_id);
  471. return cb ? cb(null, list) : that.speedList();
  472. });
  473. };
  474. /**
  475. * API method to launch a process that will serve directory over http
  476. */
  477. CLI.prototype.autoinstall = function (cb) {
  478. var filepath = path.resolve(path.dirname(module.filename), '../Sysinfo/ServiceDetection/ServiceDetection.js');
  479. this.start(filepath, (err, res) => {
  480. if (err) {
  481. Common.printError(cst.PREFIX_MSG_ERR + 'Error while trying to serve : ' + err.message || err);
  482. return cb ? cb(err) : this.speedList(cst.ERROR_EXIT);
  483. }
  484. return cb ? cb(null) : this.speedList();
  485. });
  486. }
  487. /**
  488. * API method to launch a process that will serve directory over http
  489. *
  490. * @param {Object} opts options
  491. * @param {String} opts.path path to be served
  492. * @param {Number} opts.port port on which http will bind
  493. * @param {Boolean} opts.spa single page app served
  494. * @param {String} opts.basicAuthUsername basic auth username
  495. * @param {String} opts.basicAuthPassword basic auth password
  496. * @param {Object} commander commander object
  497. * @param {Function} cb optional callback
  498. */
  499. CLI.prototype.serve = function (target_path, port, opts, commander, cb) {
  500. var that = this;
  501. var servePort = process.env.PM2_SERVE_PORT || port || 8080;
  502. var servePath = path.resolve(process.env.PM2_SERVE_PATH || target_path || '.');
  503. var filepath = path.resolve(path.dirname(module.filename), './Serve.js');
  504. if (typeof commander.name === 'string')
  505. opts.name = commander.name
  506. else
  507. opts.name = 'static-page-server-' + servePort
  508. if (!opts.env)
  509. opts.env = {};
  510. opts.env.PM2_SERVE_PORT = servePort;
  511. opts.env.PM2_SERVE_PATH = servePath;
  512. opts.env.PM2_SERVE_SPA = opts.spa;
  513. if (opts.basicAuthUsername && opts.basicAuthPassword) {
  514. opts.env.PM2_SERVE_BASIC_AUTH = 'true';
  515. opts.env.PM2_SERVE_BASIC_AUTH_USERNAME = opts.basicAuthUsername;
  516. opts.env.PM2_SERVE_BASIC_AUTH_PASSWORD = opts.basicAuthPassword;
  517. }
  518. if (opts.monitor) {
  519. opts.env.PM2_SERVE_MONITOR = opts.monitor
  520. }
  521. opts.cwd = servePath;
  522. this.start(filepath, opts, function (err, res) {
  523. if (err) {
  524. Common.printError(cst.PREFIX_MSG_ERR + 'Error while trying to serve : ' + err.message || err);
  525. return cb ? cb(err) : that.speedList(cst.ERROR_EXIT);
  526. }
  527. Common.printOut(cst.PREFIX_MSG + 'Serving ' + servePath + ' on port ' + servePort);
  528. return cb ? cb(null, res) : that.speedList();
  529. });
  530. }
  531. /**
  532. * Ping daemon - if PM2 daemon not launched, it will launch it
  533. * @method ping
  534. */
  535. CLI.prototype.ping = function(cb) {
  536. var that = this;
  537. that.Client.executeRemote('ping', {}, function(err, res) {
  538. if (err) {
  539. Common.printError(err);
  540. return cb ? cb(new Error(err)) : that.exitCli(cst.ERROR_EXIT);
  541. }
  542. Common.printOut(res);
  543. return cb ? cb(null, res) : that.exitCli(cst.SUCCESS_EXIT);
  544. });
  545. };
  546. /**
  547. * Execute remote command
  548. */
  549. CLI.prototype.remote = function(command, opts, cb) {
  550. var that = this;
  551. that[command](opts.name, function(err_cmd, ret) {
  552. if (err_cmd)
  553. console.error(err_cmd);
  554. console.log('Command %s finished', command);
  555. return cb(err_cmd, ret);
  556. });
  557. };
  558. /**
  559. * This remote method allows to pass multiple arguments
  560. * to PM2
  561. * It is used for the new scoped PM2 action system
  562. */
  563. CLI.prototype.remoteV2 = function(command, opts, cb) {
  564. var that = this;
  565. if (that[command].length == 1)
  566. return that[command](cb);
  567. opts.args.push(cb);
  568. return that[command].apply(this, opts.args);
  569. };
  570. /**
  571. * Description
  572. * @method generateSample
  573. * @param {} name
  574. * @return
  575. */
  576. CLI.prototype.generateSample = function(mode) {
  577. var that = this;
  578. var templatePath;
  579. if (mode == 'simple')
  580. templatePath = path.join(cst.TEMPLATE_FOLDER, cst.APP_CONF_TPL_SIMPLE);
  581. else
  582. templatePath = path.join(cst.TEMPLATE_FOLDER, cst.APP_CONF_TPL);
  583. var sample = fs.readFileSync(templatePath);
  584. var dt = sample.toString();
  585. var f_name = 'ecosystem.config.js';
  586. var pwd = process.env.PWD || process.cwd();
  587. try {
  588. fs.writeFileSync(path.join(pwd, f_name), dt);
  589. } catch (e) {
  590. console.error(e.stack || e);
  591. return that.exitCli(cst.ERROR_EXIT);
  592. }
  593. Common.printOut('File %s generated', path.join(pwd, f_name));
  594. that.exitCli(cst.SUCCESS_EXIT);
  595. };
  596. /**
  597. * Description
  598. * @method dashboard
  599. * @return
  600. */
  601. CLI.prototype.dashboard = function(cb) {
  602. var that = this;
  603. var Dashboard = require('./Dashboard');
  604. if (cb)
  605. return cb(new Error('Dashboard cant be called programmatically'));
  606. Dashboard.init();
  607. this.Client.launchBus(function (err, bus) {
  608. if (err) {
  609. console.error('Error launchBus: ' + err);
  610. that.exitCli(cst.ERROR_EXIT);
  611. }
  612. bus.on('log:*', function(type, data) {
  613. Dashboard.log(type, data)
  614. })
  615. });
  616. process.on('SIGINT', function() {
  617. this.Client.disconnectBus(function() {
  618. process.exit(cst.SUCCESS_EXIT);
  619. });
  620. });
  621. function refreshDashboard() {
  622. that.Client.executeRemote('getMonitorData', {}, function(err, list) {
  623. if (err) {
  624. console.error('Error retrieving process list: ' + err);
  625. that.exitCli(cst.ERROR_EXIT);
  626. }
  627. Dashboard.refresh(list);
  628. setTimeout(function() {
  629. refreshDashboard();
  630. }, 800);
  631. });
  632. }
  633. refreshDashboard();
  634. };
  635. CLI.prototype.monit = function(cb) {
  636. var that = this;
  637. var Monit = require('./Monit.js');
  638. if (cb) return cb(new Error('Monit cant be called programmatically'));
  639. Monit.init();
  640. function launchMonitor() {
  641. that.Client.executeRemote('getMonitorData', {}, function(err, list) {
  642. if (err) {
  643. console.error('Error retrieving process list: ' + err);
  644. that.exitCli(conf.ERROR_EXIT);
  645. }
  646. Monit.refresh(list);
  647. setTimeout(function() {
  648. launchMonitor();
  649. }, 400);
  650. });
  651. }
  652. launchMonitor();
  653. };
  654. CLI.prototype.inspect = function(app_name, cb) {
  655. const that = this;
  656. this.trigger(app_name, 'internal:inspect', function (err, res) {
  657. if(res && res[0]) {
  658. if (res[0].data.return === '') {
  659. Common.printOut(`Inspect disabled on ${app_name}`);
  660. } else {
  661. Common.printOut(`Inspect enabled on ${app_name} => go to chrome : chrome://inspect !!!`);
  662. }
  663. } else {
  664. Common.printOut(`Unable to activate inspect mode on ${app_name} !!!`);
  665. }
  666. that.exitCli(cst.SUCCESS_EXIT);
  667. });
  668. };
  669. };