factorio-rcon-prometheus-exporter
Version:
A Prometheus exporter that connects to a Factorio server via RCON and exports metrics.
137 lines (133 loc) • 4.04 kB
JavaScript
var __create = Object.create;
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __getProtoOf = Object.getPrototypeOf;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __copyProps = (to, from, except, desc) => {
if (from && typeof from === "object" || typeof from === "function") {
for (let key of __getOwnPropNames(from))
if (!__hasOwnProp.call(to, key) && key !== except)
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
}
return to;
};
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
// If the importer is in node compatibility mode or this is not an ESM
// file that has been converted to a CommonJS file using a Babel-
// compatible transform (i.e. "__esModule" has not been set), then set
// "default" to the CommonJS "module.exports" for node compatibility.
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
mod
));
// bin/http.ts
var import_express = __toESM(require("express"));
// src/rcon.ts
var import_promises = require("node:fs/promises");
var import_node_path = require("node:path");
var import_rcon_client = require("rcon-client");
var FactorioRcon = class extends import_rcon_client.Rcon {
connected = false;
metricsScript;
constructor(host, port, password) {
super({
host,
port,
password
});
this.on("connect", this.onConnect);
this.on("end", this.onDisconnect);
this.on("error", this.onError);
}
getHostname() {
return this.config.host + ":" + this.config.port;
}
async runScript(script) {
if (!this.connected) await this.connect();
const response = await this.send("/sc " + script);
return response;
}
async getMetrics() {
if (!this.connected) await this.connect();
if (!this.metricsScript) {
const scriptPath = (0, import_node_path.join)(__dirname, "metrics.lua");
const originalScript = await (0, import_promises.readFile)(scriptPath, "utf-8");
this.metricsScript = originalScript.replaceAll(/process\.env\.(\w+)/g, (substr, environmentVariable) => {
return JSON.stringify(process.env[environmentVariable] ?? substr);
});
}
return await this.runScript(this.metricsScript);
}
onConnect = () => {
this.connected = true;
};
onDisconnect = () => {
this.connected = false;
};
onError = (error) => {
console.log(error);
};
};
// bin/http.ts
var {
/**
* Host to bind the HTTP server to
*/
HOST = "0.0.0.0",
/**
* Port for the HTTP server
*/
PORT = "9772",
/**
* IP or Hostname for the RCON server
*/
RCON_HOST = "localhost",
/**
* RCON port
*/
RCON_PORT = "27015",
/**
* RCON password
*/
RCON_PASSWORD = ""
} = process.env;
var app = (0, import_express.default)();
var rcon = new FactorioRcon(RCON_HOST, parseInt(RCON_PORT, 10), RCON_PASSWORD);
app.get("/", (_req, res) => {
res.send(`<html lang="en">
<head>
<title>Factorio RCON Prometheus Exporter</title>
</head>
<body>
<h1>Factorio RCON Prometheus Exporter</h1>
<p><a href="/metrics">Metrics</a></p>
</body>
</html>
`);
});
app.get("/metrics", (_req, res) => {
rcon.getMetrics().then((metrics) => {
res.set("Content-Disposition", "inline");
res.set("Content-Type", "text/plain; version=0.0.4");
res.end(metrics);
}).catch((err) => {
console.error(err);
if (err instanceof Error) {
res.status(500).end(`# ${err.message}`);
} else {
res.status(500).end(`# ${String(err)}`);
}
});
});
app.listen(parseInt(PORT, 10), HOST, () => {
console.log(`Server running at http://${HOST}:${PORT}/`);
});
process.on("SIGINT", () => {
process.exit();
});
process.on("SIGTERM", () => {
process.exit();
});
//# sourceMappingURL=http.js.map
;