diff --git a/lib/server.js b/lib/server.js index 7c785a0e..32f02915 100644 --- a/lib/server.js +++ b/lib/server.js @@ -1,10 +1,13 @@ var _ = require('lodash') var events = require('events') +var filesize = require('filesize') var Gamedig = require('gamedig') +var usage = require('pidusage') var slugify = require('slugify') var ArmaServer = require('arma-server') +var processesInterval = 2000 var queryInterval = 5000 var queryTypes = { arma1: 'arma', @@ -66,6 +69,49 @@ Server.prototype.update = function (options) { this.port = parseInt(this.port, 10) // If port is a string then gamedig fails } +function processStats (stats) { + return { + cpu: stats.cpu, + cpuFormatted: stats.cpu.toFixed(0) + ' %', + memory: stats.memory, + memoryFormatted: filesize(stats.memory) + } +} + +Server.prototype.queryProcesses = function () { + if (!this.instance) { + return + } + + var self = this + var headlessPids = this.headlessClientInstances.map(function (instance) { + return instance.pid + }) + var serverPid = self.instance.pid + var pids = [serverPid].concat(headlessPids) + usage(pids, function (err, stats) { + if (!self.instance) { + return + } + + if (err) { + self.processes = null + } else { + self.processes = pids.map(function (pid, idx) { + var pidStats = processStats(stats[pid]) + if (pid === serverPid) { + pidStats.name = 'Server' + } else { + pidStats.name = 'Headless ' + idx // First headless at idx 1 + } + return pidStats + }) + } + + self.emit('state') + }) +} + Server.prototype.queryStatus = function () { if (!this.instance) { return @@ -165,8 +211,10 @@ Server.prototype.start = function () { var self = this instance.on('close', function (code) { + clearInterval(self.queryProcessesInterval) clearInterval(self.queryStatusInterval) self.state = null + self.processes = null self.pid = null self.instance = null @@ -178,6 +226,9 @@ Server.prototype.start = function () { this.pid = instance.pid this.instance = instance this.headlessClientInstances = [] + this.queryProcessesInterval = setInterval(function () { + self.queryProcesses() + }, processesInterval) this.queryStatusInterval = setInterval(function () { self.queryStatus() }, queryInterval) @@ -274,6 +325,7 @@ Server.prototype.toJSON = function () { persistent: this.persistent, pid: this.pid, port: this.port, + processes: this.processes, state: this.state, title: this.title, von: this.von, diff --git a/package.json b/package.json index f4f294bc..b615982d 100644 --- a/package.json +++ b/package.json @@ -38,6 +38,7 @@ "lodash": "^4.17.10", "morgan": "^1.8.1", "multer": "^1.3.0", + "pidusage": "2.0.17", "raw-loader": "^0.5.1", "serve-static": "^1.12.1", "slugify": "^1.1.0", diff --git a/public/js/app/models/server.js b/public/js/app/models/server.js index 7d13ddaa..478fb199 100644 --- a/public/js/app/models/server.js +++ b/public/js/app/models/server.js @@ -18,6 +18,7 @@ module.exports = Backbone.Model.extend({ password: '', persistent: false, port: 2302, + processes: null, state: null, title: '', von: false, diff --git a/public/js/tpl/servers/info.html b/public/js/tpl/servers/info.html index aa566eed..fe5feeb2 100644 --- a/public/js/tpl/servers/info.html +++ b/public/js/tpl/servers/info.html @@ -39,6 +39,36 @@ +<% if (processes) { %> +
+ +
+ <% processes.map(function (process) { %> +
+ +
+

<%= process.name %>

+
+
+ +
+ +
+

<%= process.cpuFormatted %>

+
+
+ +
+ +
+

<%= process.memoryFormatted %>

+
+
+ <% }) %> +
+
+<% } %> + <% if (state) { %>
diff --git a/public/js/tpl/servers/list.html b/public/js/tpl/servers/list.html index fd4f04ed..bd905bc6 100644 --- a/public/js/tpl/servers/list.html +++ b/public/js/tpl/servers/list.html @@ -1,9 +1,12 @@ - + + + + diff --git a/public/js/tpl/servers/list_item.html b/public/js/tpl/servers/list_item.html index dd374fc0..956e00fd 100644 --- a/public/js/tpl/servers/list_item.html +++ b/public/js/tpl/servers/list_item.html @@ -21,13 +21,21 @@ Start <% } %> - - + + + <% } %> +
StatusStatus Port TitleCPURAM
<%-port%> <%-title%> + <% if (processes && processes[0]) { %> + <%= processes[0].cpuFormatted %> + <% } %> + + <% if (processes && processes[0]) { %> + <%= processes[0].memoryFormatted %>