PHP LogoLog Analysis Tool

A Log Analysis Tool is a software application or a script designed to process, parse, filter, and extract meaningful information from log files generated by various systems, applications, and networks. Log files are chronological records of events, errors, warnings, and informational messages that provide insights into the operational behavior and health of a system.

Importance:
Log analysis is crucial for:
* Debugging and Troubleshooting: Quickly identifying the root cause of issues, errors, or crashes by examining the sequence of events leading up to a problem.
* Performance Monitoring: Tracking application response times, resource utilization, and identifying bottlenecks.
* Security Auditing: Detecting suspicious activities, unauthorized access attempts, or potential security breaches.
* System Health Monitoring: Gaining a real-time or historical overview of system stability and identifying trends.
* Compliance: Fulfilling regulatory requirements by maintaining and analyzing audit trails.

Core Functionalities:
Common features of a log analysis tool include:
* Log Ingestion: Reading log data from various sources (files, databases, streams).
* Parsing: Structuring unstructured log lines into identifiable fields (timestamp, level, message, source, etc.). This often involves regular expressions.
* Filtering: Displaying only relevant log entries based on criteria like log level (e.g., ERROR, WARNING), keywords, time range, or source.
* Searching: Allowing users to find specific patterns or keywords across large volumes of logs.
* Aggregation: Summarizing log data, such as counting occurrences of certain events or calculating averages.
* Visualization: Presenting aggregated data through graphs, charts, and dashboards for easier interpretation.
* Alerting: Notifying administrators when specific critical events or thresholds are met.
* Real-time vs. Batch Analysis: Some tools process logs as they are generated (real-time), while others analyze historical data (batch).

In essence, a log analysis tool transforms raw, often overwhelming, log data into actionable intelligence, helping maintain robust, secure, and performant systems.

Example Code

<?php

class LogAnalyzer {
    private $logFilePath;

    public function __construct($logFilePath) {
        if (!file_exists($logFilePath)) {
            throw new Exception("Log file not found at: " . $logFilePath);
        }
        $this->logFilePath = $logFilePath;
    }

    /
     * Reads and filters log entries based on level.
     *
     * @param string $filterLevel The log level to filter by (e.g., 'INFO', 'WARNING', 'ERROR'). Case-insensitive.
     * @param int $limit Optional. Maximum number of entries to return.
     * @return array An array of matching log entries.
     */
    public function analyzeByLevel($filterLevel, $limit = null) {
        $filteredEntries = [];
        $handle = fopen($this->logFilePath, "r");

        if ($handle) {
            $count = 0;
            while (($line = fgets($handle)) !== false) {
                // Example log format: [YYYY-MM-DD HH:MM:SS] [LEVEL] MESSAGE
                // Regex to capture timestamp, level, and message.
                // The \[ and \] are literal square brackets in the regex.
                if (preg_match('/^\[(.*?)\] \[(.*?)\] (.*)$/', trim($line), $matches)) {
                    $timestamp = $matches[1];
                    $level = strtoupper($matches[2]); // Convert to uppercase for consistent comparison
                    $message = $matches[3];

                    if (strtoupper($filterLevel) === $level) {
                        $filteredEntries[] = [
                            'timestamp' => $timestamp,
                            'level' => $level,
                            'message' => $message
                        ];
                        $count++;
                        if ($limit !== null && $count >= $limit) {
                            break;
                        }
                    }
                }
            }
            fclose($handle);
        } else {
            throw new Exception("Could not open log file: " . $this->logFilePath);
        }

        return $filteredEntries;
    }

    /
     * Counts occurrences of log levels.
     * @return array An associative array where keys are log levels and values are their counts.
     */
    public function countLevels() {
        $levelCounts = [];
        $handle = fopen($this->logFilePath, "r");

        if ($handle) {
            while (($line = fgets($handle)) !== false) {
                if (preg_match('/^\[(.*?)\] \[(.*?)\] (.*)$/', trim($line), $matches)) {
                    $level = strtoupper($matches[2]);
                    $levelCounts[$level] = ($levelCounts[$level] ?? 0) + 1;
                }
            }
            fclose($handle);
        } else {
            throw new Exception("Could not open log file for counting: " . $this->logFilePath);
        }

        return $levelCounts;
    }
}

// --- Example Usage ---

// 1. Create a dummy log file for testing
$logFileName = 'application.log';
file_put_contents($logFileName, ''); // Clear existing content
file_put_contents($logFileName, "[2023-10-27 10:00:01] [INFO] User 'alice' logged in.\n", FILE_APPEND);
file_put_contents($logFileName, "[2023-10-27 10:00:15] [DEBUG] Processing request ID: 12345.\n", FILE_APPEND);
file_put_contents($logFileName, "[2023-10-27 10:01:30] [WARNING] Disk space getting low (85% used).\n", FILE_APPEND);
file_put_contents($logFileName, "[2023-10-27 10:02:05] [ERROR] Database connection failed for user 'db_user'.\n", FILE_APPEND);
file_put_contents($logFileName, "[2023-10-27 10:03:10] [INFO] Data synchronization complete.\n", FILE_APPEND);
file_put_contents($logFileName, "[2023-10-27 10:04:20] [WARNING] High CPU usage detected (92%).\n", FILE_APPEND);
file_put_contents($logFileName, "[2023-10-27 10:05:00] [ERROR] API endpoint 'auth_service' returned 500.\n", FILE_APPEND);
file_put_contents($logFileName, "[2023-10-27 10:06:00] [INFO] User 'bob' logged out.\n", FILE_APPEND);


try {
    $analyzer = new LogAnalyzer($logFileName);

    echo "<h3>Analysis by Log Level: ERROR</h3>";
    $errorLogs = $analyzer->analyzeByLevel('ERROR');
    if (empty($errorLogs)) {
        echo "<p>No ERROR logs found.</p>";
    } else {
        foreach ($errorLogs as $entry) {
            echo "<p><b>[{$entry['level']}]</b> {$entry['timestamp']} - {$entry['message']}</p>";
        }
    }

    echo "<h3>Analysis by Log Level: WARNING (Limited to 1 entry)</h3>";
    $warningLogs = $analyzer->analyzeByLevel('WARNING', 1);
    if (empty($warningLogs)) {
        echo "<p>No WARNING logs found.</p>";
    } else {
        foreach ($warningLogs as $entry) {
            echo "<p><b>[{$entry['level']}]</b> {$entry['timestamp']} - {$entry['message']}</p>";
        }
    }

    echo "<h3>Log Level Counts</h3>";
    $levelCounts = $analyzer->countLevels();
    if (empty($levelCounts)) {
        echo "<p>No log entries processed.</p>";
    } else {
        echo "<ul>";
        foreach ($levelCounts as $level => $count) {
            echo "<li><b>{$level}:</b> {$count}</li>";
        }
        echo "</ul>";
    }

} catch (Exception $e) {
    echo "<p>Error: " . $e->getMessage() . "</p>";
}

// Clean up the dummy log file after testing (uncomment to enable)
// unlink($logFileName);

?>