refactor: performance
This commit is contained in:
parent
76c5ad6910
commit
b0d72f595e
18
pm2-gui.ini
18
pm2-gui.ini
|
|
@ -3,21 +3,27 @@
|
|||
;
|
||||
pm2 = ~/.pm2
|
||||
;
|
||||
; The interval between communications of Monitor.
|
||||
; The monitor will fetch system CPU/Memory amount after this certain time interval.
|
||||
; it could be milliseconds or various time formats(https://github.com/zeit/ms)
|
||||
;
|
||||
refresh = 5000
|
||||
refresh = 5s
|
||||
;
|
||||
; Port of Web server and socket agent.
|
||||
;
|
||||
port = 8088
|
||||
;
|
||||
; A value indicates whether or not run the pm2-gui damonized.
|
||||
; A value indicates whether or not run the pm2-gui as damonization.
|
||||
;
|
||||
daemonize = true
|
||||
daemonize = false
|
||||
;
|
||||
; A value indicates whether or not the action buttons (i.e. `restart`, `stop all`...) should be displayed on web page.
|
||||
;
|
||||
readonly = false
|
||||
;
|
||||
; The monitor will fetch process CPU/Memory amount after this certain time interval.
|
||||
; it could be milliseconds or various time formats(https://github.com/zeit/ms)
|
||||
;
|
||||
process_refresh = 3s
|
||||
|
||||
[log]
|
||||
;
|
||||
|
|
@ -35,7 +41,7 @@ date = false
|
|||
;
|
||||
; Log level, one of debug, log, info, warn, error.
|
||||
;
|
||||
level = warn
|
||||
level = info
|
||||
;
|
||||
; Socket.io origins check, e.g.:
|
||||
; origins = 'example.com:* http://example.com:* http://www.example.com:8088'
|
||||
|
|
@ -46,7 +52,7 @@ level = warn
|
|||
;
|
||||
; This authorization will be used to authorize socket / web connections if it's set.
|
||||
;
|
||||
authorization = AuTh
|
||||
;authorization = AuTh
|
||||
;
|
||||
; A value indicates whether agent offline or not.
|
||||
;
|
||||
|
|
|
|||
170
pm2-gui.js
170
pm2-gui.js
|
|
@ -1,23 +1,31 @@
|
|||
'use strict'
|
||||
|
||||
var chalk = require('chalk')
|
||||
var path = require('path')
|
||||
var fs = require('fs')
|
||||
var _ = require('lodash')
|
||||
var socketIO = require('socket.io')
|
||||
var inquirer = require('inquirer')
|
||||
|
||||
var Monitor = require('./lib/monitor')
|
||||
var Log = require('./lib/util/log')
|
||||
var Web = require('./web/index')
|
||||
var layout = require('./lib/blessed-widget/layout')
|
||||
var Layout = require('./lib/blessed-widget/layout')
|
||||
|
||||
var regLocal = /^(127\.0\.0\.1|0\.0\.0\.0|localhost)$/i
|
||||
|
||||
// cli
|
||||
if (path.basename(process.mainModule.filename, '.js') === 'pm2-gui') {
|
||||
var cmd, file
|
||||
if (process.argv.length > 2) {
|
||||
var cmd = 'start'
|
||||
var file
|
||||
var processArgvLen = process.argv.length
|
||||
|
||||
if (processArgvLen > 2) {
|
||||
cmd = process.argv[2]
|
||||
}
|
||||
if (process.argv.length > 3) {
|
||||
if (processArgvLen > 3) {
|
||||
file = process.argv[3]
|
||||
}
|
||||
cmd = cmd || 'start'
|
||||
|
||||
switch (cmd) {
|
||||
case 'start':
|
||||
|
|
@ -44,13 +52,17 @@ exports.startAgent = startAgent
|
|||
exports.dashboard = dashboard
|
||||
exports.exitGraceful = exitGraceful
|
||||
|
||||
/**
|
||||
* Strat the web server by a configured file.
|
||||
* @param {String} confFile full path of config file
|
||||
* @return {N/A}
|
||||
*/
|
||||
function startWebServer (confFile) {
|
||||
var monitor = slave({
|
||||
confFile: confFile
|
||||
})
|
||||
var options = monitor.options
|
||||
|
||||
options.port = options.port || 8088
|
||||
// express server
|
||||
var server = Web({
|
||||
middleware: function (req, res, next) {
|
||||
req._config = options
|
||||
|
|
@ -58,7 +70,7 @@ function startWebServer (confFile) {
|
|||
},
|
||||
port: options.port
|
||||
})
|
||||
|
||||
// socket.io server
|
||||
monitor.sockio = socketIO(server, {
|
||||
origins: options.origins || '*:*'
|
||||
})
|
||||
|
|
@ -66,18 +78,22 @@ function startWebServer (confFile) {
|
|||
console.info('Web server is listening on 127.0.0.1:' + options.port)
|
||||
}
|
||||
|
||||
/**
|
||||
* Simply start the agent
|
||||
* @param {String} confFile full path of config file
|
||||
* @return {N/A}
|
||||
*/
|
||||
function startAgent (confFile) {
|
||||
var monitor = slave({
|
||||
confFile: confFile
|
||||
})
|
||||
|
||||
// check agent status
|
||||
var options = monitor.options
|
||||
options.agent = options.agent || {}
|
||||
if (options.agent.offline) {
|
||||
console.error('Agent is offline, can not start it.')
|
||||
if (options.agent && options.agent.offline) {
|
||||
console.error('Agent is offline, fatal to start it.')
|
||||
return process.exit(0)
|
||||
}
|
||||
options.port = options.port || 8088
|
||||
// socket.io server
|
||||
var sockio = socketIO()
|
||||
sockio.listen(options.port, {
|
||||
origins: options.origins || '*:*'
|
||||
|
|
@ -87,19 +103,25 @@ function startAgent (confFile) {
|
|||
console.info('Socket.io server is listening on 0.0.0.0:' + options.port)
|
||||
}
|
||||
|
||||
/**
|
||||
* Curses like dashboard
|
||||
* @param {String} confFile full path of config file
|
||||
* @return {N/A}
|
||||
*/
|
||||
function dashboard (confFile) {
|
||||
// restore cursor
|
||||
process.on('exit', function () {
|
||||
process.stdout.write('\u001b[?25h')
|
||||
})
|
||||
// process.on('exit', function () {
|
||||
// process.stderr.write('\u001b[?25h')
|
||||
// })
|
||||
// which server would you like to connect to.
|
||||
var monitor = slave({
|
||||
confFile: confFile
|
||||
})
|
||||
|
||||
var options = _.clone(monitor.options)
|
||||
var q = Monitor.available(options)
|
||||
|
||||
if (!q) {
|
||||
console.error('No agent is online, can not start it.')
|
||||
console.error('No agent is online, fatal to start it.')
|
||||
return process.exit(0)
|
||||
}
|
||||
var ql = q.choices.length
|
||||
|
|
@ -117,40 +139,54 @@ function dashboard (confFile) {
|
|||
console.log('')
|
||||
inquirer.prompt(q).then(function (answers) {
|
||||
console.log('')
|
||||
// connecting...
|
||||
_connectToDashboard(monitor, options, Monitor.parseConnectionString(answers.socket_server))
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* Exit process graceful
|
||||
* @param {Number} code
|
||||
* @param {String} signal
|
||||
* @return {N/A}
|
||||
*/
|
||||
function exitGraceful (code, signal) {
|
||||
code = code || 0
|
||||
if (signal !== '-f') {
|
||||
console.debug('Slave has exited, code: ' + code + ', signal: ' + (signal || 'NULL'))
|
||||
console.debug('Slave has exited, code: ' + code + ', signal: ' + (signal || 'N/A'))
|
||||
}
|
||||
// exit process after std flushed
|
||||
var fds = 0
|
||||
var stds = [process.stdout, process.stderr]
|
||||
stds.forEach(function (std) {
|
||||
var fd = std.fd
|
||||
if (!std.bufferSize) {
|
||||
fds = fds | fd
|
||||
return
|
||||
}
|
||||
std.write && std.write('', function () {
|
||||
fds = fds | fd
|
||||
tryToExit()
|
||||
})
|
||||
})
|
||||
tryToExit()
|
||||
|
||||
function tryToExit () {
|
||||
if ((fds & 1) && (fds & 2)) {
|
||||
process.exit(code)
|
||||
}
|
||||
}
|
||||
|
||||
[process.stdout, process.stderr].forEach(function (std) {
|
||||
var fd = std.fd
|
||||
if (!std.bufferSize) {
|
||||
fds = fds | fd
|
||||
} else {
|
||||
std.write && std.write('', function () {
|
||||
fds = fds | fd
|
||||
tryToExit()
|
||||
})
|
||||
}
|
||||
})
|
||||
tryToExit()
|
||||
}
|
||||
|
||||
/**
|
||||
* Spawn a slave-worker
|
||||
* @param {Object} options
|
||||
* @return {N/A}
|
||||
*/
|
||||
function slave (options) {
|
||||
process.title = 'pm2-gui slave'
|
||||
options = options || {}
|
||||
// check config file.
|
||||
var confFile = options.confFile
|
||||
if (!confFile) {
|
||||
confFile = path.resolve(__dirname, './pm2-gui.ini')
|
||||
|
|
@ -160,28 +196,32 @@ function slave (options) {
|
|||
return process.exit(0)
|
||||
}
|
||||
}
|
||||
|
||||
// initialize monitor.
|
||||
var monitor = Monitor({
|
||||
confFile: confFile
|
||||
})
|
||||
|
||||
// initialize logger.
|
||||
Log(monitor.options.log)
|
||||
|
||||
// logo
|
||||
console.log(chalk.cyan(
|
||||
'\n' +
|
||||
'█▀▀█ █▀▄▀█ █▀█ ░░ ▒█▀▀█ ▒█░▒█ ▀█▀\n' +
|
||||
'█░░█ █░▀░█ ░▄▀ ▀▀ ▒█░▄▄ ▒█░▒█ ▒█░\n' +
|
||||
'█▀▀▀ ▀░░░▀ █▄▄ ░░ ▒█▄▄█ ░▀▄▄▀ ▄█▄\n'))
|
||||
|
||||
// listening signal (CTRL+C...)
|
||||
process.on('uncaughtException', caughtException)
|
||||
process.on('SIGTERM', shutdown)
|
||||
process.on('SIGINT', shutdown)
|
||||
process.on('SIGHUP', restart)
|
||||
process.on('uncaughtException', caughtException)
|
||||
process.on('exit', exitGraceful)
|
||||
|
||||
return monitor
|
||||
|
||||
function shutdown (code, signal) {
|
||||
console.info('Shutting down....')
|
||||
monitor.quit()
|
||||
console.info('Shutdown complete!')
|
||||
console.info('Completed!')
|
||||
exitGraceful(code, '-f')
|
||||
}
|
||||
|
||||
|
|
@ -191,40 +231,54 @@ function slave (options) {
|
|||
action: 'restart'
|
||||
})
|
||||
} else {
|
||||
console.error('No IPC found, could not restart monitor, shutting down.')
|
||||
console.error('No IPC found, fatal to restart monitor')
|
||||
shutdown(1)
|
||||
}
|
||||
}
|
||||
|
||||
function caughtException (err) {
|
||||
console.error(err.stack)
|
||||
process.stderr.write(chalk.red.bold('[PROCESS EXCEPTION]') + ' ' + err.stack + '\n')
|
||||
shutdown(1)
|
||||
}
|
||||
|
||||
return monitor
|
||||
}
|
||||
|
||||
/**
|
||||
* Connect to socket.io server and render the curses dashboard
|
||||
* @param {Monitor} monitor
|
||||
* @param {Object} options
|
||||
* @param {Object} connection
|
||||
* @return {N/A}
|
||||
*/
|
||||
function _connectToDashboard (monitor, options, connection) {
|
||||
connection = _.extend({}, options, connection)
|
||||
if (!!~['127.0.0.1', '0.0.0.0', 'localhost'].indexOf(connection.hostname)) { // eslint-disable-line no-extra-boolean-cast
|
||||
return monitor.connect(connection, function (socket) {
|
||||
console.info('Agent is online, try to connect it in dashboard directly.')
|
||||
layout(connection).render(monitor)
|
||||
}, function (err, socket) {
|
||||
if (err === 'unauthorized') {
|
||||
console.error('There was an error with the authentication:', err)
|
||||
return process.exit(0)
|
||||
if (regLocal.test(connection.hostname)) {
|
||||
console.info('Connecting to local dashboard')
|
||||
return monitor.connect(connection, function (err, socket) {
|
||||
if (err) {
|
||||
if (err === 'unauthorized') {
|
||||
console.error('There was an error caught when verifying the auth-code:', err.message)
|
||||
return process.exit(0)
|
||||
}
|
||||
console.warn('Fatal to connect to monitor:', err.message)
|
||||
console.warn('Agent is offline, try to start it:', '127.0.0.1:' + connection.port)
|
||||
// start socket.io server.
|
||||
var sockio = socketIO()
|
||||
sockio.listen(connection.port, {
|
||||
origins: options.origins || '*:*'
|
||||
})
|
||||
// run monitor
|
||||
monitor.sockio = sockio
|
||||
monitor.run()
|
||||
// render dashboard
|
||||
Layout(connection).render(monitor)
|
||||
return
|
||||
}
|
||||
console.warn('Agent is offline, try to start it.')
|
||||
var sockio = socketIO()
|
||||
sockio.listen(connection.port, {
|
||||
origins: options.origins || '*:*'
|
||||
})
|
||||
monitor.sockio = sockio
|
||||
monitor.run()
|
||||
layout(connection).render(monitor)
|
||||
// render dashboard
|
||||
console.info('Agent is online, try to connect it in dashboard directly.')
|
||||
Layout(connection).render(monitor)
|
||||
})
|
||||
}
|
||||
|
||||
layout(connection).render(monitor)
|
||||
console.info('Connecting to remote dashboard')
|
||||
Layout(connection).render(monitor)
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue