diff --git a/acp.js b/acp.js index d1424a0e..12ad6e9e 100644 --- a/acp.js +++ b/acp.js @@ -160,6 +160,16 @@ module.exports = function (Server) { ActionLog.clearOne(data); ActionLog.record(user.ip, user.name, "acp-actionlog-clear-one", data); }); + + user.socket.on("acp-view-stats", function () { + var db = Server.db.getConnection(); + if(!db) + return; + var query = "SELECT * FROM stats WHERE 1"; + var results = db.querySync(query); + if(results) + user.socket.emit("acp-view-stats", results.fetchAllSync()); + }); } } } diff --git a/database.js b/database.js index 4c737b48..3901a3d9 100644 --- a/database.js +++ b/database.js @@ -201,6 +201,19 @@ function init() { if(!results) { Logger.errlog.log("! Failed to create actionlog table"); } + + // Create stats table + query = ["CREATE TABLE IF NOT EXISTS `stats` (", + "`time` BIGINT NOT NULL,", + "`usercount` INT NOT NULL,", + "`chancount` INT NOT NULL,", + "`mem` INT NOT NULL,", + "PRIMARY KEY (`time`))", + "ENGINE = MyISAM;"].join(""); + results = db.querySync(query); + if(!results) { + Logger.errlog.log("! Failed to create stats table"); + } } /* REGION Global Bans */ diff --git a/server.js b/server.js index 63c208b1..315b9554 100644 --- a/server.js +++ b/server.js @@ -62,6 +62,7 @@ var Server = { //for(var i in chan) // delete chan[i]; }, + stats: null, app: null, io: null, httpserv: null, @@ -147,6 +148,9 @@ var Server = { // init ACP this.acp = require("./acp")(this); + + // init stats + this.stats = require("./stats")(this); }, shutdown: function () { Logger.syslog.log("Unloading channels"); diff --git a/www/acp.html b/www/acp.html index ae15855f..04063d84 100644 --- a/www/acp.html +++ b/www/acp.html @@ -44,6 +44,7 @@
  • Users
  • Loaded Channels
  • Action Log
  • +
  • Server Stats
  • @@ -219,6 +220,14 @@ +
    +

    User Count

    + +

    Channel Count

    + +

    Memory Usage (MB)

    + +
    @@ -240,6 +249,7 @@ + diff --git a/www/assets/js/acp.js b/www/assets/js/acp.js index 81236773..fd3c983d 100644 --- a/www/assets/js/acp.js +++ b/www/assets/js/acp.js @@ -169,6 +169,11 @@ $("#actionlog_time").click(function() { tableResort($("#actionlog table"), "time"); }); +menuHandler("#show_stats", "#stats"); +$("#show_stats").click(function () { + socket.emit("acp-view-stats"); +}); + function reverseLog() { $("#log").text($("#log").text().split("\n").reverse().join("\n")); } @@ -492,6 +497,72 @@ function setupCallbacks() { $("").appendTo(tr); }); + socket.on("acp-view-stats", function (stats) { + var labels = []; + var ucounts = []; + var ccounts = []; + var mcounts = []; + var lastdate = ""; + stats.forEach(function (s) { + var d = new Date(parseInt(s.time)); + var t = ""; + if(d.toDateString() !== lastdate) { + lastdate = d.toDateString(); + t = d.getFullYear()+"-"+(d.getMonth()+1)+"-"+d.getDate(); + t += " " + d.toTimeString().split(" ")[0]; + } + else { + t = d.toTimeString().split(" ")[0]; + } + labels.push(t); + ucounts.push(s.usercount); + ccounts.push(s.chancount); + mcounts.push(s.mem / 1000000); + }); + + var user_data = { + labels: labels, + datasets: [ + { + fillColor: "rgba(151, 187, 205, 0.5)", + strokeColor: "rgba(151, 187, 205, 1)", + pointColor: "rgba(151, 187, 205, 1)", + pointStrokeColor: "#fff", + data: ucounts + } + ] + }; + + var chan_data = { + labels: labels, + datasets: [ + { + fillColor: "rgba(151, 187, 205, 0.5)", + strokeColor: "rgba(151, 187, 205, 1)", + pointColor: "rgba(151, 187, 205, 1)", + pointStrokeColor: "#fff", + data: ccounts + } + ] + }; + + var mem_data = { + labels: labels, + datasets: [ + { + fillColor: "rgba(151, 187, 205, 0.5)", + strokeColor: "rgba(151, 187, 205, 1)", + pointColor: "rgba(151, 187, 205, 1)", + pointStrokeColor: "#fff", + data: mcounts + } + ] + }; + + new Chart($("#stat_users")[0].getContext("2d")).Line(user_data); + new Chart($("#stat_channels")[0].getContext("2d")).Line(chan_data); + new Chart($("#stat_mem")[0].getContext("2d")).Line(mem_data); + }); } /* cookie util */