99 lines
2.6 KiB
TypeScript
99 lines
2.6 KiB
TypeScript
interface MonitoringMetric {
|
|
name: string
|
|
value: number
|
|
timestamp: number
|
|
tags?: Record<string, string>
|
|
}
|
|
|
|
class MetricsCollector {
|
|
private metrics: MonitoringMetric[] = []
|
|
private maxMetrics = 1000
|
|
|
|
record(name: string, value: number, tags?: Record<string, string>): void {
|
|
const metric: MonitoringMetric = {
|
|
name,
|
|
value,
|
|
timestamp: Date.now(),
|
|
tags
|
|
}
|
|
|
|
this.metrics.push(metric)
|
|
|
|
// Keep only recent metrics
|
|
if (this.metrics.length > this.maxMetrics) {
|
|
this.metrics = this.metrics.slice(-this.maxMetrics)
|
|
}
|
|
}
|
|
|
|
getMetrics(name?: string, since?: number): MonitoringMetric[] {
|
|
let filtered = this.metrics
|
|
|
|
if (name) {
|
|
filtered = filtered.filter(m => m.name === name)
|
|
}
|
|
|
|
if (since) {
|
|
filtered = filtered.filter(m => m.timestamp >= since)
|
|
}
|
|
|
|
return filtered
|
|
}
|
|
|
|
getAverageResponseTime(since?: number): number {
|
|
const responseMetrics = this.getMetrics('api.response_time', since)
|
|
if (responseMetrics.length === 0) return 0
|
|
|
|
const sum = responseMetrics.reduce((acc, m) => acc + m.value, 0)
|
|
return sum / responseMetrics.length
|
|
}
|
|
|
|
getRequestCount(endpoint?: string, since?: number): number {
|
|
const requestMetrics = this.getMetrics('api.request', since)
|
|
|
|
if (endpoint) {
|
|
return requestMetrics.filter(m => m.tags?.endpoint === endpoint).length
|
|
}
|
|
|
|
return requestMetrics.length
|
|
}
|
|
|
|
getErrorCount(since?: number): number {
|
|
return this.getMetrics('api.error', since).length
|
|
}
|
|
|
|
clear(): void {
|
|
this.metrics = []
|
|
}
|
|
}
|
|
|
|
export const metrics = new MetricsCollector()
|
|
|
|
export function trackApiCall(endpoint: string, method: string, statusCode: number, responseTime: number): void {
|
|
metrics.record('api.request', 1, { endpoint, method, status: statusCode.toString() })
|
|
metrics.record('api.response_time', responseTime, { endpoint })
|
|
|
|
if (statusCode >= 400) {
|
|
metrics.record('api.error', 1, { endpoint, status: statusCode.toString() })
|
|
}
|
|
}
|
|
|
|
export function trackDatabaseQuery(operation: string, duration: number): void {
|
|
metrics.record('db.query', 1, { operation })
|
|
metrics.record('db.duration', duration, { operation })
|
|
}
|
|
|
|
export function getHealthStatus(): any {
|
|
const now = Date.now()
|
|
const fiveMinutesAgo = now - (5 * 60 * 1000)
|
|
|
|
return {
|
|
status: 'healthy',
|
|
timestamp: new Date().toISOString(),
|
|
metrics: {
|
|
requests_5min: metrics.getRequestCount(undefined, fiveMinutesAgo),
|
|
avg_response_time: Math.round(metrics.getAverageResponseTime(fiveMinutesAgo)),
|
|
errors_5min: metrics.getErrorCount(fiveMinutesAgo),
|
|
uptime: process.uptime()
|
|
}
|
|
}
|
|
} |