PHP 怎么PHP 日志分析

wen PHP项目 2

本文目录导读:

PHP 怎么PHP 日志分析

  1. 常见PHP日志类型
  2. 日志分析工具
  3. 高级分析技术
  4. 可视化分析
  5. 实时监控
  6. 最佳实践
  7. 常用分析命令
  8. 自动化脚本示例

我来详细介绍PHP日志分析的完整方法:

常见PHP日志类型

错误日志

// php.ini配置
error_reporting = E_ALL
display_errors = Off
log_errors = On
error_log = /var/log/php_errors.log

访问日志

通常由Web服务器(Nginx/Apache)记录

日志分析工具

命令行工具

# 实时查看日志
tail -f /var/log/php_errors.log
# 查找错误
grep "PHP Fatal error" /var/log/php_errors.log
# 统计错误类型
awk -F':' '{print $2}' /var/log/php_errors.log | sort | uniq -c
# 按时间查看
awk '/2024-01-15/ {print}' /var/log/php_errors.log

使用PHP分析日志

<?php
class LogAnalyzer {
    private $logFile;
    public function __construct($logFile) {
        $this->logFile = $logFile;
    }
    // 分析错误类型统计
    public function analyzeErrorTypes() {
        $errors = [];
        $handle = fopen($this->logFile, 'r');
        while (($line = fgets($handle)) !== false) {
            if (preg_match('/PHP (.*?):/', $line, $matches)) {
                $type = $matches[1];
                $errors[$type] = ($errors[$type] ?? 0) + 1;
            }
        }
        fclose($handle);
        return $errors;
    }
    // 按时间范围查询
    public function getLogsByDate($startDate, $endDate) {
        $logs = [];
        $handle = fopen($this->logFile, 'r');
        while (($line = fgets($handle)) !== false) {
            if (preg_match('/\[(.*?)\]/', $line, $matches)) {
                $date = $matches[1];
                if ($date >= $startDate && $date <= $endDate) {
                    $logs[] = $line;
                }
            }
        }
        fclose($handle);
        return $logs;
    }
}
// 使用示例
$analyzer = new LogAnalyzer('/var/log/php_errors.log');
print_r($analyzer->analyzeErrorTypes());
?>

高级分析技术

使用正则表达式提取信息

<?php
function parsePhpLogLine($line) {
    $pattern = '/^\[(\d{2}-\w{3}-\d{4} \d{2}:\d{2}:\d{2} UTC)\] PHP (.+?): (.+?) in (.+?) on line (\d+)$/';
    if (preg_match($pattern, $line, $matches)) {
        return [
            'timestamp' => $matches[1],
            'error_type' => $matches[2],
            'message' => $matches[3],
            'file' => $matches[4],
            'line' => (int)$matches[5]
        ];
    }
    return null;
}
?>

聚合分析

<?php
function aggregateErrors($logFile) {
    $errorsByFile = [];
    $errorsByType = [];
    $handle = fopen($logFile, 'r');
    while (($line = fgets($handle)) !== false) {
        $parsed = parsePhpLogLine($line);
        if (!$parsed) continue;
        // 按文件聚合
        $file = $parsed['file'];
        $errorsByFile[$file] = ($errorsByFile[$file] ?? 0) + 1;
        // 按错误类型聚合
        $type = $parsed['error_type'];
        $errorsByType[$type] = ($errorsByType[$type] ?? 0) + 1;
    }
    fclose($handle);
    return [
        'by_file' => $errorsByFile,
        'by_type' => $errorsByType
    ];
}
?>

可视化分析

生成简单报告

<?php
function generateReport($logFile, $outputFile) {
    $analyzer = new LogAnalyzer($logFile);
    // 获取分析结果
    $errorsByType = $analyzer->analyzeErrorTypes();
    arsort($errorsByType);
    // 生成HTML报告
    $html = "<html><head><title>PHP Error Report</title></head><body>";
    $html .= "<h1>PHP Error Analysis Report</h1>";
    $html .= "<table border='1'>";
    $html .= "<tr><th>Error Type</th><th>Count</th></tr>";
    foreach ($errorsByType as $type => $count) {
        $html .= "<tr><td>$type</td><td>$count</td></tr>";
    }
    $html .= "</table></body></html>";
    file_put_contents($outputFile, $html);
}
?>

实时监控

使用PHP Socket实时监控

<?php
function tailLog($logFile) {
    $handle = fopen($logFile, 'r');
    // 移动到文件末尾
    fseek($handle, 0, SEEK_END);
    while (true) {
        usleep(100000); // 100ms
        clearstatcache();
        $currentPos = ftell($handle);
        $fileSize = filesize($logFile);
        if ($fileSize < $currentPos) {
            // 文件被截断或轮转
            fclose($handle);
            $handle = fopen($logFile, 'r');
            continue;
        }
        while (($line = fgets($handle)) !== false) {
            if (strpos($line, 'PHP Fatal error') !== false) {
                // 发送警报
                sendAlert($line);
            }
        }
    }
}
?>

最佳实践

日志规范化

<?php
// 自定义日志记录
function customLogger($message, $level = 'INFO') {
    $logFormat = "[%s] [%s] %s - %s - Line: %d\n";
    $backtrace = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 1);
    $caller = $backtrace[0];
    $logEntry = sprintf(
        $logFormat,
        date('Y-m-d H:i:s'),
        $level,
        $_SERVER['REMOTE_ADDR'] ?? 'CLI',
        $message,
        $caller['line'] ?? 'N/A'
    );
    error_log($logEntry, 3, '/var/log/custom_app.log');
}
?>

日志轮转配置

; php.ini
log_rotate_max_files = 10
log_rotate_size = 100M

常用分析命令

# 统计各错误类型数量
awk '{print $4}' /var/log/php_errors.log | sort | uniq -c | sort -rn
# 获取最常出错的10个文件
grep -oP "in \K[^:]+" /var/log/php_errors.log | sort | uniq -c | sort -rn | head -10
# 查看特定日期的错误
grep "15/Jan/2024" /var/log/php_errors.log
# 监控并过滤特定错误
tail -f /var/log/php_errors.log | grep -i "database\|timeout\|fatal"

自动化脚本示例

<?php
// 自动清理和归档旧日志
$logFile = '/var/log/php_errors.log';
$archiveDir = '/var/log/archive/';
$maxSize = 100 * 1024 * 1024; // 100MB
if (file_exists($logFile) && filesize($logFile) > $maxSize) {
    $archiveName = $archiveDir . 'php_errors_' . date('Ymd_His') . '.log';
    rename($logFile, $archiveName);
    // 压缩归档
    exec("gzip $archiveName");
    // 创建新日志文件
    file_put_contents($logFile, '');
    chmod($logFile, 0644);
}
?>

通过以上方法,你可以有效地分析PHP日志,快速定位问题,并建立完善的日志监控系统,根据实际需求选择合适的分析工具和方法。

抱歉,评论功能暂时关闭!