From e908c5069b891d550a0334fe2efe04c9a127884f Mon Sep 17 00:00:00 2001 From: Hornwitser Date: Mon, 6 Apr 2020 18:56:21 +0200 Subject: [PATCH] Add autosave tracking and statistics Detect when autosaves are made and track the size in a Prometheus gague. --- CHANGELOG.md | 1 + lib/factorio/server.js | 29 +++++++++++++++++++++++++++++ slave.js | 17 +++++++++++++++++ test/lib/factorio/lines.js | 22 ++++++++++++++++++++++ 4 files changed, 69 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 19f2d8c4..59365897 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -38,6 +38,7 @@ Version 2.0.0 - Added WebSocket usage statistics. - Added commands sent statistic. - Added Factorio server CPU and memory usage statistic. +- Added Factorio autosave size statistic. ### Changes diff --git a/lib/factorio/server.js b/lib/factorio/server.js index e8414fac..8f7a6540 100644 --- a/lib/factorio/server.js +++ b/lib/factorio/server.js @@ -349,6 +349,18 @@ const outputHeuristics = [ } }, + // Message indicating the server has started an autosave + { + filter: { + type: 'log', + message: /^Saving to _autosave\d+ \((non-)?blocking\)\.$/, + }, + action: function(output) { + let name = /^Saving to (_autosave\d+) /.exec(output.message)[1]; + this.emit('_autosave', name); + }, + }, + // Message indicating the server has finished saving { filter: { @@ -419,6 +431,8 @@ const outputHeuristics = [ * output - invoked with parsed output from Factorio * rcon-ready - invoked when the RCON client has connected * game-ready - invoked when the server is finished starting up + * autosave-start - invoked when the server starts an autosave + * autosave-fnished - invoked when the autosave finished * exit - invoked when the sterver has exited */ class FactorioServer extends events.EventEmitter { @@ -454,6 +468,20 @@ class FactorioServer extends events.EventEmitter { this._stdout = new LineSplitter((line) => { this._handleOutput(line, 'stdout'); }); this._stderr = new LineSplitter((line) => { this._handleOutput(line, 'stderr'); }); + + // Track autosaving + this._runningAutosave = null; + this.on("_autosave", function(name) { + this.emit("autosave-start", name); + this._runningAutosave = name; + }) + + this.on("_saved", function() { + if (this._runningAutosave) { + this.emit("autosave-finished", this._runningAutosave); + this._runningAutosave = null; + } + }) } _check(expectedStates) { @@ -645,6 +673,7 @@ class FactorioServer extends events.EventEmitter { this._rconReady = false; this._gameReady = false; this._unexpected = []; + this._runningAutosave = null; this.emit("exit"); }); diff --git a/slave.js b/slave.js index 1d34b0e3..ce9adfc3 100644 --- a/slave.js +++ b/slave.js @@ -35,6 +35,12 @@ const instanceFactorioMemoryUsage = new prometheus.Gauge( { labels: ["instance_id"] } ); +const instanceFactorioAutosaveSize = new prometheus.Gauge( + "clusterio_instance_factorio_autosave_bytes", + "Size of Factorio server autosave in bytes.", + { labels: ["instance_id"] } +); + /** * Keeps track of the runtime parameters of an instance */ @@ -78,6 +84,17 @@ class Instance extends link.Link{ this.server.on("error", err => { console.log(`Error in instance ${this.name}:`, err); }); + + this.server.on("autosave-finished", name => { + this._autosave(name).catch(err => { + console.error("Error handling autosave-finished:", err); + }); + }); + } + + async _autosave(name) { + let stat = await fs.stat(this.path("saves", `${name}.zip`)); + instanceFactorioAutosaveSize.labels(String(this.config.get("instance.id"))).set(stat.size); } notifyExit() { diff --git a/test/lib/factorio/lines.js b/test/lib/factorio/lines.js index eb6159ba..2e316ac0 100644 --- a/test/lib/factorio/lines.js +++ b/test/lib/factorio/lines.js @@ -109,6 +109,28 @@ let testLines = new Map([ message: "Error while running event level::on_nth_tick(1)", } ], + [ + "4802.763 Info AppManager.cpp:287: Saving to _autosave4 (blocking).", + { + format: "seconds", + time: "4802.763", + type: "log", + level: "Info", + file: "AppManager.cpp:287", + message: "Saving to _autosave4 (blocking).", + } + ], + [ + "4202.780 Info AppManagerStates.cpp:1802: Saving finished", + { + format: "seconds", + time: "4202.780", + type: "log", + level: "Info", + file: "AppManagerStates.cpp:1802", + message: "Saving finished", + } + ], ]) module.exports = {