From 6d246ea4bda265f8b8b9e99acb336aeb26c9fa17 Mon Sep 17 00:00:00 2001 From: Vadim Babadzhanyan Date: Thu, 22 Aug 2024 11:47:05 +0300 Subject: [PATCH] Separate port for prometheus metrics Add Prometheus metrics [Feat]: Simple Stats API #1285 --- README.md | 2 +- docker-compose.dev.yml | 1 + docker-compose.yml | 2 ++ src/config.js | 1 + src/lib/Server.js | 44 ++++++++++++++++++++++++++++-------------- 5 files changed, 35 insertions(+), 15 deletions(-) diff --git a/README.md b/README.md index 60114c3f..bdd8d064 100644 --- a/README.md +++ b/README.md @@ -130,7 +130,7 @@ These options can be configured by setting environment variables using `-e KEY=" | `MAX_AGE` | `0` | `1440` | The maximum age of Web UI sessions in minutes. `0` means that the session will exist until the browser is closed. | | `UI_ENABLE_SORT_CLIENTS` | `false` | `true` | Enable UI sort clients by name | | `ENABLE_PROMETHEUS_METRICS` | `true` | `true` | Enable Prometheus metrics `http://0.0.0.0:51821/metrics` and `http://0.0.0.0:51821/metrics/json`| - +| `PROMETHEUS_METRICS_PORT` | `9586` | `9100` | TCP port for Prometheus metrics | > If you change `WG_PORT`, make sure to also change the exposed port. diff --git a/docker-compose.dev.yml b/docker-compose.dev.yml index bd4a836d..32953cbf 100644 --- a/docker-compose.dev.yml +++ b/docker-compose.dev.yml @@ -9,6 +9,7 @@ services: ports: - "51820:51820/udp" - "51821:51821/tcp" + - "9586:9586/tcp" cap_add: - NET_ADMIN - SYS_MODULE diff --git a/docker-compose.yml b/docker-compose.yml index aa138e29..ac1f6507 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -14,6 +14,7 @@ services: # Optional: # - PASSWORD_HASH=$$2y$$10$$hBCoykrB95WSzuV4fafBzOHWKu9sbyVa34GJr8VV5R/pIelfEMYyG (needs double $$, hash of 'foobar123'; see "How_to_generate_an_bcrypt_hash.md" for generate the hash) # - PORT=51821 + # - PROMETHEUS_METRICS_PORT=9586 # - WG_PORT=51820 # - WG_CONFIG_PORT=92820 # - WG_DEFAULT_ADDRESS=10.8.0.x @@ -39,6 +40,7 @@ services: ports: - "51820:51820/udp" - "51821:51821/tcp" + - "9586:9586/tcp" restart: unless-stopped cap_add: - NET_ADMIN diff --git a/src/config.js b/src/config.js index 30bfbc05..d03e4be9 100644 --- a/src/config.js +++ b/src/config.js @@ -42,3 +42,4 @@ module.exports.WG_ENABLE_ONE_TIME_LINKS = process.env.WG_ENABLE_ONE_TIME_LINKS | module.exports.UI_ENABLE_SORT_CLIENTS = process.env.UI_ENABLE_SORT_CLIENTS || 'false'; module.exports.WG_ENABLE_EXPIRES_TIME = process.env.WG_ENABLE_EXPIRES_TIME || 'false'; module.exports.ENABLE_PROMETHEUS_METRICS = process.env.ENABLE_PROMETHEUS_METRICS || 'true'; +module.exports.PROMETHEUS_METRICS_PORT = process.env.PROMETHEUS_METRICS_PORT || '9586'; diff --git a/src/lib/Server.js b/src/lib/Server.js index c50770da..7348f055 100644 --- a/src/lib/Server.js +++ b/src/lib/Server.js @@ -37,6 +37,7 @@ const { UI_ENABLE_SORT_CLIENTS, WG_ENABLE_EXPIRES_TIME, ENABLE_PROMETHEUS_METRICS, + PROMETHEUS_METRICS_PORT, } = require('../config'); const requiresPassword = !!PASSWORD_HASH; @@ -308,20 +309,6 @@ module.exports = class Server { const { expireDate } = await readBody(event); await WireGuard.updateClientExpireDate({ clientId, expireDate }); return { success: true }; - })) - .get('/metrics', defineEventHandler(async (event) => { - setHeader(event, 'Content-Type', 'text/plain'); - if (ENABLE_PROMETHEUS_METRICS === 'true') { - return WireGuard.getMetrics(); - } - return ''; - })) - .get('/metrics/json', defineEventHandler(async (event) => { - setHeader(event, 'Content-Type', 'application/json'); - if (ENABLE_PROMETHEUS_METRICS === 'true') { - return WireGuard.getMetricsJSON(); - } - return ''; })); const safePathJoin = (base, target) => { @@ -398,6 +385,35 @@ module.exports = class Server { createServer(toNodeListener(app)).listen(PORT, WEBUI_HOST); debug(`Listening on http://${WEBUI_HOST}:${PORT}`); + if (ENABLE_PROMETHEUS_METRICS === 'true') { + const appMetrics = createApp(); + this.app_metrics = appMetrics; + appMetrics.use(fromNodeMiddleware(expressSession({ + secret: crypto.randomBytes(256).toString('hex'), + resave: true, + saveUninitialized: true, + }))); + const metricsRouter = createRouter(); + appMetrics.use(metricsRouter); + metricsRouter + .get('/metrics', defineEventHandler(async (event) => { + setHeader(event, 'Content-Type', 'text/plain'); + if (ENABLE_PROMETHEUS_METRICS === 'true') { + return WireGuard.getMetrics(); + } + return ''; + })) + .get('/metrics/json', defineEventHandler(async (event) => { + setHeader(event, 'Content-Type', 'application/json'); + if (ENABLE_PROMETHEUS_METRICS === 'true') { + return WireGuard.getMetricsJSON(); + } + return ''; + })); + createServer(toNodeListener(appMetrics)).listen(PROMETHEUS_METRICS_PORT, WEBUI_HOST); + debug(`Prometheus metrics on http://${WEBUI_HOST}:${PROMETHEUS_METRICS_PORT}/metrics`); + } + cronJobEveryMinute(); }