UNPKG

@jackchuka/gql-ingest

Version:

A CLI tool for ingesting data from CSV files into a GraphQL API

162 lines (138 loc) • 4.79 kB
export interface EntityMetrics { entityName: string; successCount: number; failureCount: number; startTime: number; endTime?: number; } export interface ProcessingMetrics { totalEntities: number; totalSuccesses: number; totalFailures: number; entityMetrics: Map<string, EntityMetrics>; requestDurations: number[]; retryAttempts: number; retrySuccesses: number; retryFailures: number; startTime: number; endTime?: number; } export class MetricsCollector { private metrics: ProcessingMetrics; constructor() { this.metrics = { totalEntities: 0, totalSuccesses: 0, totalFailures: 0, entityMetrics: new Map(), requestDurations: [], retryAttempts: 0, retrySuccesses: 0, retryFailures: 0, startTime: Date.now(), }; } startEntityProcessing(entityName: string): void { if (!this.metrics.entityMetrics.has(entityName)) { this.metrics.entityMetrics.set(entityName, { entityName, successCount: 0, failureCount: 0, startTime: Date.now(), }); } } recordSuccess(entityName: string): void { const entityMetric = this.metrics.entityMetrics.get(entityName); if (entityMetric) { entityMetric.successCount++; this.metrics.totalSuccesses++; this.metrics.totalEntities++; } } recordFailure(entityName: string): void { const entityMetric = this.metrics.entityMetrics.get(entityName); if (entityMetric) { entityMetric.failureCount++; this.metrics.totalFailures++; this.metrics.totalEntities++; } } finishEntityProcessing(entityName: string): void { const entityMetric = this.metrics.entityMetrics.get(entityName); if (entityMetric) { entityMetric.endTime = Date.now(); } } finishProcessing(): ProcessingMetrics { this.metrics.endTime = Date.now(); return { ...this.metrics }; } getEntityMetrics(entityName: string): EntityMetrics | undefined { return this.metrics.entityMetrics.get(entityName); } getTotalProcessed(): number { return this.metrics.totalEntities; } getSuccessRate(): number { if (this.metrics.totalEntities === 0) return 0; return (this.metrics.totalSuccesses / this.metrics.totalEntities) * 100; } recordRequestDuration(duration: number): void { this.metrics.requestDurations.push(duration); } recordRetrySuccess(attempts: number): void { this.metrics.retryAttempts += attempts; this.metrics.retrySuccesses++; } recordRetryFailure(attempts: number): void { this.metrics.retryAttempts += attempts; this.metrics.retryFailures++; } getAverageRequestDuration(): number { if (this.metrics.requestDurations.length === 0) return 0; const sum = this.metrics.requestDurations.reduce((a, b) => a + b, 0); return sum / this.metrics.requestDurations.length; } getDurationMs(): number { const endTime = this.metrics.endTime || Date.now(); return endTime - this.metrics.startTime; } generateSummary(): string { const duration = this.getDurationMs(); const successRate = this.getSuccessRate(); const avgRequestDuration = this.getAverageRequestDuration(); let summary = `\nšŸ“Š Processing Summary:\n`; summary += ` Total Processed: ${this.metrics.totalEntities}\n`; summary += ` āœ“ Successes: ${this.metrics.totalSuccesses}\n`; summary += ` āœ— Failures: ${this.metrics.totalFailures}\n`; summary += ` Success Rate: ${successRate.toFixed(1)}%\n`; summary += ` Duration: ${(duration / 1000).toFixed(2)}s\n`; if (this.metrics.requestDurations.length > 0) { summary += ` Avg Request Time: ${avgRequestDuration.toFixed(0)}ms\n`; } if (this.metrics.retryAttempts > 0) { summary += ` Retry Attempts: ${this.metrics.retryAttempts}\n`; summary += ` Retry Successes: ${this.metrics.retrySuccesses}\n`; summary += ` Retry Failures: ${this.metrics.retryFailures}\n`; } if (this.metrics.entityMetrics.size > 0) { summary += `\nšŸ“‹ Per-Entity Breakdown:\n`; for (const [entityName, entityMetric] of this.metrics.entityMetrics) { const entityTotal = entityMetric.successCount + entityMetric.failureCount; const entityRate = entityTotal > 0 ? (entityMetric.successCount / entityTotal) * 100 : 0; const entityDuration = entityMetric.endTime ? entityMetric.endTime - entityMetric.startTime : 0; summary += ` ${entityName}: ${entityTotal} total (${ entityMetric.successCount } āœ“, ${entityMetric.failureCount} āœ—) - ${entityRate.toFixed( 1 )}% success - ${(entityDuration / 1000).toFixed(2)}s\n`; } } return summary; } }