import * as plugins from '../../plugins.js'; import type { OpsServer } from '../classes.opsserver.js'; import * as interfaces from '../../../ts_interfaces/index.js'; import { MetricsManager } from '../../monitoring/index.js'; export class StatsHandler { public typedrouter = new plugins.typedrequest.TypedRouter(); constructor(private opsServerRef: OpsServer) { // Add this handler's router to the parent this.opsServerRef.typedrouter.addTypedRouter(this.typedrouter); this.registerHandlers(); } private registerHandlers(): void { // Server Statistics Handler this.typedrouter.addTypedHandler( new plugins.typedrequest.TypedHandler( 'getServerStatistics', async (dataArg, toolsArg) => { const stats = await this.collectServerStats(); return { stats: { uptime: stats.uptime, startTime: Date.now() - (stats.uptime * 1000), memoryUsage: stats.memoryUsage, cpuUsage: stats.cpuUsage, activeConnections: stats.activeConnections, totalConnections: stats.totalConnections, }, history: dataArg.includeHistory ? stats.history : undefined, }; } ) ); // Email Statistics Handler this.typedrouter.addTypedHandler( new plugins.typedrequest.TypedHandler( 'getEmailStatistics', async (dataArg, toolsArg) => { const emailServer = this.opsServerRef.dcRouterRef.emailServer; if (!emailServer) { return { stats: { sent: 0, received: 0, bounced: 0, queued: 0, failed: 0, averageDeliveryTime: 0, deliveryRate: 0, bounceRate: 0, }, }; } const stats = await this.collectEmailStats(); return { stats: { sent: stats.sentToday, received: stats.receivedToday, bounced: Math.floor(stats.sentToday * stats.bounceRate / 100), queued: stats.queueSize, failed: 0, averageDeliveryTime: 0, deliveryRate: stats.deliveryRate, bounceRate: stats.bounceRate, }, domainBreakdown: dataArg.includeDetails ? stats.domainBreakdown : undefined, }; } ) ); // DNS Statistics Handler this.typedrouter.addTypedHandler( new plugins.typedrequest.TypedHandler( 'getDnsStatistics', async (dataArg, toolsArg) => { const dnsServer = this.opsServerRef.dcRouterRef.dnsServer; if (!dnsServer) { return { stats: { totalQueries: 0, cacheHits: 0, cacheMisses: 0, cacheHitRate: 0, activeDomains: 0, averageResponseTime: 0, queryTypes: {}, }, }; } const stats = await this.collectDnsStats(); return { stats: { totalQueries: stats.totalQueries, cacheHits: stats.cacheHits, cacheMisses: stats.cacheMisses, cacheHitRate: stats.cacheHitRate, activeDomains: stats.topDomains.length, averageResponseTime: 0, queryTypes: stats.queryTypes, }, domainBreakdown: dataArg.includeQueryTypes ? stats.domainBreakdown : undefined, }; } ) ); // Queue Status Handler this.typedrouter.addTypedHandler( new plugins.typedrequest.TypedHandler( 'getQueueStatus', async (dataArg, toolsArg) => { const emailServer = this.opsServerRef.dcRouterRef.emailServer; const queues: interfaces.data.IQueueStatus[] = []; if (emailServer) { const status = await this.getQueueStatus(); queues.push({ name: dataArg.queueName || 'default', size: status.pending, processing: status.active, failed: status.failed, retrying: status.retrying, averageProcessingTime: 0, }); } return { queues, totalItems: queues.reduce((sum, q) => sum + q.size + q.processing + q.failed + q.retrying, 0), }; } ) ); // Health Status Handler this.typedrouter.addTypedHandler( new plugins.typedrequest.TypedHandler( 'getHealthStatus', async (dataArg, toolsArg) => { const health = await this.checkHealthStatus(); return { health: { healthy: health.healthy, uptime: process.uptime(), services: health.services.reduce((acc, service) => { acc[service.name] = { status: service.status, message: service.message, lastCheck: Date.now(), }; return acc; }, {} as any), version: '2.12.0', // TODO: Get from package.json }, }; } ) ); } private async collectServerStats(): Promise<{ uptime: number; cpuUsage: { user: number; system: number; }; memoryUsage: interfaces.data.IServerStats['memoryUsage']; requestsPerSecond: number; activeConnections: number; totalConnections: number; history: Array<{ timestamp: number; value: number; }>; }> { // Get metrics from MetricsManager if available if (this.opsServerRef.dcRouterRef.metricsManager) { const serverStats = await this.opsServerRef.dcRouterRef.metricsManager.getServerStats(); return { uptime: serverStats.uptime, cpuUsage: serverStats.cpuUsage, memoryUsage: serverStats.memoryUsage, requestsPerSecond: serverStats.requestsPerSecond, activeConnections: serverStats.activeConnections, totalConnections: serverStats.totalConnections, history: [], // TODO: Implement history tracking }; } // Fallback to basic stats if MetricsManager not available const uptime = process.uptime(); const memUsage = process.memoryUsage(); const cpuUsage = plugins.os.loadavg()[0] * 100 / plugins.os.cpus().length; return { uptime, cpuUsage: { user: cpuUsage * 0.7, system: cpuUsage * 0.3, }, memoryUsage: { heapUsed: memUsage.heapUsed, heapTotal: memUsage.heapTotal, external: memUsage.external, rss: memUsage.rss, }, requestsPerSecond: 0, activeConnections: 0, totalConnections: 0, history: [], }; } private async collectEmailStats(): Promise<{ sentToday: number; receivedToday: number; bounceRate: number; deliveryRate: number; queueSize: number; domainBreakdown?: { [domain: string]: interfaces.data.IEmailStats }; }> { // Get metrics from MetricsManager if available if (this.opsServerRef.dcRouterRef.metricsManager) { const emailStats = await this.opsServerRef.dcRouterRef.metricsManager.getEmailStats(); return { sentToday: emailStats.sentToday, receivedToday: emailStats.receivedToday, bounceRate: emailStats.bounceRate, deliveryRate: emailStats.deliveryRate, queueSize: emailStats.queueSize, }; } // Fallback if MetricsManager not available return { sentToday: 0, receivedToday: 0, bounceRate: 0, deliveryRate: 100, queueSize: 0, }; } private async collectDnsStats(): Promise<{ queriesPerSecond: number; totalQueries: number; cacheHits: number; cacheMisses: number; cacheHitRate: number; topDomains: Array<{ domain: string; count: number; }>; queryTypes: { [key: string]: number }; domainBreakdown?: { [domain: string]: interfaces.data.IDnsStats }; }> { // Get metrics from MetricsManager if available if (this.opsServerRef.dcRouterRef.metricsManager) { const dnsStats = await this.opsServerRef.dcRouterRef.metricsManager.getDnsStats(); return { queriesPerSecond: dnsStats.queriesPerSecond, totalQueries: dnsStats.totalQueries, cacheHits: dnsStats.cacheHits, cacheMisses: dnsStats.cacheMisses, cacheHitRate: dnsStats.cacheHitRate, topDomains: dnsStats.topDomains, queryTypes: dnsStats.queryTypes, }; } // Fallback if MetricsManager not available return { queriesPerSecond: 0, totalQueries: 0, cacheHits: 0, cacheMisses: 0, cacheHitRate: 0, topDomains: [], queryTypes: {}, }; } private async getQueueStatus(): Promise<{ pending: number; active: number; failed: number; retrying: number; items: Array<{ id: string; recipient: string; subject: string; status: string; attempts: number; nextRetry?: number; }>; }> { // TODO: Implement actual queue status collection return { pending: 0, active: 0, failed: 0, retrying: 0, items: [], }; } private async checkHealthStatus(): Promise<{ healthy: boolean; services: Array<{ name: string; status: 'healthy' | 'degraded' | 'unhealthy'; message?: string; }>; checks: Array<{ name: string; passed: boolean; message?: string; }>; }> { const services: Array<{ name: string; status: 'healthy' | 'degraded' | 'unhealthy'; message?: string; }> = []; // Check HTTP Proxy if (this.opsServerRef.dcRouterRef.smartProxy) { services.push({ name: 'HTTP/HTTPS Proxy', status: 'healthy', }); } // Check Email Server if (this.opsServerRef.dcRouterRef.emailServer) { services.push({ name: 'Email Server', status: 'healthy', }); } // Check DNS Server if (this.opsServerRef.dcRouterRef.dnsServer) { services.push({ name: 'DNS Server', status: 'healthy', }); } // Check OpsServer services.push({ name: 'OpsServer', status: 'healthy', }); const healthy = services.every(s => s.status === 'healthy'); return { healthy, services, checks: [ { name: 'Memory Usage', passed: process.memoryUsage().heapUsed < (plugins.os.totalmem() * 0.9), message: 'Memory usage within limits', }, ], }; } }