diff --git a/README.md b/README.md index 8de6e78..9169491 100644 --- a/README.md +++ b/README.md @@ -2,12 +2,12 @@ Works (or should work) with the following servers : -* Tested : - * CSGO (tested) -* Not tested : +* Working : + * CSGO + * GMod +* Not working (I'm planning on adding them in the near future) : * CSS * L4D2 - * GMod (Not working, will fix later) * TF2 * HL2DM @@ -32,39 +32,52 @@ Add the following configuration to Prometheus static configuration : ``` - job_name: 'srcds' static_configs: - - targets: ["::"] + - targets: [":::"] relabel_configs: - source_labels: [__address__] - regex: "(.+):.+:.+" + regex: "(.+):.+:.+:.+" replacement: "$1" target_label: __param_ip - source_labels: [__address__] - regex: ".+:(.+):.+" + regex: ".+:(.+):.+:.+" replacement: "$1" target_label: __param_port - source_labels: [__address__] - regex: ".+:.+:(.+)" + regex: ".+:.+:(.+):.+" replacement: "$1" target_label: __param_password + - source_labels: [__address__] + regex: ".+:.+:.+:(.+)" + replacement: "$1" + target_label: __param_game - source_labels: [__param_target] target_label: instance - target_label: __address__ replacement: : # Real exporter's IP:Port ``` +Values for `game` field : + +| Game | Value | +|:----------:|:-------------:| +| CS:GO | csgo | +| Garry's Mod | gmod | + ## How to access If you want to see what the exporter returns, you can access : - `http://:9591/metrics?ip=&port=&password=` + `http://:9591/metrics?ip=&port=&password=&game=` ## Grafana dashboard Is there a Grafana dashboard available ? Of course! -https://grafana.com/grafana/dashboards/11333 +**CSGO** : https://grafana.com/grafana/dashboards/11333 + +**GMod** : Coming ### Support diff --git a/index.js b/index.js index 65ddeff..e9ad66e 100644 --- a/index.js +++ b/index.js @@ -6,7 +6,34 @@ const Gauge = prometheus.Gauge; const app = express(); -async function getStats(ip, port, password) { +function csgoRequest(response, res){ + status.set((Number(1))); + cpu.set((Number(response[0]))); + netin.set((Number(response[1]))); + netout.set((Number(response[2]))); + uptime.set((Number(response[3]))); + maps.set((Number(response[4]))); + fps.set((Number(response[5]))); + players.set((Number(response[6]))); + svms.set((Number(response[7]))); + varms.set((Number(response[8]))); + tick.set((Number(response[9]))); + res.end(csgoRegistry.metrics()); +} + +function gmodRequest(response, res){ + status.set((Number(1))); + cpu.set((Number(response[0]))); + netin.set((Number(response[1]))); + netout.set((Number(response[2]))); + uptime.set((Number(response[3]))); + maps.set((Number(response[4]))); + fps.set((Number(response[5]))); + players.set((Number(response[6]))); + res.end(gmodRegistry.metrics()); +} + +async function getStats(ip, port, password, game) { let result; try { const client = await connect(ip, port, password, 5000); @@ -20,65 +47,84 @@ async function getStats(ip, port, password) { throw err } } - return result; + if (game === "csgo"){ + var resultArray = result.split(/\r?\n/); + resultArray.pop(); + resultArray.shift(); + var finalArray = resultArray[0].split(/\s+/); + finalArray.shift(); + return finalArray; + } else if (game === "gmod") { + var resultArray = result.split(/\r?\n/); + resultArray.shift(); + var finalArray = resultArray[0].split(/\s+/); + return finalArray; + } } -const status = new Gauge({name: "srcds_status", help: "The server's status, 0 = offline/bad password, 1 = online"}); -const cpu = new Gauge({name: "srcds_cpu", help: "Probably the priority level of the srcds executable from an operating system point of view (0 - No priority, 10 - biggest priority)"}); -const netin = new Gauge({name: "srcds_netin", help: "Incoming bandwidth, in kbps, received by the server"}); -const netout = new Gauge({name: "srcds_netout", help: "Incoming bandwidth, in kbps, sent by the server"}); -const uptime = new Gauge({name: "srcds_uptime", help: "The server's uptime, in minutes"}); -const maps = new Gauge({name: "srcds_maps", help: "The number of maps played on that server since it's start"}); -const fps = new Gauge({name: "srcds_fps", help: "The server's tick (10 fps on idle, 64 fps for 64 ticks server, 128 fps for 128 ticks..)"}); -const players = new Gauge({name: "srcds_players", help: "The number of real players actually connected on the server"}); -const svms = new Gauge({name: "srcds_svms", help: "ms per sim frame"}); -const varms = new Gauge({name: "srcds_varms", help: "ms variance"}); -const tick = new Gauge({name: "srcds_tick", help: "The time in MS per tick"}); +const csgoRegistry = new prometheus.Registry(); +const gmodRegistry = new prometheus.Registry(); + +//Global metrics, used accross all Source gameservers +const status = new Gauge({name: "srcds_status", help: "The server's status, 0 = offline/bad password, 1 = online", registers: [csgoRegistry, gmodRegistry]}); +const cpu = new Gauge({name: "srcds_cpu", help: "Probably the priority level of the srcds executable from an operating system point of view (0 - No priority, 10 - biggest priority)", registers: [csgoRegistry, gmodRegistry]}); +const netin = new Gauge({name: "srcds_netin", help: "Incoming bandwidth, in kbps, received by the server", registers: [csgoRegistry, gmodRegistry]}); +const netout = new Gauge({name: "srcds_netout", help: "Incoming bandwidth, in kbps, sent by the server", registers: [csgoRegistry, gmodRegistry]}); +const uptime = new Gauge({name: "srcds_uptime", help: "The server's uptime, in minutes", registers: [csgoRegistry, gmodRegistry]}); +const maps = new Gauge({name: "srcds_maps", help: "The number of maps played on that server since it's start", registers: [csgoRegistry, gmodRegistry]}); +const fps = new Gauge({name: "srcds_fps", help: "The server's tick (10 fps on idle, 64 fps for 64 ticks server, 128 fps for 128 ticks..)", registers: [csgoRegistry, gmodRegistry]}); +const players = new Gauge({name: "srcds_players", help: "The number of real players actually connected on the server", registers: [csgoRegistry, gmodRegistry]}); + +// CSGO metrics +const svms = new Gauge({name: "srcds_svms", help: "ms per sim frame", registers: [csgoRegistry]}); +const varms = new Gauge({name: "srcds_varms", help: "ms variance", registers: [csgoRegistry]}); +const tick = new Gauge({name: "srcds_tick", help: "The time in MS per tick", registers: [csgoRegistry]}); + +app.get('/', (req, res) => { + res.send('use /metrics?ip=<srcds ip>&port=<srcds port>&password=<rcon password>&game=<game> to get data'); +}); app.get('/metrics', (req, res) => { var ip = req.query.ip; var port = req.query.port; var password = req.query.password; + var game = req.query.game; - if (ip == null || port == null || password == null){ - res.send("Missing parameter, either IP, port or RCON password"); + if (ip == null || port == null || password == null || game == null){ + res.send("Missing parameter, either IP, port, RCON password or game
use /metrics?ip=<srcds ip>&port=<srcds port>&password=<rcon password>&game=<game> to get data"); } else { - const defaultLabels = { server: ip+':'+port }; - prometheus.register.setDefaultLabels(defaultLabels); - getStats(ip, port, password).then(result => { - var resultArray = result.split(/\r?\n/); - resultArray.pop(); - resultArray.shift(); - var finalArray = resultArray[0].split(/\s+/); - finalArray.shift(); + if (game === "csgo" || game === "gmod"){ + getStats(ip, port, password, game, res).then(result => { + if (game === "csgo"){ + const defaultLabels = { server: ip+':'+port, game: game }; + csgoRegistry.setDefaultLabels(defaultLabels); + csgoRequest(result, res); + } else if (game === "gmod"){ + const defaultLabels = { server: ip+':'+port, game: game }; + gmodRegistry.setDefaultLabels(defaultLabels); + gmodRequest(result, res); + } + }).catch(e => { + status.set((Number(0))); + cpu.set((Number(0))); + netin.set((Number(0))); + netout.set((Number(0))); + uptime.set((Number(0))); + maps.set((Number(0))); + fps.set((Number(0))); + players.set((Number(0))); + svms.set((Number(0))); + varms.set((Number(0))); + tick.set((Number(0))); - status.set((Number(1))); - cpu.set((Number(finalArray[0]))); - netin.set((Number(finalArray[1]))); - netout.set((Number(finalArray[2]))); - uptime.set((Number(finalArray[3]))); - maps.set((Number(finalArray[4]))); - fps.set((Number(finalArray[5]))); - players.set((Number(finalArray[6]))); - svms.set((Number(finalArray[7]))); - varms.set((Number(finalArray[8]))); - tick.set((Number(finalArray[9]))); - - res.end(prometheus.register.metrics()); - }).catch(e => { - status.set((Number(0))); - cpu.set((Number(0))); - netin.set((Number(0))); - netout.set((Number(0))); - uptime.set((Number(0))); - maps.set((Number(0))); - fps.set((Number(0))); - players.set((Number(0))); - svms.set((Number(0))); - varms.set((Number(0))); - tick.set((Number(0))); - - res.end(prometheus.register.metrics()); - }) + if (game === "csgo"){ + res.end(csgoRegistry.metrics()); + } else if (game === "gmod"){ + res.end(gmodRegistry.metrics()); + } + }) + } else { + res.send("Incorrect game value, currently supported games are : csgo, gmod"); + } } }); diff --git a/package-lock.json b/package-lock.json index 5357a63..83802b0 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "srcds-exporter", - "version": "0.0.1", + "version": "1.0.0", "lockfileVersion": 1, "requires": true, "dependencies": {