- Nginx 日志分析查看器 - 单文件 PHP 版
- 基于阿里百炼 Coding Plan + Trae 实战开发
- 来源:https://blog.csdn.net/2403_/article/details/ */
// ==================== 配置区域 ==================== // 配置多个网站日志路径(白名单机制) $LOG_FILES = [
'default' => '/var/log/nginx/access.log', // 示例:'site1' => '/var/log/nginx/site1.access.log', // 示例:'site2' => '/home/wwwlogs/site2.log',
];
// 默认设置 \(DEFAULT_LIMIT = 2000; \)MAX_LIMIT = 10000; $PAGE_SIZE = 100;
// ==================== 安全与工具函数 ==================== error_reporting(0); ini_set(‘display_errors’, 0);
function getParam(\(key, \)default = “)
function validateLogKey(\(key, \)allowed) {
return in_array($key, array_keys($allowed)) ? $key : key($allowed);
}
function parseNginxLogLine(\(line) ):d{2}:d{2}/', \)matches[2], $timeMatch);
$hour = $timeMatch[1] ?? '00'; return [ 'ip' => $matches[1], 'time' => $matches[2], 'hour' => $hour, 'method' => $matches[3], 'uri' => $matches[4], 'status' => (int)$matches[5], 'bytes' => $matches[6] === '-' ? 0 : (int)$matches[6], 'referer' => $matches[7], 'ua' => $ua, 'is_spider' => $isSpider, 'raw' => $line ]; } return null;
}
function readLogLines(\(filepath, \)limit)
if (!is_readable($filepath)) { return ['error' => '文件不可读,请检查权限:' . $filepath]; } $lines = []; $file = new SplFileObject($filepath); $file->seek(PHP_INT_MAX); $total = $file->key(); $start = max(0, $total - $limit); $file->seek($start); while (!$file->eof()) } $file->next(); } return array_reverse($lines);
}
function getStatusCategory($status)
// ==================== 数据处理 ==================== \(logKey = validateLogKey(getParam('log', 'default'), \)LOG_FILES); \(logPath = \)LOG_FILES[\(logKey]; \)limit = min(max(1, (int)getParam(‘limit’, \(DEFAULT_LIMIT)), \)MAX_LIMIT); $page = max(1, (int)getParam(‘page’, 1));
\(logs = []; \)stats = [
'total' => 0, 'unique_ips' => 0, 'spider_count' => 0, 'status_2xx' => 0, 'status_3xx' => 0, 'status_4xx' => 0, 'status_5xx' => 0, 'hours' => array_fill(0, 24, 0), 'top_ips' => [], 'top_uris' => [], 'top_uas' => [], 'top_referers' => [],
];
if (file_exists(\(logPath) && is_readable(\)logPath)) else
if ($log['is_spider']) { $stats['spider_count']++; } $cat = getStatusCategory($log['status']); if (isset($stats['status_' . $cat])) { $stats['status_' . $cat]++; } $hour = (int)$log['hour']; $stats['hours'][$hour]++; } $stats['unique_ips'] = count($ips); arsort($ips); arsort($uris); arsort($uas); arsort($referers); $stats['top_ips'] = array_slice($ips, 0, 10, true); $stats['top_uris'] = array_slice($uris, 0, 10, true); $stats['top_uas'] = array_slice($uas, 0, 10, true); $stats['top_referers'] = array_slice($referers, 0, 10, true); }
}
// 分页计算 \(totalPages = max(1, ceil(count(\)logs) / \(PAGE_SIZE)); \)pageLogs = array_slice(\(logs, (\)page - 1) * \(PAGE_SIZE, \)PAGE_SIZE);
// 筛选参数 \(filterIp = getParam('filter_ip'); \)filterUri = getParam(‘filter_uri’); \(filterStatus = getParam('filter_status'); \)filterSpider = getParam(‘filter_spider’);
\(filteredLogs = \)logs; if ($filterIp) {
$filteredLogs = array_filter($filteredLogs, fn($l) => stripos($l['ip'], $filterIp) !== false);
} if ($filterUri) {
$filteredLogs = array_filter($filteredLogs, fn($l) => stripos($l['uri'], $filterUri) !== false);
} if ($filterStatus) {
$filteredLogs = array_filter($filteredLogs, fn($l) => $l['status'] == $filterStatus);
} if ($filterSpider !== “) {
$isSpiderFilter = $filterSpider === '1'; $filteredLogs = array_filter($filteredLogs, fn($l) => $l['is_spider'] === $isSpiderFilter);
} ?>
Nginx 日志分析查看器
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容,请联系我们,一经查实,本站将立刻删除。
如需转载请保留出处:https://51itzy.com/kjqy/269218.html