Skip to main content
Glama
zqushair
by zqushair
monitoring.ts7.1 kB
import os from 'os'; import logger from './logger.js'; // Interface for system metrics interface SystemMetrics { uptime: number; cpuUsage: number; memoryUsage: { total: number; free: number; used: number; usedPercentage: number; }; processMemoryUsage: NodeJS.MemoryUsage; } // Interface for application metrics interface ApplicationMetrics { requestCount: number; errorCount: number; webhookCount: number; averageResponseTime: number; } /** * Rolling window statistics for efficient response time tracking * This class maintains running statistics without storing individual data points */ class RollingStats { private count: number = 0; private sum: number = 0; private sumOfSquares: number = 0; private min: number = Number.MAX_VALUE; private max: number = Number.MIN_VALUE; private readonly windowSize: number; private readonly decayFactor: number; /** * Create a new rolling statistics tracker * @param windowSize The approximate number of data points to consider */ constructor(windowSize: number = 1000) { this.windowSize = windowSize; // Calculate decay factor based on window size // This ensures older values have less weight as new values are added this.decayFactor = 1 - (1 / windowSize); } /** * Add a new value to the statistics * @param value The value to add */ public add(value: number): void { // Apply decay factor to existing statistics this.sum *= this.decayFactor; this.sumOfSquares *= this.decayFactor; this.count = Math.min(this.count + 1, this.windowSize); // Update statistics with new value this.sum += value; this.sumOfSquares += value * value; this.min = Math.min(this.min, value); this.max = Math.max(this.max, value); } /** * Get the mean (average) of the values * @returns The mean value */ public mean(): number { return this.count > 0 ? this.sum / this.count : 0; } /** * Get the variance of the values * @returns The variance */ public variance(): number { if (this.count <= 1) return 0; const mean = this.mean(); return Math.max(0, this.sumOfSquares / this.count - mean * mean); } /** * Get the standard deviation of the values * @returns The standard deviation */ public stdDev(): number { return Math.sqrt(this.variance()); } /** * Get the minimum value * @returns The minimum value */ public getMin(): number { return this.count > 0 ? this.min : 0; } /** * Get the maximum value * @returns The maximum value */ public getMax(): number { return this.count > 0 ? this.max : 0; } /** * Get the number of values * @returns The count */ public getCount(): number { return this.count; } /** * Reset the statistics */ public reset(): void { this.count = 0; this.sum = 0; this.sumOfSquares = 0; this.min = Number.MAX_VALUE; this.max = Number.MIN_VALUE; } } /** * Extended application metrics interface with additional statistics */ interface ExtendedApplicationMetrics extends ApplicationMetrics { responseTimeStats: { min: number; max: number; stdDev: number; count: number; }; } /** * Class to track application metrics * Uses efficient statistical tracking for response times */ class MetricsTracker { private requestCount = 0; private errorCount = 0; private webhookCount = 0; private responseTimeStats: RollingStats; constructor() { this.responseTimeStats = new RollingStats(1000); // Track ~1000 most recent requests } /** * Increment request count */ public incrementRequestCount(): void { this.requestCount++; } /** * Increment error count */ public incrementErrorCount(): void { this.errorCount++; } /** * Increment webhook count */ public incrementWebhookCount(): void { this.webhookCount++; } /** * Add response time * @param time Response time in milliseconds */ public addResponseTime(time: number): void { this.responseTimeStats.add(time); } /** * Get average response time * @returns The average response time */ public getAverageResponseTime(): number { return this.responseTimeStats.mean(); } /** * Get application metrics * @returns Application metrics */ public getMetrics(): ExtendedApplicationMetrics { return { requestCount: this.requestCount, errorCount: this.errorCount, webhookCount: this.webhookCount, averageResponseTime: this.getAverageResponseTime(), responseTimeStats: { min: this.responseTimeStats.getMin(), max: this.responseTimeStats.getMax(), stdDev: this.responseTimeStats.stdDev(), count: this.responseTimeStats.getCount() } }; } /** * Reset metrics (for testing or periodic resets) */ public reset(): void { this.requestCount = 0; this.errorCount = 0; this.webhookCount = 0; this.responseTimeStats.reset(); } } // Create a singleton instance of the metrics tracker export const metricsTracker = new MetricsTracker(); // Get system metrics export function getSystemMetrics(): SystemMetrics { const totalMemory = os.totalmem(); const freeMemory = os.freemem(); const usedMemory = totalMemory - freeMemory; const usedPercentage = (usedMemory / totalMemory) * 100; return { uptime: process.uptime(), cpuUsage: os.loadavg()[0], // 1 minute load average memoryUsage: { total: totalMemory, free: freeMemory, used: usedMemory, usedPercentage, }, processMemoryUsage: process.memoryUsage(), }; } // Get all metrics (system and application) export function getAllMetrics(): { system: SystemMetrics; application: ApplicationMetrics } { return { system: getSystemMetrics(), application: metricsTracker.getMetrics(), }; } // Log metrics periodically export function startMetricsLogging(intervalMs = 60000): NodeJS.Timeout { return setInterval(() => { const metrics = getAllMetrics(); logger.info('System metrics', { metrics: metrics.system }); logger.info('Application metrics', { metrics: metrics.application }); }, intervalMs); } // Middleware to track request metrics export function requestMetricsMiddleware( req: any, res: any, next: () => void ): void { // Record start time const startTime = Date.now(); // Increment request count metricsTracker.incrementRequestCount(); // Track response time on response finish res.on('finish', () => { const responseTime = Date.now() - startTime; metricsTracker.addResponseTime(responseTime); // If it's an error response, increment error count if (res.statusCode >= 400) { metricsTracker.incrementErrorCount(); } }); next(); } // Health check function export function healthCheck(): { status: string; timestamp: string; version: string } { return { status: 'ok', timestamp: new Date().toISOString(), version: process.env.npm_package_version || '1.0.0', }; }

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/zqushair/Frontapp-MCP'

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