Files
easystream-main/f_scripts/analyze_logs.php
SamiAhmed7777 0b7e2d0a5b feat: Add comprehensive documentation suite and reorganize project structure
- Created complete documentation in docs/ directory
- Added PROJECT_OVERVIEW.md with feature highlights and getting started guide
- Added ARCHITECTURE.md with system design and technical details
- Added SECURITY.md with comprehensive security implementation guide
- Added DEVELOPMENT.md with development workflows and best practices
- Added DEPLOYMENT.md with production deployment instructions
- Added API.md with complete REST API documentation
- Added CONTRIBUTING.md with contribution guidelines
- Added CHANGELOG.md with version history and migration notes
- Reorganized all documentation files into docs/ directory for better organization
- Updated README.md with proper documentation links and quick navigation
- Enhanced project structure with professional documentation standards
2025-10-21 00:39:45 -07:00

280 lines
8.9 KiB
PHP

<?php
/*******************************************************************************************************************
| Log Analysis Script
| Analyzes log files and generates reports
|*******************************************************************************************************************/
define('_ISVALID', true);
include_once '../f_core/config.core.php';
class LogAnalyzer
{
private $logDir = '../f_data/logs/';
public function generateReport($days = 7)
{
$report = [
'summary' => $this->getSummary($days),
'errors' => $this->getTopErrors($days),
'security_events' => $this->getSecurityEvents($days),
'performance_issues' => $this->getPerformanceIssues($days),
'user_activity' => $this->getUserActivity($days)
];
return $report;
}
private function getSummary($days)
{
$summary = [
'total_entries' => 0,
'by_level' => [
'error' => 0,
'warning' => 0,
'info' => 0,
'debug' => 0
],
'by_day' => []
];
$cutoffDate = date('Y-m-d', strtotime("-{$days} days"));
$logFiles = glob($this->logDir . '*.log');
foreach ($logFiles as $file) {
$lines = file($file, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
foreach ($lines as $line) {
$entry = json_decode($line, true);
if (!$entry || $entry['timestamp'] < $cutoffDate) continue;
$summary['total_entries']++;
$level = $entry['level'] ?? 'unknown';
if (isset($summary['by_level'][$level])) {
$summary['by_level'][$level]++;
}
$day = date('Y-m-d', strtotime($entry['timestamp']));
$summary['by_day'][$day] = ($summary['by_day'][$day] ?? 0) + 1;
}
}
return $summary;
}
private function getTopErrors($days, $limit = 10)
{
$errors = [];
$cutoffDate = date('Y-m-d', strtotime("-{$days} days"));
$errorFiles = glob($this->logDir . '*_error.log');
foreach ($errorFiles as $file) {
$lines = file($file, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
foreach ($lines as $line) {
$entry = json_decode($line, true);
if (!$entry || $entry['timestamp'] < $cutoffDate) continue;
$message = $entry['message'] ?? 'Unknown error';
$errors[$message] = ($errors[$message] ?? 0) + 1;
}
}
arsort($errors);
return array_slice($errors, 0, $limit, true);
}
private function getSecurityEvents($days)
{
$events = [];
$cutoffDate = date('Y-m-d', strtotime("-{$days} days"));
$logFiles = glob($this->logDir . '*.log');
foreach ($logFiles as $file) {
$lines = file($file, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
foreach ($lines as $line) {
$entry = json_decode($line, true);
if (!$entry || $entry['timestamp'] < $cutoffDate) continue;
if (isset($entry['context']['security_event']) && $entry['context']['security_event']) {
$events[] = [
'timestamp' => $entry['timestamp'],
'message' => $entry['message'],
'ip' => $entry['ip'] ?? 'unknown',
'user_id' => $entry['user_id'] ?? null
];
}
}
}
return array_slice($events, -50); // Last 50 security events
}
private function getPerformanceIssues($days)
{
$issues = [];
$cutoffDate = date('Y-m-d', strtotime("-{$days} days"));
$logFiles = glob($this->logDir . '*.log');
foreach ($logFiles as $file) {
$lines = file($file, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
foreach ($lines as $line) {
$entry = json_decode($line, true);
if (!$entry || $entry['timestamp'] < $cutoffDate) continue;
if (isset($entry['context']['performance_issue']) && $entry['context']['performance_issue']) {
$issues[] = [
'timestamp' => $entry['timestamp'],
'message' => $entry['message'],
'execution_time' => $entry['context']['execution_time'] ?? 0
];
}
}
}
// Sort by execution time (slowest first)
usort($issues, function($a, $b) {
return $b['execution_time'] <=> $a['execution_time'];
});
return array_slice($issues, 0, 20); // Top 20 performance issues
}
private function getUserActivity($days)
{
$activity = [];
$cutoffDate = date('Y-m-d', strtotime("-{$days} days"));
$logFiles = glob($this->logDir . '*.log');
foreach ($logFiles as $file) {
$lines = file($file, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
foreach ($lines as $line) {
$entry = json_decode($line, true);
if (!$entry || $entry['timestamp'] < $cutoffDate) continue;
$userId = $entry['user_id'] ?? null;
if ($userId) {
$activity[$userId] = ($activity[$userId] ?? 0) + 1;
}
}
}
arsort($activity);
return array_slice($activity, 0, 10, true); // Top 10 most active users
}
public function exportReport($format = 'json')
{
$report = $this->generateReport();
switch ($format) {
case 'json':
return json_encode($report, JSON_PRETTY_PRINT);
case 'html':
return $this->generateHTMLReport($report);
case 'csv':
return $this->generateCSVReport($report);
default:
return $report;
}
}
private function generateHTMLReport($report)
{
$html = '<!DOCTYPE html>
<html>
<head>
<title>Log Analysis Report</title>
<style>
body { font-family: Arial, sans-serif; margin: 20px; }
.section { margin-bottom: 30px; }
table { border-collapse: collapse; width: 100%; }
th, td { border: 1px solid #ddd; padding: 8px; text-align: left; }
th { background-color: #f2f2f2; }
.error { color: #f44336; }
.warning { color: #ff9800; }
.info { color: #2196f3; }
</style>
</head>
<body>
<h1>Log Analysis Report</h1>
<p>Generated on: ' . date('Y-m-d H:i:s') . '</p>
<div class="section">
<h2>Summary</h2>
<p>Total log entries: ' . $report['summary']['total_entries'] . '</p>
<table>
<tr><th>Level</th><th>Count</th></tr>';
foreach ($report['summary']['by_level'] as $level => $count) {
$html .= "<tr><td class=\"{$level}\">{$level}</td><td>{$count}</td></tr>";
}
$html .= '</table>
</div>
<div class="section">
<h2>Top Errors</h2>
<table>
<tr><th>Error Message</th><th>Count</th></tr>';
foreach ($report['errors'] as $error => $count) {
$html .= '<tr><td>' . htmlspecialchars($error) . '</td><td>' . $count . '</td></tr>';
}
$html .= '</table>
</div>
<div class="section">
<h2>Recent Security Events</h2>
<table>
<tr><th>Timestamp</th><th>Event</th><th>IP</th><th>User ID</th></tr>';
foreach (array_slice($report['security_events'], -10) as $event) {
$html .= '<tr>
<td>' . $event['timestamp'] . '</td>
<td>' . htmlspecialchars($event['message']) . '</td>
<td>' . $event['ip'] . '</td>
<td>' . ($event['user_id'] ?: 'Guest') . '</td>
</tr>';
}
$html .= '</table>
</div>
</body>
</html>';
return $html;
}
}
// CLI usage
if (php_sapi_name() === 'cli') {
$analyzer = new LogAnalyzer();
$format = $argv[1] ?? 'json';
$days = (int)($argv[2] ?? 7);
echo $analyzer->exportReport($format);
} else {
// Web usage
$analyzer = new LogAnalyzer();
$format = $_GET['format'] ?? 'html';
$days = (int)($_GET['days'] ?? 7);
if ($format === 'html') {
echo $analyzer->exportReport($format);
} else {
header('Content-Type: application/json');
echo $analyzer->exportReport('json');
}
}
?>