From 50cdcd09990c57d43247fca902eeb7483db5d49d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tam=C3=A1s=20G=C3=A1lffy?= Date: Sat, 8 Jul 2023 23:23:36 +0200 Subject: [PATCH 1/4] Add relay metrics --- src/relay/udp.relay.cleanup.mjs | 13 +++++++-- src/relay/udp.relay.handler.mjs | 48 +++++++++++++++++++++++++++++++++ 2 files changed, 59 insertions(+), 2 deletions(-) diff --git a/src/relay/udp.relay.cleanup.mjs b/src/relay/udp.relay.cleanup.mjs index 452f778..a4c1d54 100644 --- a/src/relay/udp.relay.cleanup.mjs +++ b/src/relay/udp.relay.cleanup.mjs @@ -2,6 +2,14 @@ import { UDPRelayHandler } from './udp.relay.handler.mjs' /* eslint-enable */ import { time } from '../utils.mjs' +import * as prometheus from 'prom-client' +import { metricsRegistry } from '../metrics/metrics.registry.mjs' + +const expiredRelayCounter = new prometheus.Counter({ + name: 'noray_relay_expired', + help: 'Count of expired relays', + registers: [metricsRegistry] +}) /** * Remove idle relays. @@ -14,7 +22,8 @@ export function cleanupUdpRelayTable (relayHandler, timeout) { relayHandler.relayTable .map(relay => [relay, Math.max(relay.lastSent, relay.lastReceived)]) .filter(([_, lastTraffic]) => lastTraffic <= timeCutoff) - .forEach(([relay, _]) => + .forEach(([relay, _]) => { relayHandler.freeRelay(relay) - ) + expiredRelayCounter.inc() + }) } diff --git a/src/relay/udp.relay.handler.mjs b/src/relay/udp.relay.handler.mjs index 304a8d1..4c9ff53 100644 --- a/src/relay/udp.relay.handler.mjs +++ b/src/relay/udp.relay.handler.mjs @@ -6,9 +6,41 @@ import { UDPSocketPool } from './udp.socket.pool.mjs' import { time } from '../utils.mjs' import { EventEmitter } from 'node:events' import logger from '../logger.mjs' +import * as prometheus from 'prom-client' +import { metricsRegistry } from '../metrics/metrics.registry.mjs' const log = logger.child({ name: 'UDPRelayHandler' }) +const relayDurationHistogram = new prometheus.Histogram({ + name: 'noray_relay_duration', + help: 'Time it takes to relay a packet', + registers: [metricsRegistry] +}) + +const relaySizeHistorgram = new prometheus.Histogram({ + name: 'noray_relay_size', + help: 'Size of the packet being relayed', + registers: [metricsRegistry] +}) + +const relayDropCounter = new prometheus.Counter({ + name: 'noray_relay_drop_count', + help: 'Number of relay packets dropped', + registers: [metricsRegistry] +}) + +const activeRelayGauge = new prometheus.Gauge({ + name: 'noray_relay_count', + help: 'Count of currently active relays', + registers: [metricsRegistry] +}) + +const expiredRelayCounter = new prometheus.Counter({ + name: 'noray_relay_expired', + help: 'Count of expired relays', + registers: [metricsRegistry] +}) + /** * Class implementing the actual relay logic. * @@ -74,6 +106,8 @@ export class UDPRelayHandler extends EventEmitter { this.#relayTable.push(relay) log.trace({ relay }, 'Relay created') + activeRelayGauge.inc() + return relay } @@ -104,6 +138,9 @@ export class UDPRelayHandler extends EventEmitter { this.#socketPool.returnPort(relay.port) this.#relayTable = this.#relayTable.filter((_, i) => i !== idx) + + activeRelayGauge.dec() + return true } @@ -112,6 +149,8 @@ export class UDPRelayHandler extends EventEmitter { */ clear () { this.relayTable.forEach(entry => this.freeRelay(entry)) + + activeRelayGauge.reset() } /** @@ -124,6 +163,8 @@ export class UDPRelayHandler extends EventEmitter { * @fires UDPRelayHandler#drop */ relay (msg, sender, target) { + const measure = relayDurationHistogram.startTimer() + const senderRelay = this.#relayTable.find(r => r.address.port === sender.port && r.address.address === sender.address ) @@ -132,6 +173,10 @@ export class UDPRelayHandler extends EventEmitter { if (!senderRelay || !targetRelay) { // We don't have a relay for the sender, target, or both this.emit('drop', senderRelay, targetRelay, sender, target, msg) + + relayDropCounter.inc() + measure() + return false } @@ -149,6 +194,9 @@ export class UDPRelayHandler extends EventEmitter { senderRelay.lastReceived = time() targetRelay.lastSent = time() + relaySizeHistorgram.observe(msg?.byteLength ?? 0) + measure() + return true } From 2e1af6b34c0ba4781d8296b81dfcf003eddaf71c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tam=C3=A1s=20G=C3=A1lffy?= Date: Sat, 8 Jul 2023 23:25:40 +0200 Subject: [PATCH 2/4] Add remote registrar metrics --- src/relay/udp.remote.registrar.mjs | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/src/relay/udp.remote.registrar.mjs b/src/relay/udp.remote.registrar.mjs index b05801f..d606500 100644 --- a/src/relay/udp.remote.registrar.mjs +++ b/src/relay/udp.remote.registrar.mjs @@ -5,9 +5,29 @@ import dgram from 'node:dgram' import assert from 'node:assert' import logger from '../logger.mjs' import { requireParam } from '../assertions.mjs' +import * as prometheus from 'prom-client' +import { metricsRegistry } from '../metrics/metrics.registry.mjs' const log = logger.child({ name: 'UDPRemoteRegistrar' }) +const registerSuccessCounter = new prometheus.Counter({ + name: 'noray_remote_registrar_success', + help: 'Number of successful remote address registrations', + registers: [metricsRegistry] +}) + +const registerFailCounter = new prometheus.Counter({ + name: 'noray_remote_registrar_fail', + help: 'Number of failed remote address registrations', + registers: [metricsRegistry] +}) + +const registerRepatCounter = new prometheus.Counter({ + name: 'noray_remote_registrar_repeat', + help: 'Number of redundant remote address registrations', + registers: [metricsRegistry] +}) + /** * @summary Class for remote address registration over UDP. * @@ -80,12 +100,15 @@ export class UDPRemoteRegistrar { if (host.rinfo) { // Host has already remote info registered this.#socket.send('OK', rinfo.port, rinfo.address) + registerRepatCounter.inc() return } host.rinfo = rinfo this.#socket.send('OK', rinfo.port, rinfo.address) + registerSuccessCounter.inc() } catch (e) { + registerFailCounter.inc() this.#socket.send(e.message ?? 'Error', rinfo.port, rinfo.address) } } From e6fbccb3c8a2822e2d3fae08219839ef899fa98c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tam=C3=A1s=20G=C3=A1lffy?= Date: Sat, 8 Jul 2023 23:26:07 +0200 Subject: [PATCH 3/4] bv --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 3cc4ad0..5086d50 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@foxssake/noray", - "version": "1.2.0", + "version": "1.3.0", "description": "Online multiplayer orchestrator and potential game platform", "main": "src/noray.mjs", "bin": { From 76af5b7852fb521a788ac1db0af61b20daa9c0b3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tam=C3=A1s=20G=C3=A1lffy?= Date: Sat, 8 Jul 2023 23:28:13 +0200 Subject: [PATCH 4/4] f --- src/relay/udp.relay.handler.mjs | 6 ------ 1 file changed, 6 deletions(-) diff --git a/src/relay/udp.relay.handler.mjs b/src/relay/udp.relay.handler.mjs index 4c9ff53..d54a5f5 100644 --- a/src/relay/udp.relay.handler.mjs +++ b/src/relay/udp.relay.handler.mjs @@ -35,12 +35,6 @@ const activeRelayGauge = new prometheus.Gauge({ registers: [metricsRegistry] }) -const expiredRelayCounter = new prometheus.Counter({ - name: 'noray_relay_expired', - help: 'Count of expired relays', - registers: [metricsRegistry] -}) - /** * Class implementing the actual relay logic. *