Adding support for GMod servers, updating README.md file with new requirements

This commit is contained in:
Corentin Closs
2020-01-20 16:43:23 +01:00
parent 5d09bd2058
commit 714dfbe3bc
3 changed files with 121 additions and 62 deletions

View File

@@ -2,12 +2,12 @@
Works (or should work) with the following servers : Works (or should work) with the following servers :
* Tested : * Working :
* CSGO (tested) * CSGO
* Not tested : * GMod
* Not working (I'm planning on adding them in the near future) :
* CSS * CSS
* L4D2 * L4D2
* GMod (Not working, will fix later)
* TF2 * TF2
* HL2DM * HL2DM
@@ -32,39 +32,52 @@ Add the following configuration to Prometheus static configuration :
``` ```
- job_name: 'srcds' - job_name: 'srcds'
static_configs: static_configs:
- targets: ["<ip>:<port>:<rconpassword>"] - targets: ["<ip>:<port>:<rconpassword>:<game>"]
relabel_configs: relabel_configs:
- source_labels: [__address__] - source_labels: [__address__]
regex: "(.+):.+:.+" regex: "(.+):.+:.+:.+"
replacement: "$1" replacement: "$1"
target_label: __param_ip target_label: __param_ip
- source_labels: [__address__] - source_labels: [__address__]
regex: ".+:(.+):.+" regex: ".+:(.+):.+:.+"
replacement: "$1" replacement: "$1"
target_label: __param_port target_label: __param_port
- source_labels: [__address__] - source_labels: [__address__]
regex: ".+:.+:(.+)" regex: ".+:.+:(.+):.+"
replacement: "$1" replacement: "$1"
target_label: __param_password target_label: __param_password
- source_labels: [__address__]
regex: ".+:.+:.+:(.+)"
replacement: "$1"
target_label: __param_game
- source_labels: [__param_target] - source_labels: [__param_target]
target_label: instance target_label: instance
- target_label: __address__ - target_label: __address__
replacement: <IP>:<port> # Real exporter's IP:Port replacement: <IP>:<port> # Real exporter's IP:Port
``` ```
Values for `game` field :
| Game | Value |
|:----------:|:-------------:|
| CS:GO | csgo |
| Garry's Mod | gmod |
## How to access ## How to access
If you want to see what the exporter returns, you can access : If you want to see what the exporter returns, you can access :
`http://<ip>:9591/metrics?ip=<srcds ip>&port=<srcds port>&password=<rcon password>` `http://<ip>:9591/metrics?ip=<srcds ip>&port=<srcds port>&password=<rcon password>&game=<game>`
## Grafana dashboard ## Grafana dashboard
Is there a Grafana dashboard available ? Of course! Is there a Grafana dashboard available ? Of course!
https://grafana.com/grafana/dashboards/11333 **CSGO** : https://grafana.com/grafana/dashboards/11333
**GMod** : Coming
### Support ### Support

148
index.js
View File

@@ -6,7 +6,34 @@ const Gauge = prometheus.Gauge;
const app = express(); 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; let result;
try { try {
const client = await connect(ip, port, password, 5000); const client = await connect(ip, port, password, 5000);
@@ -20,65 +47,84 @@ async function getStats(ip, port, password) {
throw err 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 csgoRegistry = new prometheus.Registry();
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 gmodRegistry = new prometheus.Registry();
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"}); //Global metrics, used accross all Source gameservers
const uptime = new Gauge({name: "srcds_uptime", help: "The server's uptime, in minutes"}); const status = new Gauge({name: "srcds_status", help: "The server's status, 0 = offline/bad password, 1 = online", registers: [csgoRegistry, gmodRegistry]});
const maps = new Gauge({name: "srcds_maps", help: "The number of maps played on that server since it's start"}); 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 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 netin = new Gauge({name: "srcds_netin", help: "Incoming bandwidth, in kbps, received by the server", registers: [csgoRegistry, gmodRegistry]});
const players = new Gauge({name: "srcds_players", help: "The number of real players actually connected on the server"}); const netout = new Gauge({name: "srcds_netout", help: "Incoming bandwidth, in kbps, sent by the server", registers: [csgoRegistry, gmodRegistry]});
const svms = new Gauge({name: "srcds_svms", help: "ms per sim frame"}); const uptime = new Gauge({name: "srcds_uptime", help: "The server's uptime, in minutes", registers: [csgoRegistry, gmodRegistry]});
const varms = new Gauge({name: "srcds_varms", help: "ms variance"}); const maps = new Gauge({name: "srcds_maps", help: "The number of maps played on that server since it's start", registers: [csgoRegistry, gmodRegistry]});
const tick = new Gauge({name: "srcds_tick", help: "The time in MS per tick"}); 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=&lt;srcds ip&gt;&port=&lt;srcds port&gt;&password=&lt;rcon password&gt;&game=&lt;game&gt; to get data');
});
app.get('/metrics', (req, res) => { app.get('/metrics', (req, res) => {
var ip = req.query.ip; var ip = req.query.ip;
var port = req.query.port; var port = req.query.port;
var password = req.query.password; var password = req.query.password;
var game = req.query.game;
if (ip == null || port == null || password == null){ if (ip == null || port == null || password == null || game == null){
res.send("Missing parameter, either IP, port or RCON password"); res.send("Missing parameter, either IP, port, RCON password or game<br />use /metrics?ip=&lt;srcds ip&gt;&port=&lt;srcds port&gt;&password=&lt;rcon password&gt;&game=&lt;game&gt; to get data");
} else { } else {
const defaultLabels = { server: ip+':'+port }; if (game === "csgo" || game === "gmod"){
prometheus.register.setDefaultLabels(defaultLabels); getStats(ip, port, password, game, res).then(result => {
getStats(ip, port, password).then(result => { if (game === "csgo"){
var resultArray = result.split(/\r?\n/); const defaultLabels = { server: ip+':'+port, game: game };
resultArray.pop(); csgoRegistry.setDefaultLabels(defaultLabels);
resultArray.shift(); csgoRequest(result, res);
var finalArray = resultArray[0].split(/\s+/); } else if (game === "gmod"){
finalArray.shift(); 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))); if (game === "csgo"){
cpu.set((Number(finalArray[0]))); res.end(csgoRegistry.metrics());
netin.set((Number(finalArray[1]))); } else if (game === "gmod"){
netout.set((Number(finalArray[2]))); res.end(gmodRegistry.metrics());
uptime.set((Number(finalArray[3]))); }
maps.set((Number(finalArray[4]))); })
fps.set((Number(finalArray[5]))); } else {
players.set((Number(finalArray[6]))); res.send("Incorrect game value, currently supported games are : csgo, gmod");
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());
})
} }
}); });

2
package-lock.json generated
View File

@@ -1,6 +1,6 @@
{ {
"name": "srcds-exporter", "name": "srcds-exporter",
"version": "0.0.1", "version": "1.0.0",
"lockfileVersion": 1, "lockfileVersion": 1,
"requires": true, "requires": true,
"dependencies": { "dependencies": {