diff --git a/index.js b/index.js index e9ad66e..4befd7d 100644 --- a/index.js +++ b/index.js @@ -6,7 +6,62 @@ const Gauge = prometheus.Gauge; const app = express(); -function csgoRequest(response, res){ +async function rconCommand(client, command) { + try { + return client.command(command); + } catch (err) { + if (err instanceof TimeoutError) { + console.error('request timed out') + } else { + throw err + } + } +} + +async function getMetamod(client) { + return rconCommand(client, 'meta'); +} + +function metamodRequest(response) { + if (response) { + isEnabled = isValidResponse(response); + metamodEnabledGauge.set(isEnabled ? Number(0) : Number(1)); + } else { + metamodEnabledGauge.set((Number(-1))) + } +} + +async function getSourcemod(client) { + return rconCommand(client, 'sm'); +} + +function sourcemodRequest(response) { + if (response) { + isEnabled = isValidResponse(response); + sourcemodEnabledGauge.set(isEnabled ? Number(0) : Number(1)); + } else { + sourcemodEnabledGauge.set((Number(-1))) + } +} + +async function getSourcepython(client) { + return rconCommand(client, 'sp'); +} + +function sourcepythonRequest(response) { + if (response) { + isEnabled = isValidResponse(response); + sourcepythonEnabledGauge.set(isEnabled ? Number(0) : Number(1)); + } else { + sourcepythonEnabledGauge.set(Number(-1)) + } +} + +function isValidResponse(response) { + return !response.includes('Unknown'); +} + +function csgoRequest(response){ status.set((Number(1))); cpu.set((Number(response[0]))); netin.set((Number(response[1]))); @@ -18,10 +73,9 @@ function csgoRequest(response, res){ svms.set((Number(response[7]))); varms.set((Number(response[8]))); tick.set((Number(response[9]))); - res.end(csgoRegistry.metrics()); } -function gmodRequest(response, res){ +function gmodRequest(response){ status.set((Number(1))); cpu.set((Number(response[0]))); netin.set((Number(response[1]))); @@ -30,32 +84,19 @@ function gmodRequest(response, res){ 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); - const stats = await client.command('stats'); - await client.disconnect(); - result = stats; - } catch (err) { - if (err instanceof TimeoutError) { - console.error('request timed out') - } else { - throw err - } - } +async function getStats(client, game) { + const stats = await rconCommand(client, 'stats'); if (game === "csgo"){ - var resultArray = result.split(/\r?\n/); + var resultArray = stats.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/); + var resultArray = stats.split(/\r?\n/); resultArray.shift(); var finalArray = resultArray[0].split(/\s+/); return finalArray; @@ -79,52 +120,87 @@ const svms = new Gauge({name: "srcds_svms", help: "ms per sim frame", registers: 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]}); +const sourcemodEnabledGauge = new Gauge({name: "srcds_sourcemod_enabled", help: "Is sourcemod enabled", registers: [csgoRegistry]}); +const metamodEnabledGauge = new Gauge({name: "srcds_metamod_enabled", help: "Is metamod enabled", registers: [csgoRegistry]}); +const sourcepythonEnabledGauge = new Gauge({name: "srcds_sourcepython_enabled", help: "Is sourcepython enabled", registers: [csgoRegistry]}); + app.get('/', (req, res) => { - res.send('use /metrics?ip=<srcds ip>&port=<srcds port>&password=<rcon password>&game=<game> to get data'); + res.send('use /metrics?ip=<srcds ip>&port=<srcds port>&password=<rcon password>&game=<game>&sm=<boolean>&meta=<boolean>sp=<boolean> to get data'); }); -app.get('/metrics', (req, res) => { +app.get('/metrics', async (req, res) => { var ip = req.query.ip; var port = req.query.port; var password = req.query.password; var game = req.query.game; - + let metamod = req.query.metamod || false; + let sourcemod = req.query.sourcemod || false; + let sourcepython = req.query.sourcepython || false; 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 { - 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); + res.send("Missing parameter, either IP, port, RCON password or game
use /metrics?ip=<srcds ip>&port=<srcds port>&password=<rcon password>&game=<game>&sm=&meta=sp= to get data"); + return; + } + if (game === "csgo" || game === "gmod"){ + const client = await connect(ip, port, password, 5000); + const statsResponse = await getStats(client, game) + try { + if (game === "csgo"){ + const defaultLabels = { server: ip+':'+port, game: game}; + csgoRegistry.setDefaultLabels(defaultLabels); + + csgoRequest(statsResponse); + if (metamod) { + const metamodResponse = await getMetamod(client); + metamodRequest(metamodResponse); + } else { + metamodRequest(null); } - }).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))); + + if (sourcemod) { + const sourcemodResponse = await getSourcemod(client); + sourcemodRequest(sourcemodResponse); + } else { + sourcemodRequest(null); + } + if (sourcepython) { + const sourcepythonResponse = await getSourcepython(client); + sourcepythonRequest(sourcepythonResponse); + } else { + sourcepythonRequest(null); + } + + res.end(csgoRegistry.metrics()); + } else if (game === "gmod"){ + const defaultLabels = { server: ip+':'+port, game: game }; + gmodRegistry.setDefaultLabels(defaultLabels); + gmodRequest(result, res); + res.end(gmodRegistry.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))); + metamodEnabledGauge.set((Number(-1))); + sourcemodEnabledGauge.set((Number(-1))); + sourcepythonEnabledGauge.set((Number(-1))); - 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"); + if (game === "csgo"){ + res.end(csgoRegistry.metrics()); + } else if (game === "gmod"){ + res.end(gmodRegistry.metrics()); + } } + await client.disconnect(); + } else { + res.send("Incorrect game value, currently supported games are : csgo, gmod"); } });