Skip to main content
Glama
Panth1823

Formula1 MCP Server

metrics.ts3.41 kB
/** * Basic metrics collection for Prometheus * Simple in-memory metrics (can be upgraded to Prometheus client library) */ import { config } from '../config/index.js'; interface MetricValue { value: number; labels?: Record<string, string>; } class MetricsCollector { private counters: Map<string, number> = new Map(); private gauges: Map<string, number> = new Map(); private histograms: Map<string, number[]> = new Map(); // Counter metrics incrementCounter(name: string, labels?: Record<string, string>): void { const key = this.getKey(name, labels); this.counters.set(key, (this.counters.get(key) || 0) + 1); } // Gauge metrics setGauge(name: string, value: number, labels?: Record<string, string>): void { const key = this.getKey(name, labels); this.gauges.set(key, value); } // Histogram metrics observeHistogram(name: string, value: number, labels?: Record<string, string>): void { const key = this.getKey(name, labels); const values = this.histograms.get(key) || []; values.push(value); this.histograms.set(key, values); } private getKey(name: string, labels?: Record<string, string>): string { if (!labels || Object.keys(labels).length === 0) { return name; } const labelStr = Object.entries(labels) .map(([k, v]) => `${k}="${v}"`) .join(','); return `${name}{${labelStr}}`; } // Export metrics in Prometheus format exportPrometheus(): string { const lines: string[] = []; // Export counters for (const [key, value] of this.counters.entries()) { lines.push(`# TYPE ${key.split('{')[0]} counter`); lines.push(`${key} ${value}`); } // Export gauges for (const [key, value] of this.gauges.entries()) { lines.push(`# TYPE ${key.split('{')[0]} gauge`); lines.push(`${key} ${value}`); } // Export histograms (simplified - just count and sum) for (const [key, values] of this.histograms.entries()) { const baseName = key.split('{')[0]; const sum = values.reduce((a, b) => a + b, 0); const count = values.length; const avg = count > 0 ? sum / count : 0; lines.push(`# TYPE ${baseName} histogram`); lines.push(`${baseName}_sum${key.includes('{') ? '{' + key.split('{')[1] : ''} ${sum}`); lines.push(`${baseName}_count${key.includes('{') ? '{' + key.split('{')[1] : ''} ${count}`); lines.push(`${baseName}_avg${key.includes('{') ? '{' + key.split('{')[1] : ''} ${avg}`); } return lines.join('\n') + '\n'; } // Reset all metrics reset(): void { this.counters.clear(); this.gauges.clear(); this.histograms.clear(); } } export const metrics = new MetricsCollector(); // Helper middleware to track request metrics export function trackRequestMetrics(req: any, res: any, next: any): void { if (!config.metricsEnabled) { return next(); } const startTime = Date.now(); const method = req.method; const path = req.path; // Track request count metrics.incrementCounter('http_requests_total', { method, path }); // Track response time res.on('finish', () => { const duration = Date.now() - startTime; metrics.observeHistogram('http_request_duration_ms', duration, { method, path }); metrics.incrementCounter('http_responses_total', { method, path, status: res.statusCode.toString(), }); }); next(); }

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/Panth1823/formula1-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server