errorsByLevel['emergency'] ?? 0) + ($this->errorsByLevel['alert'] ?? 0) + ($this->errorsByLevel['critical'] ?? 0); } /** * Get error rate as percentage */ public function getErrorRatePercentage(): float { return round($this->errorRate * 100, 2); } /** * Get most problematic route */ public function getMostProblematicRoute(): ?array { if (empty($this->errorsByRoute)) { return null; } $route = array_key_first($this->errorsByRoute); $count = reset($this->errorsByRoute); return [ 'route' => $route, 'count' => $count, 'percentage' => $this->totalErrors > 0 ? round(($count / $this->totalErrors) * 100, 2) : 0, ]; } /** * Get most frequent exception */ public function getMostFrequentException(): ?array { if (empty($this->errorsByException)) { return null; } $exception = array_key_first($this->errorsByException); $count = reset($this->errorsByException); return [ 'exception' => $exception, 'count' => $count, 'percentage' => $this->totalErrors > 0 ? round(($count / $this->totalErrors) * 100, 2) : 0, ]; } /** * Get peak error hour */ public function getPeakErrorHour(): ?array { if (empty($this->errorsByHour)) { return null; } $hour = array_key_first($this->errorsByHour); $count = reset($this->errorsByHour); return [ 'hour' => $hour, 'count' => $count, 'time' => sprintf('%02d:00', $hour), ]; } /** * Get error trend direction */ public function getErrorTrend(): string { if (count($this->errorsByDay) < 2) { return 'stable'; } $days = array_values($this->errorsByDay); $recent = array_slice($days, -3); // Last 3 days $previous = array_slice($days, -6, 3); // Previous 3 days if (empty($recent) || empty($previous)) { return 'stable'; } $recentAvg = array_sum($recent) / count($recent); $previousAvg = array_sum($previous) / count($previous); $change = $previousAvg > 0 ? (($recentAvg - $previousAvg) / $previousAvg) * 100 : 0; if ($change > 20) { return 'increasing'; } elseif ($change < -20) { return 'decreasing'; } else { return 'stable'; } } /** * Get error distribution health score (0-100) */ public function getHealthScore(): int { $score = 100; // Penalize high error rates if ($this->errorRate > 0.05) { // > 5% $score -= 30; } elseif ($this->errorRate > 0.02) { // > 2% $score -= 15; } elseif ($this->errorRate > 0.01) { // > 1% $score -= 5; } // Penalize critical errors $criticalCount = $this->getCriticalErrorCount(); if ($criticalCount > 0) { $score -= min(40, $criticalCount * 5); } // Penalize trending up if ($this->getErrorTrend() === 'increasing') { $score -= 15; } // Penalize concentrated errors (single route causing many errors) $topRoute = $this->getMostProblematicRoute(); if ($topRoute && $topRoute['percentage'] > 50) { $score -= 10; } return max(0, $score); } /** * Get insights and recommendations */ public function getInsights(): array { $insights = []; // Critical error insight $criticalCount = $this->getCriticalErrorCount(); if ($criticalCount > 0) { $insights[] = [ 'type' => 'critical', 'message' => "Found {$criticalCount} critical errors that require immediate attention.", 'priority' => 'high', ]; } // Error rate insight if ($this->errorRate > 0.05) { $insights[] = [ 'type' => 'error_rate', 'message' => sprintf('Error rate is %.2f%%, which is above the recommended threshold of 2%%.', $this->getErrorRatePercentage()), 'priority' => 'high', ]; } // Route concentration insight $topRoute = $this->getMostProblematicRoute(); if ($topRoute && $topRoute['percentage'] > 40) { $insights[] = [ 'type' => 'route_concentration', 'message' => sprintf('Route "%s" accounts for %.1f%% of all errors. Consider reviewing this endpoint.', $topRoute['route'], $topRoute['percentage']), 'priority' => 'medium', ]; } // Exception concentration insight $topException = $this->getMostFrequentException(); if ($topException && $topException['percentage'] > 50) { $insights[] = [ 'type' => 'exception_concentration', 'message' => sprintf('Exception "%s" accounts for %.1f%% of all errors. This indicates a systemic issue.', basename($topException['exception']), $topException['percentage']), 'priority' => 'medium', ]; } // Trend insight $trend = $this->getErrorTrend(); if ($trend === 'increasing') { $insights[] = [ 'type' => 'trend', 'message' => 'Error trend is increasing over the last few days. Monitor closely.', 'priority' => 'medium', ]; } elseif ($trend === 'decreasing') { $insights[] = [ 'type' => 'trend', 'message' => 'Error trend is decreasing. Good progress!', 'priority' => 'low', ]; } // No errors insight if ($this->totalErrors === 0) { $insights[] = [ 'type' => 'no_errors', 'message' => 'No errors recorded in this period. System is operating smoothly.', 'priority' => 'low', ]; } return $insights; } /** * Convert to array */ public function toArray(): array { return [ 'total_errors' => $this->totalErrors, 'unique_errors' => $this->uniqueErrors, 'errors_by_level' => $this->errorsByLevel, 'errors_by_exception' => $this->errorsByException, 'errors_by_route' => $this->errorsByRoute, 'errors_by_user' => $this->errorsByUser, 'errors_by_hour' => $this->errorsByHour, 'errors_by_day' => $this->errorsByDay, 'top_errors' => $this->topErrors, 'trending_errors' => $this->trendingErrors, 'error_rate' => $this->errorRate, 'error_rate_percentage' => $this->getErrorRatePercentage(), 'response_time_impact' => $this->responseTimeImpact, 'environment_breakdown' => $this->environmentBreakdown, 'period_start' => $this->periodStart->format('c'), 'period_end' => $this->periodEnd->format('c'), 'critical_error_count' => $this->getCriticalErrorCount(), 'most_problematic_route' => $this->getMostProblematicRoute(), 'most_frequent_exception' => $this->getMostFrequentException(), 'peak_error_hour' => $this->getPeakErrorHour(), 'error_trend' => $this->getErrorTrend(), 'health_score' => $this->getHealthScore(), 'insights' => $this->getInsights(), ]; } }