Skip to main content
Glama
log-comparator.ts5.43 kB
/** * Log Comparator Module * Compares baseline vs slot log analysis for deployment decisions * Part of DXP-112 implementation */ interface LogAnalysisResult { errors?: { total: number; }; performance?: { avgResponseTime?: number | null; p95ResponseTime?: number | null; p99ResponseTime?: number | null; }; summary?: { healthScore: number; }; } interface ComparisonThresholds { maxErrorIncrease?: number; maxScoreDecrease?: number; maxLatencyIncrease?: number; } interface ComparisonResult { decision: 'safe' | 'warning' | 'critical'; recommendation: 'proceed' | 'investigate' | 'rollback'; baseline: { totalErrors: number; healthScore: number; avgLatency: number | null; p95Latency: number | null; }; slot: { totalErrors: number; healthScore: number; avgLatency: number | null; p95Latency: number | null; }; deltas: { errorDelta: number; errorDeltaPercent: number; scoreDelta: number; latencyDelta: number; }; reasons: string[]; thresholdsApplied: { maxErrorIncrease: number; maxScoreDecrease: number; maxLatencyIncrease: number; }; } /** * Compare two log analysis results and provide deployment recommendation * @param {Object} baseline - Baseline log analysis result * @param {Object} slot - Slot log analysis result * @param {Object} thresholds - Optional threshold overrides * @returns {Object} Comparison result with decision and recommendation */ function compareLogs( baseline: LogAnalysisResult, slot: LogAnalysisResult, thresholds: ComparisonThresholds = {} ): ComparisonResult { // Apply default thresholds const maxErrorIncrease = thresholds.maxErrorIncrease ?? 0.5; // 50% const maxScoreDecrease = thresholds.maxScoreDecrease ?? 20; // 20 points const maxLatencyIncrease = thresholds.maxLatencyIncrease ?? 100; // 100ms // Extract key metrics const baselineErrors = baseline.errors?.total ?? 0; const slotErrors = slot.errors?.total ?? 0; const baselineScore = baseline.summary?.healthScore ?? 100; const slotScore = slot.summary?.healthScore ?? 100; const baselineLatency = baseline.performance?.p95ResponseTime ?? 0; const slotLatency = slot.performance?.p95ResponseTime ?? 0; // Calculate deltas const errorDelta = slotErrors - baselineErrors; const errorDeltaPercent = baselineErrors > 0 ? errorDelta / baselineErrors : (slotErrors > 0 ? 1.0 : 0); // If baseline=0, slot>0 = 100% increase const scoreDelta = slotScore - baselineScore; const latencyDelta = slotLatency - baselineLatency; // Evaluate thresholds const reasons: string[] = []; let decision: 'safe' | 'warning' | 'critical' = 'safe'; // Check error rate increase if (errorDeltaPercent > maxErrorIncrease) { const percentText = (errorDeltaPercent * 100).toFixed(1); reasons.push(`Error rate increased by ${percentText}% (${baselineErrors} → ${slotErrors})`); decision = 'critical'; } // Check health score decrease if (scoreDelta < 0 && Math.abs(scoreDelta) > maxScoreDecrease) { reasons.push(`Health score dropped from ${baselineScore} to ${slotScore} (${scoreDelta} points)`); decision = decision === 'critical' ? 'critical' : 'warning'; } // Check latency increase if (latencyDelta > maxLatencyIncrease) { reasons.push(`P95 latency increased by ${latencyDelta}ms (${baselineLatency}ms → ${slotLatency}ms)`); decision = decision === 'critical' ? 'critical' : 'warning'; } // If no issues found, add positive reasons if (reasons.length === 0) { if (scoreDelta > 0) { reasons.push(`Health score improved from ${baselineScore} to ${slotScore}`); } if (errorDelta <= 0) { reasons.push(`Error rate maintained or decreased (${baselineErrors} → ${slotErrors})`); } if (latencyDelta <= 0) { reasons.push(`Latency maintained or improved (${baselineLatency}ms → ${slotLatency}ms)`); } } // Make recommendation let recommendation: 'proceed' | 'investigate' | 'rollback'; if (decision === 'safe') { recommendation = 'proceed'; } else if (decision === 'warning') { recommendation = 'investigate'; } else { recommendation = 'rollback'; } return { decision, recommendation, baseline: { totalErrors: baselineErrors, healthScore: baselineScore, avgLatency: baseline.performance?.avgResponseTime ?? 0, p95Latency: baselineLatency }, slot: { totalErrors: slotErrors, healthScore: slotScore, avgLatency: slot.performance?.avgResponseTime ?? 0, p95Latency: slotLatency }, deltas: { errorDelta, errorDeltaPercent: parseFloat((errorDeltaPercent * 100).toFixed(2)), scoreDelta, latencyDelta }, reasons, thresholdsApplied: { maxErrorIncrease: maxErrorIncrease * 100, // Convert to percentage for display maxScoreDecrease, maxLatencyIncrease } }; } export default { compareLogs };

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/JaxonDigital/optimizely-dxp-mcp'

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