From f6dd85b7334f73537cc250e1b280ee2e6d065060 Mon Sep 17 00:00:00 2001 From: adjoly Date: Tue, 22 Jul 2025 17:59:35 +0200 Subject: [PATCH] =?UTF-8?q?=E3=80=8C=E2=9C=A8=E3=80=8D=20feat:=20added=20e?= =?UTF-8?q?xporter=20to=20node=20shitty=20code=20(yes=20thats=20mine=20and?= =?UTF-8?q?=20=3F=3F=3F)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docker/api-base/compose.yml | 2 ++ .../prometheus/config/prometheus.yml | 8 +++++ package.json | 3 +- pnpm-lock.yaml | 30 +++++++++++++++++++ src/api/auth/default.js | 26 ++++++++++++++++ src/api/user/default.js | 26 ++++++++++++++++ 6 files changed, 94 insertions(+), 1 deletion(-) diff --git a/docker/api-base/compose.yml b/docker/api-base/compose.yml index 283c711..3aa20a8 100644 --- a/docker/api-base/compose.yml +++ b/docker/api-base/compose.yml @@ -9,6 +9,7 @@ services: networks: - front - back + - prom-exporter environment: - TZ=Europe/Paris - API_TARGET=user @@ -24,6 +25,7 @@ services: networks: - front - back + - prom-exporter environment: - TZ=Europe/Paris - API_TARGET=auth diff --git a/docker/monitoring/prometheus/config/prometheus.yml b/docker/monitoring/prometheus/config/prometheus.yml index 92fea5f..7c42e9d 100644 --- a/docker/monitoring/prometheus/config/prometheus.yml +++ b/docker/monitoring/prometheus/config/prometheus.yml @@ -23,3 +23,11 @@ scrape_configs: - job_name: 'node-exporter' static_configs: - targets: ['node-exporter:9100'] + + - job_name: 'auth-api' + static_configs: + - targets: ['transcendence-api-auth:3000'] + + - job_name: 'user-api' + static_configs: + - targets: ['transcendence-api-user:3000'] diff --git a/package.json b/package.json index 1144baf..671f7c1 100644 --- a/package.json +++ b/package.json @@ -9,7 +9,8 @@ "better-sqlite3": "^12.2.0", "fastify": "^5.4.0", "fastify-cli": "^7.4.0", - "google-auth-library": "^10.1.0" + "google-auth-library": "^10.1.0", + "prom-client": "^15.1.3" }, "type": "module", "devDependencies": { diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 15413f9..788206f 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -38,6 +38,9 @@ importers: google-auth-library: specifier: ^10.1.0 version: 10.1.0 + prom-client: + specifier: ^15.1.3 + version: 15.1.3 devDependencies: '@tailwindcss/vite': specifier: ^4.1.11 @@ -268,6 +271,10 @@ packages: resolution: {integrity: sha512-9I2Zn6+NJLfaGoz9jN3lpwDgAYvfGeNYdbAIjJOqzs4Tpc+VU3Jqq4IofSUBKajiDS8k9fZIg18/z13mpk1bsA==} engines: {node: '>=8'} + '@opentelemetry/api@1.9.0': + resolution: {integrity: sha512-3giAOQvZiH5F9bMlMiv8+GSPMeqg0dbaeo58/0SlA9sxSqZhnUtxzX9/2FzyhS9sWQf5S0GJE0AKBrFqjpeYcg==} + engines: {node: '>=8.0.0'} + '@rollup/rollup-android-arm-eabi@4.44.2': resolution: {integrity: sha512-g0dF8P1e2QYPOj1gu7s/3LVP6kze9A7m6x0BZ9iTdXK8N5c2V7cpBKHV3/9A4Zd8xxavdhK0t4PnqjkqVmUc9Q==} cpu: [arm] @@ -520,6 +527,9 @@ packages: bindings@1.5.0: resolution: {integrity: sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==} + bintrees@1.0.2: + resolution: {integrity: sha512-VOMgTMwjAaUG580SXn3LacVgjurrbMme7ZZNYGSSV7mmtY6QQRh0Eg3pwIcntQ77DErK1L0NxkbetjcoXzVwKw==} + bl@4.1.0: resolution: {integrity: sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==} @@ -1093,6 +1103,10 @@ packages: process-warning@5.0.0: resolution: {integrity: sha512-a39t9ApHNx2L4+HBnQKqxxHNs1r7KF+Intd8Q/g1bUh6q0WIp9voPXJ/x0j+ZL45KF1pJd9+q2jLIRMfvEshkA==} + prom-client@15.1.3: + resolution: {integrity: sha512-6ZiOBfCywsD4k1BN9IX0uZhF+tJkV8q8llP64G5Hajs4JOeVLPCwpPVcpXy3BwYiUGgyJzsJJQeOIv7+hDSq8g==} + engines: {node: ^16 || ^18 || >=20} + proxy-from-env@1.1.0: resolution: {integrity: sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==} @@ -1225,6 +1239,9 @@ packages: resolution: {integrity: sha512-5S7Va8hKfV7W5U6g3aYxXmlPoZVAwUMy9AOKyF2fVuZa2UD3qZjg578OrLRt8PcNN1PleVaL/5/yYATNL0ICUw==} engines: {node: '>=18'} + tdigest@0.1.2: + resolution: {integrity: sha512-+G0LLgjjo9BZX2MfdvPfH+MKLCrxlXSYec5DaPYP1fe6Iyhf0/fSmJ0bFiZ1F8BT6cGXl2LpltQptzjXKWEkKA==} + thread-stream@3.1.0: resolution: {integrity: sha512-OqyPZ9u96VohAyMfJykzmivOrY2wfMSf3C5TtFJVgN+Hm6aj+voFhlK+kZEIv2FBh1X6Xp3DlnCOfEQ3B2J86A==} @@ -1460,6 +1477,8 @@ snapshots: '@lukeed/ms@2.0.2': {} + '@opentelemetry/api@1.9.0': {} + '@rollup/rollup-android-arm-eabi@4.44.2': optional: true @@ -1656,6 +1675,8 @@ snapshots: dependencies: file-uri-to-path: 1.0.0 + bintrees@1.0.2: {} + bl@4.1.0: dependencies: buffer: 5.7.1 @@ -2264,6 +2285,11 @@ snapshots: process-warning@5.0.0: {} + prom-client@15.1.3: + dependencies: + '@opentelemetry/api': 1.9.0 + tdigest: 0.1.2 + proxy-from-env@1.1.0: {} pump@3.0.3: @@ -2412,6 +2438,10 @@ snapshots: mkdirp: 3.0.1 yallist: 5.0.0 + tdigest@0.1.2: + dependencies: + bintrees: 1.0.2 + thread-stream@3.1.0: dependencies: real-require: 0.2.0 diff --git a/src/api/auth/default.js b/src/api/auth/default.js index ee5928a..b8a9063 100644 --- a/src/api/auth/default.js +++ b/src/api/auth/default.js @@ -1,5 +1,6 @@ import fastifyJWT from '@fastify/jwt'; import fastifyCookie from '@fastify/cookie'; +import client from 'prom-client'; import { register } from './register.js'; import { login } from './login.js'; @@ -13,6 +14,7 @@ import { totpVerify } from './totpVerify.js'; const saltRounds = 10; export const appName = process.env.APP_NAME || 'knl_meowscendence'; +const collectDefaultMetrics = client.collectDefaultMetrics authDB.prepareDB(); @@ -21,6 +23,30 @@ authDB.prepareDB(); * @param {import('fastify').FastifyPluginOptions} options */ export default async function(fastify, options) { + + collectDefaultMetrics({ labels: { service: "auth-api" } }) + client.register.setDefaultLabels({ service: "auth-api" }) + + const httpRequestCounter = new client.Counter({ + name: 'http_requests_total', + help: 'Total number of HTTP requests', + labelNames: ['method', 'route', 'status_code'], + }) + + fastify.addHook('onResponse', (req, res, done) => { + httpRequestCounter.inc({ + method: req.method, + route: req.routerPath || req.url, + status_code: res.statusCode, + }) + done() + }) + fastify.get('/metrics', async (req, reply) => { + reply + .header('Content-Type', client.register.contentType) + .send(await client.register.metrics()) + }) + fastify.register(fastifyJWT, { secret: process.env.JWT_SECRET || '123456789101112131415161718192021', cookie: { diff --git a/src/api/user/default.js b/src/api/user/default.js index 260025e..34ef89d 100644 --- a/src/api/user/default.js +++ b/src/api/user/default.js @@ -1,8 +1,10 @@ import fastifyJWT from '@fastify/jwt'; import fastifyCookie from '@fastify/cookie'; import Database from 'better-sqlite3'; +import client from 'prom-client'; var env = process.env.NODE_ENV || 'development'; +const collectDefaultMetrics = client.collectDefaultMetrics let database; @@ -57,6 +59,30 @@ const deleteFriends = database.prepare('DELETE FROM friends WHERE username = ?;' */ export default async function(fastify, options) { + collectDefaultMetrics({ labels: { service: "auth-api" } }) + client.register.setDefaultLabels({ service: "auth-api" }) + + const httpRequestCounter = new client.Counter({ + name: 'http_requests_total', + help: 'Total number of HTTP requests', + labelNames: ['method', 'route', 'status_code'], + }) + + fastify.addHook('onResponse', (req, res, done) => { + httpRequestCounter.inc({ + method: req.method, + route: req.routerPath || req.url, + status_code: res.statusCode, + }) + done() + }) + fastify.get('/metrics', async (req, reply) => { + reply + .header('Content-Type', client.register.contentType) + .send(await client.register.metrics()) + }) + + fastify.register(fastifyJWT, { secret: process.env.JWT_SECRET || '123456789101112131415161718192021', cookie: {