feat: 초기 프로젝트 설정 및 룰.md 파일 추가
This commit is contained in:
459
api.hyungi.net/node_modules/pm2/lib/API/Dashboard.js
generated
vendored
Normal file
459
api.hyungi.net/node_modules/pm2/lib/API/Dashboard.js
generated
vendored
Normal file
@@ -0,0 +1,459 @@
|
||||
/**
|
||||
* Copyright 2013-2022 the PM2 project authors. All rights reserved.
|
||||
* Use of this source code is governed by a license that
|
||||
* can be found in the LICENSE file.
|
||||
*/
|
||||
|
||||
var os = require('os');
|
||||
var p = require('path');
|
||||
var blessed = require('blessed');
|
||||
var debug = require('debug')('pm2:monit');
|
||||
var printf = require('sprintf-js').sprintf;
|
||||
|
||||
// Total memory
|
||||
const totalMem = os.totalmem();
|
||||
|
||||
var Dashboard = {};
|
||||
|
||||
var DEFAULT_PADDING = {
|
||||
top : 0,
|
||||
left : 1,
|
||||
right : 1
|
||||
};
|
||||
|
||||
var WIDTH_LEFT_PANEL = 30;
|
||||
|
||||
/**
|
||||
* Synchronous Dashboard init method
|
||||
* @method init
|
||||
* @return this
|
||||
*/
|
||||
Dashboard.init = function() {
|
||||
// Init Screen
|
||||
this.screen = blessed.screen({
|
||||
smartCSR: true,
|
||||
fullUnicode: true
|
||||
});
|
||||
this.screen.title = 'PM2 Dashboard';
|
||||
|
||||
this.logLines = {}
|
||||
|
||||
this.list = blessed.list({
|
||||
top: '0',
|
||||
left: '0',
|
||||
width: WIDTH_LEFT_PANEL + '%',
|
||||
height: '70%',
|
||||
padding: 0,
|
||||
scrollbar: {
|
||||
ch: ' ',
|
||||
inverse: false
|
||||
},
|
||||
border: {
|
||||
type: 'line'
|
||||
},
|
||||
keys: true,
|
||||
autoCommandKeys: true,
|
||||
tags: true,
|
||||
style: {
|
||||
selected: {
|
||||
bg: 'blue',
|
||||
fg: 'white'
|
||||
},
|
||||
scrollbar: {
|
||||
bg: 'blue',
|
||||
fg: 'black'
|
||||
},
|
||||
fg: 'white',
|
||||
border: {
|
||||
fg: 'blue'
|
||||
},
|
||||
header: {
|
||||
fg: 'blue'
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
this.list.on('select item', (item, i) => {
|
||||
this.logBox.clearItems()
|
||||
})
|
||||
|
||||
this.logBox = blessed.list({
|
||||
label: ' Logs ',
|
||||
top: '0',
|
||||
left: WIDTH_LEFT_PANEL + '%',
|
||||
width: 100 - WIDTH_LEFT_PANEL + '%',
|
||||
height: '70%',
|
||||
padding: DEFAULT_PADDING,
|
||||
scrollable: true,
|
||||
scrollbar: {
|
||||
ch: ' ',
|
||||
inverse: false
|
||||
},
|
||||
keys: true,
|
||||
autoCommandKeys: true,
|
||||
tags: true,
|
||||
border: {
|
||||
type: 'line'
|
||||
},
|
||||
style: {
|
||||
fg: 'white',
|
||||
border: {
|
||||
fg: 'white'
|
||||
},
|
||||
scrollbar: {
|
||||
bg: 'blue',
|
||||
fg: 'black'
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
this.metadataBox = blessed.box({
|
||||
label: ' Metadata ',
|
||||
top: '70%',
|
||||
left: WIDTH_LEFT_PANEL + '%',
|
||||
width: 100 - WIDTH_LEFT_PANEL + '%',
|
||||
height: '26%',
|
||||
padding: DEFAULT_PADDING,
|
||||
scrollable: true,
|
||||
scrollbar: {
|
||||
ch: ' ',
|
||||
inverse: false
|
||||
},
|
||||
keys: true,
|
||||
autoCommandKeys: true,
|
||||
tags: true,
|
||||
border: {
|
||||
type: 'line'
|
||||
},
|
||||
style: {
|
||||
fg: 'white',
|
||||
border: {
|
||||
fg: 'white'
|
||||
},
|
||||
scrollbar: {
|
||||
bg: 'blue',
|
||||
fg: 'black'
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
this.metricsBox = blessed.list({
|
||||
label: ' Custom Metrics ',
|
||||
top: '70%',
|
||||
left: '0%',
|
||||
width: WIDTH_LEFT_PANEL + '%',
|
||||
height: '26%',
|
||||
padding: DEFAULT_PADDING,
|
||||
scrollbar: {
|
||||
ch: ' ',
|
||||
inverse: false
|
||||
},
|
||||
keys: true,
|
||||
autoCommandKeys: true,
|
||||
tags: true,
|
||||
border: {
|
||||
type: 'line'
|
||||
},
|
||||
style: {
|
||||
fg: 'white',
|
||||
border: {
|
||||
fg: 'white'
|
||||
},
|
||||
scrollbar: {
|
||||
bg: 'blue',
|
||||
fg: 'black'
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
this.box4 = blessed.text({
|
||||
content: ' left/right: switch boards | up/down/mouse: scroll | Ctrl-C: exit{|} {cyan-fg}{bold}To go further check out https://pm2.io/{/} ',
|
||||
left: '0%',
|
||||
top: '95%',
|
||||
width: '100%',
|
||||
height: '6%',
|
||||
valign: 'middle',
|
||||
tags: true,
|
||||
style: {
|
||||
fg: 'white'
|
||||
}
|
||||
});
|
||||
|
||||
this.list.focus();
|
||||
|
||||
this.screen.append(this.list);
|
||||
this.screen.append(this.logBox);
|
||||
this.screen.append(this.metadataBox);
|
||||
this.screen.append(this.metricsBox);
|
||||
this.screen.append(this.box4);
|
||||
|
||||
this.list.setLabel(' Process List ');
|
||||
|
||||
this.screen.render();
|
||||
|
||||
var that = this;
|
||||
|
||||
var i = 0;
|
||||
var boards = ['list', 'logBox', 'metricsBox', 'metadataBox'];
|
||||
this.screen.key(['left', 'right'], function(ch, key) {
|
||||
(key.name === 'left') ? i-- : i++;
|
||||
if (i == 4)
|
||||
i = 0;
|
||||
if (i == -1)
|
||||
i = 3;
|
||||
that[boards[i]].focus();
|
||||
that[boards[i]].style.border.fg = 'blue';
|
||||
if (key.name === 'left') {
|
||||
if (i == 3)
|
||||
that[boards[0]].style.border.fg = 'white';
|
||||
else
|
||||
that[boards[i + 1]].style.border.fg = 'white';
|
||||
}
|
||||
else {
|
||||
if (i == 0)
|
||||
that[boards[3]].style.border.fg = 'white';
|
||||
else
|
||||
that[boards[i - 1]].style.border.fg = 'white';
|
||||
}
|
||||
});
|
||||
|
||||
this.screen.key(['escape', 'q', 'C-c'], function(ch, key) {
|
||||
this.screen.destroy();
|
||||
process.exit(0);
|
||||
});
|
||||
|
||||
// async refresh of the ui
|
||||
setInterval(function () {
|
||||
that.screen.render();
|
||||
}, 300);
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Refresh dashboard
|
||||
* @method refresh
|
||||
* @param {} processes
|
||||
* @return this
|
||||
*/
|
||||
Dashboard.refresh = function(processes) {
|
||||
debug('Monit refresh');
|
||||
|
||||
if(!processes) {
|
||||
this.list.setItem(0, 'No process available');
|
||||
return;
|
||||
}
|
||||
|
||||
if (processes.length != this.list.items.length) {
|
||||
this.list.clearItems();
|
||||
}
|
||||
|
||||
// Total of processes memory
|
||||
var mem = 0;
|
||||
processes.forEach(function(proc) {
|
||||
mem += proc.monit.memory;
|
||||
})
|
||||
|
||||
// Sort process list
|
||||
processes.sort(function(a, b) {
|
||||
if (a.pm2_env.name < b.pm2_env.name)
|
||||
return -1;
|
||||
if (a.pm2_env.name > b.pm2_env.name)
|
||||
return 1;
|
||||
return 0;
|
||||
});
|
||||
|
||||
// Loop to get process infos
|
||||
for (var i = 0; i < processes.length; i++) {
|
||||
// Percent of memory use by one process in all pm2 processes
|
||||
var memPercent = (processes[i].monit.memory / mem) * 100;
|
||||
|
||||
// Status of process
|
||||
var status = processes[i].pm2_env.status == 'online' ? '{green-fg}' : '{red-fg}';
|
||||
status = status + '{bold}' + processes[i].pm2_env.status + '{/}';
|
||||
|
||||
var name = processes[i].pm2_env.name || p.basename(processes[i].pm2_env.pm_exec_path);
|
||||
|
||||
// Line of list
|
||||
var item = printf('[%2s] %s {|} Mem: {bold}{%s-fg}%3d{/} MB CPU: {bold}{%s-fg}%2d{/} %s %s',
|
||||
processes[i].pm2_env.pm_id,
|
||||
name,
|
||||
gradient(memPercent, [255, 0, 0], [0, 255, 0]),
|
||||
(processes[i].monit.memory / 1048576).toFixed(2),
|
||||
gradient(processes[i].monit.cpu, [255, 0, 0], [0, 255, 0]),
|
||||
processes[i].monit.cpu,
|
||||
"%",
|
||||
status);
|
||||
|
||||
// Check if item exist
|
||||
if (this.list.getItem(i)) {
|
||||
this.list.setItem(i, item);
|
||||
}
|
||||
else {
|
||||
this.list.pushItem(item);
|
||||
}
|
||||
|
||||
var proc = processes[this.list.selected];
|
||||
// render the logBox
|
||||
let process_id = proc.pm_id
|
||||
let logs = this.logLines[process_id];
|
||||
if(typeof(logs) !== "undefined"){
|
||||
this.logBox.setItems(logs)
|
||||
if (!this.logBox.focused) {
|
||||
this.logBox.setScrollPerc(100);
|
||||
}
|
||||
}else{
|
||||
this.logBox.clearItems();
|
||||
}
|
||||
this.logBox.setLabel(` ${proc.pm2_env.name} Logs `)
|
||||
|
||||
this.metadataBox.setLine(0, 'App Name ' + '{bold}' + proc.pm2_env.name + '{/}');
|
||||
this.metadataBox.setLine(1, 'Namespace ' + '{bold}' + proc.pm2_env.namespace + '{/}');
|
||||
this.metadataBox.setLine(2, 'Version ' + '{bold}' + proc.pm2_env.version + '{/}');
|
||||
this.metadataBox.setLine(3, 'Restarts ' + proc.pm2_env.restart_time);
|
||||
this.metadataBox.setLine(4, 'Uptime ' + ((proc.pm2_env.pm_uptime && proc.pm2_env.status == 'online') ? timeSince(proc.pm2_env.pm_uptime) : 0));
|
||||
this.metadataBox.setLine(5, 'Script path ' + proc.pm2_env.pm_exec_path);
|
||||
this.metadataBox.setLine(6, 'Script args ' + (proc.pm2_env.args ? (typeof proc.pm2_env.args == 'string' ? JSON.parse(proc.pm2_env.args.replace(/'/g, '"')):proc.pm2_env.args).join(' ') : 'N/A'));
|
||||
this.metadataBox.setLine(7, 'Interpreter ' + proc.pm2_env.exec_interpreter);
|
||||
this.metadataBox.setLine(8, 'Interpreter args ' + (proc.pm2_env.node_args.length != 0 ? proc.pm2_env.node_args : 'N/A'));
|
||||
this.metadataBox.setLine(9, 'Exec mode ' + (proc.pm2_env.exec_mode == 'fork_mode' ? '{bold}fork{/}' : '{blue-fg}{bold}cluster{/}'));
|
||||
this.metadataBox.setLine(10, 'Node.js version ' + proc.pm2_env.node_version);
|
||||
this.metadataBox.setLine(11, 'watch & reload ' + (proc.pm2_env.watch ? '{green-fg}{bold}✔{/}' : '{red-fg}{bold}✘{/}'));
|
||||
this.metadataBox.setLine(12, 'Unstable restarts ' + proc.pm2_env.unstable_restarts);
|
||||
|
||||
this.metadataBox.setLine(13, 'Comment ' + ((proc.pm2_env.versioning) ? proc.pm2_env.versioning.comment : 'N/A'));
|
||||
this.metadataBox.setLine(14, 'Revision ' + ((proc.pm2_env.versioning) ? proc.pm2_env.versioning.revision : 'N/A'));
|
||||
this.metadataBox.setLine(15, 'Branch ' + ((proc.pm2_env.versioning) ? proc.pm2_env.versioning.branch : 'N/A'));
|
||||
this.metadataBox.setLine(16, 'Remote url ' + ((proc.pm2_env.versioning) ? proc.pm2_env.versioning.url : 'N/A'));
|
||||
this.metadataBox.deleteLine(17)
|
||||
this.metadataBox.setLine(17, 'Last update ' + ((proc.pm2_env.versioning) ? proc.pm2_env.versioning.update_time : 'N/A'));
|
||||
|
||||
if (Object.keys(proc.pm2_env.axm_monitor).length != this.metricsBox.items.length) {
|
||||
this.metricsBox.clearItems();
|
||||
}
|
||||
var j = 0;
|
||||
for (var key in proc.pm2_env.axm_monitor) {
|
||||
var metric_name = proc.pm2_env.axm_monitor[key].hasOwnProperty('value') ? proc.pm2_env.axm_monitor[key].value : proc.pm2_env.axm_monitor[key]
|
||||
var metric_unit = proc.pm2_env.axm_monitor[key].hasOwnProperty('unit') ? proc.pm2_env.axm_monitor[key].unit : null
|
||||
var probe = `{bold}${key}{/} {|} ${metric_name}${metric_unit == null ? '' : ' ' + metric_unit}`
|
||||
|
||||
if (this.metricsBox.getItem(j)) {
|
||||
this.metricsBox.setItem(j, probe);
|
||||
}
|
||||
else {
|
||||
this.metricsBox.pushItem(probe);
|
||||
}
|
||||
j++;
|
||||
}
|
||||
|
||||
this.screen.render();
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Put Log
|
||||
* @method log
|
||||
* @param {} data
|
||||
* @return this
|
||||
*/
|
||||
Dashboard.log = function(type, data) {
|
||||
var that = this;
|
||||
|
||||
if(typeof(this.logLines[data.process.pm_id]) == "undefined"){
|
||||
this.logLines[data.process.pm_id]=[];
|
||||
}
|
||||
// Logs colors
|
||||
switch (type) {
|
||||
case 'PM2':
|
||||
var color = '{blue-fg}';
|
||||
break;
|
||||
case 'out':
|
||||
var color = '{green-fg}';
|
||||
break;
|
||||
case 'err':
|
||||
var color = '{red-fg}';
|
||||
break;
|
||||
default:
|
||||
var color = '{white-fg}';
|
||||
}
|
||||
|
||||
var logs = data.data.split('\n')
|
||||
|
||||
logs.forEach((log) => {
|
||||
if (log.length > 0) {
|
||||
this.logLines[data.process.pm_id].push(color + data.process.name + '{/} > ' + log)
|
||||
|
||||
|
||||
//removing logs if longer than limit
|
||||
let count = 0;
|
||||
let max_count = 0;
|
||||
let leading_process_id = -1;
|
||||
|
||||
for(var process_id in this.logLines){
|
||||
count += this.logLines[process_id].length;
|
||||
if( this.logLines[process_id].length > max_count){
|
||||
leading_process_id = process_id;
|
||||
max_count = this.logLines[process_id].length;
|
||||
}
|
||||
}
|
||||
|
||||
if (count > 200) {
|
||||
this.logLines[leading_process_id].shift()
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
module.exports = Dashboard;
|
||||
|
||||
function timeSince(date) {
|
||||
|
||||
var seconds = Math.floor((new Date() - date) / 1000);
|
||||
|
||||
var interval = Math.floor(seconds / 31536000);
|
||||
|
||||
if (interval > 1) {
|
||||
return interval + 'Y';
|
||||
}
|
||||
interval = Math.floor(seconds / 2592000);
|
||||
if (interval > 1) {
|
||||
return interval + 'M';
|
||||
}
|
||||
interval = Math.floor(seconds / 86400);
|
||||
if (interval > 1) {
|
||||
return interval + 'D';
|
||||
}
|
||||
interval = Math.floor(seconds / 3600);
|
||||
if (interval > 1) {
|
||||
return interval + 'h';
|
||||
}
|
||||
interval = Math.floor(seconds / 60);
|
||||
if (interval > 1) {
|
||||
return interval + 'm';
|
||||
}
|
||||
return Math.floor(seconds) + 's';
|
||||
}
|
||||
|
||||
/* Args :
|
||||
* p : Percent 0 - 100
|
||||
* rgb_ : Array of rgb [255, 255, 255]
|
||||
* Return :
|
||||
* Hexa #FFFFFF
|
||||
*/
|
||||
function gradient(p, rgb_beginning, rgb_end) {
|
||||
|
||||
var w = (p / 100) * 2 - 1;
|
||||
|
||||
var w1 = (w + 1) / 2.0;
|
||||
var w2 = 1 - w1;
|
||||
|
||||
var rgb = [parseInt(rgb_beginning[0] * w1 + rgb_end[0] * w2),
|
||||
parseInt(rgb_beginning[1] * w1 + rgb_end[1] * w2),
|
||||
parseInt(rgb_beginning[2] * w1 + rgb_end[2] * w2)];
|
||||
|
||||
return "#" + ((1 << 24) + (rgb[0] << 16) + (rgb[1] << 8) + rgb[2]).toString(16).slice(1);
|
||||
}
|
||||
Reference in New Issue
Block a user