diff --git a/stats.js b/stats.js index 02fc6b4..095e103 100644 --- a/stats.js +++ b/stats.js @@ -29,6 +29,16 @@ var getBytes = function(s) { return bytes; }; +var getDatetime = function (number, units) { + var datetime = moment(); + if (number) { + return datetime.subtract(number, units); + } + // round to whole minutes + return datetime.format('YYYY-MM-DD HH:mm:00'); +}; + + var getContainers = function() { var containers = {}; var out; @@ -86,16 +96,31 @@ var getCreateContainerId = function(name, cid, cb) { }; var writeContainerStats = function(cid, container, now) { - getCreateContainerId(container.name, cid, function(id) { - var stm = db.prepare("INSERT INTO stats (id, ts, cpu, mem, net_in, net_out, block_in, block_out) " + - "VALUES (?, ?, ?, ?, ?, ?, ?, ?)"); - stm.run(id, now, container.cpu, container.mem, container.net.in, container.net.out, container.block.in, container.block.out); - stm.finalize(); + getCreateContainerId(container.name, cid, function (id) { + // get the last stats + db.get('SELECT net_in, net_out, block_in, block_out FROM stats WHERE id = ? ORDER BY ts DESC LIMIT 1', id, function (err, row) { + if (err) { + console.error(err); + } + + if (row) { + // make values relative + if (container.net.in > 0) container.net.in -= row.net_in; + if (container.net.out > 0) container.net.out -= row.net_out; + if (container.block.in > 0) container.block.in -= row.block_in; + if (container.block.out > 0) container.block.out -= row.block_out; + } + + var stm = db.prepare("INSERT INTO stats (id, ts, cpu, mem, net_in, net_out, block_in, block_out) " + + "VALUES (?, ?, ?, ?, ?, ?, ?, ?)"); + stm.run(id, now, container.cpu, container.mem, container.net.in, container.net.out, container.block.in, container.block.out); + stm.finalize(); + }); }); }; var writeStats = function(containers) { - var now = moment().format('YYYY-MM-DD HH:mm:ss'); + var now = getDatetime(); for (var id in containers) { var container = containers[id]; writeContainerStats(id, container, now); @@ -110,6 +135,7 @@ var main = function() { }; var cleanupContainers = function (activeContainers) { + // get list of active containers var list = []; for (var key in activeContainers) { @@ -125,33 +151,38 @@ var cleanupContainers = function (activeContainers) { // ids var ids = list.join(','); - // delete all non-active containers - var sql = `DELETE FROM containers WHERE name NOT IN (${ids})`; - db.all(sql, function (err, rows) { - handleError(err); - // delete stats on these containers - db.all('DELETE FROM stats WHERE ID NOT in (SELECT id FROM containers)', function (err, rows) { - handleError(err); - // cleanup old stats - var old = moment().subtract(CLEANUP_DAYS, 'days').format('YYYY-MM-DD HH:mm:ss'); - db.all('DELETE FROM stats WHERE ts < ?', old, function (err, result) { - handleError(err); - }); - }); - }); -}; + // vars + var cleanupDays = moment().subtract(CLEANUP_DAYS, 'days').format(); + var CleanupWeekly = moment().sub -var handleError = function (error) { - if (error) { - console.error(error); + // cleanup queries + var cleanupQueries = [ + `DELETE FROM containers WHERE name NOT IN (${ids})`, + 'DELETE FROM stats WHERE ID NOT in (SELECT id FROM containers)', + `DELETE FROM stats WHERE ts < '${getDatetime(CLEANUP_DAYS, 'days')}'`, + `DELETE FROM stats WHERE ts < '${getDatetime(1, 'day')}' and strftime('%M', ts) != '00'`, // keep hourly records after one day + `DELETE FROM stats WHERE ts < '${getDatetime(1, 'week')}' and strftime('%H', ts) != '00'`, // keep daily records after one week + `DELETE FROM stats WHERE ts < '${getDatetime(1, 'year')}' and strftime('%d', ts) != '00'`, // keep daily records after one month + ]; + + for (var query of cleanupQueries) { + db.all(query, function (err, rows) { + if (err) { + console.error(err); + } + }); } }; - db.run("PRAGMA journal_mode=WAL"); +// create tables db.run("CREATE TABLE IF NOT EXISTS containers ( " + "id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, " + - "name TEXT NOT NULL)"); + "name TEXT NOT NULL)", + function (err, result) { + db.run("CREATE INDEX IF NOT EXISTS containers_name ON containers(name)"); + } +); db.run("CREATE TABLE IF NOT EXISTS stats ( " + "id INTEGER NOT NULL, " + @@ -161,6 +192,12 @@ db.run("CREATE TABLE IF NOT EXISTS stats ( " + "net_in REAL NOT NULL, " + "net_out REAL NOT NULL, " + "block_in REAL NOT NULL, " + - "block_out REAL NOT NULL)"); + "block_out REAL NOT NULL)", + function (err, result) { + db.run("CREATE INDEX IF NOT EXISTS stats_ts ON stats(ts)"); + db.run("CREATE INDEX IF NOT EXISTS stats_id ON stats(id, ts)"); + } +); + setTimeout(main, INTERVAL * 1000);