From 47cada73f30002915379d10068ed48c24e68af69 Mon Sep 17 00:00:00 2001 From: human-77 <147721177+human-77@users.noreply.github.com> Date: Thu, 19 Feb 2026 09:10:02 -0300 Subject: [PATCH 1/4] Create /metrics endpoint --- app/metrics/route.ts | 48 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) create mode 100644 app/metrics/route.ts diff --git a/app/metrics/route.ts b/app/metrics/route.ts new file mode 100644 index 0000000..c55e6ca --- /dev/null +++ b/app/metrics/route.ts @@ -0,0 +1,48 @@ +import { getStatusCounters } from "../libraries/requestCounter"; + +export async function GET() { + const usage = process.cpuUsage(); + const totalSeconds = (usage.user + usage.system) / 1e6; + const memoria = process.memoryUsage(); + let body = ` +# HELP up If the server is responding to HTTP requests +# TYPE up gauge +up 1 +# HELP process_cpu_seconds_total Total CPU time in seconds +# TYPE process_cpu_seconds_total counter +process_cpu_seconds_total ${totalSeconds} +# HELP process_memoria_rss Resident Set Size: total memory allocated for the process +# TYPE process_memoria_rss gauge +process_memoria_rss ${memoria.rss} +# HELP process_memoria_heapTotal Total heap size allocated. +# TYPE process_memoria_heapTotal gauge +process_memoria_heapTotal ${memoria.heapTotal} +# HELP process_memoria_heapUsed Total heap size used. +# TYPE process_memoria_heapUsed gauge +process_memoria_heapUsed ${memoria.heapUsed} +# HELP process_memoria_external Total external memory size. +# TYPE process_memoria_external gauge +process_memoria_external ${memoria.external} +# HELP process_memoria_arrayBuffers Total array buffers size. +# TYPE process_memoria_arrayBuffers gauge +process_memoria_arrayBuffers ${memoria.arrayBuffers} +`; + + // Add status code metrics + body += "# HELP http_requests_by_status Total requests per route and status code\n"; + body += "# TYPE http_requests_by_status counter\n"; + const statusCounters = getStatusCounters(); + // for loop inside for loop to iterate over all routes and status + Object.entries(statusCounters).forEach(([route, statuses]) => { + Object.entries(statuses).forEach(([status, count]) => { + body += `http_requests_by_status{route="${route}",status="${status}"} ${count}\n`; + }); + }); + + return new Response(body, { + status: 200, + headers: { + "Content-Type": "text/plain; version=0.0.4", + }, + }); +} From e3362e14742a34e31ac20eb06ca9007fda3a0c53 Mon Sep 17 00:00:00 2001 From: human-77 <147721177+human-77@users.noreply.github.com> Date: Thu, 19 Feb 2026 09:11:49 -0300 Subject: [PATCH 2/4] Create /app/libraries/requestCounter.ts --- app/libraries/requestCounter.ts | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) create mode 100644 app/libraries/requestCounter.ts diff --git a/app/libraries/requestCounter.ts b/app/libraries/requestCounter.ts new file mode 100644 index 0000000..7903cbd --- /dev/null +++ b/app/libraries/requestCounter.ts @@ -0,0 +1,32 @@ +// lib/requestCounter.ts + +// Use globalThis to persist counters across module reloads +const globalForCounters = globalThis as unknown as { + statusCounters: Record> | undefined; +}; + +if (!globalForCounters.statusCounters) { + globalForCounters.statusCounters = {}; +} + +const { statusCounters } = globalForCounters; + +export function incrementCounter(route: string, statusCode?: number) { + // Registers status of the response for the given route. If statusCode is undefined, it will not be counted. + if (statusCode !== undefined) { + if (!statusCounters[route]) { + statusCounters[route] = {}; + } + const status = statusCode.toString(); + if (statusCounters[route][status] === undefined) { + statusCounters[route][status] = 0; + } + statusCounters[route][status] += 1; + } else { + console.log(`Error in counting requests for the ${route}`); + } +} + +export function getStatusCounters() { + return statusCounters; +} From e512a0600be506be80047fa35ff4602e24aed70a Mon Sep 17 00:00:00 2001 From: human-77 <147721177+human-77@users.noreply.github.com> Date: Thu, 19 Feb 2026 09:13:19 -0300 Subject: [PATCH 3/4] Create __test__/metrics.test.ts Basic test for /metrics/route.ts --- __tests__/metrics.test.ts | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 __tests__/metrics.test.ts diff --git a/__tests__/metrics.test.ts b/__tests__/metrics.test.ts new file mode 100644 index 0000000..bb9755a --- /dev/null +++ b/__tests__/metrics.test.ts @@ -0,0 +1,9 @@ +import { GET } from "../app/metrics/route"; + +describe("metrics route", () => { + it("returns status ok", async () => { + const response = await GET(); + const text = await response.text(); + expect(text).toEqual(expect.any(String)); + }); +}); From 4d37af919e4194ac1349250d404a13cc5eb25fd8 Mon Sep 17 00:00:00 2001 From: human-77 <147721177+human-77@users.noreply.github.com> Date: Sun, 17 May 2026 11:50:29 -0300 Subject: [PATCH 4/4] Correcting `STELLAR_TOOLS_NAMES` on stellar.test.ts --- __tests__/contracts/stellar.test.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/__tests__/contracts/stellar.test.ts b/__tests__/contracts/stellar.test.ts index 52a3736..0a776cd 100644 --- a/__tests__/contracts/stellar.test.ts +++ b/__tests__/contracts/stellar.test.ts @@ -11,8 +11,9 @@ import contractsMcpPackage from "@openzeppelin/contracts-mcp/package.json"; const STELLAR_TOOLS_NAMES = [ "stellar-fungible", - "stellar-non-fungible", + "stellar-governor", "stellar-stablecoin", + "stellar-non-fungible" ]; const STELLAR_ENDPOINT = "http://localhost:3000/contracts/stellar/mcp";