Log Parser

True\LogParser reads Apache combined-format access logs — plain or .gz compressed — and turns each line into a structured object. It implements Iterator so you can foreach straight over the file without holding the whole thing in memory.

Iterating a log file

use True\LogParser;

$log = new LogParser('/var/log/apache2/access.log');

foreach ($log as $entry) {
    echo "{$entry->ip}  {$entry->datetime}  {$entry->type} {$entry->page}  {$entry->code}\n";
}

Rotated logs work the same way — pass a .gz path and the parser decompresses it on the fly:

$log = new LogParser('/var/log/apache2/access.log.2024-04-01.gz');
foreach ($log as $entry) { /* ... */ }

Entry shape

Each entry is an object with these properties:

PropertyDescription
ipClient IP address.
datetimeAccess time in Y-m-d H:i:s format.
typeHTTP method (GET, POST, …).
pageRequested path / resource.
codeHTTP status code.
sizeResponse size in bytes.
refererReferer URL.
clientUser-Agent string.

Common patterns

Top IPs by hit count

$counts = [];
foreach (new LogParser('/var/log/apache2/access.log') as $entry) {
    $counts[$entry->ip] = ($counts[$entry->ip] ?? 0) + 1;
}
arsort($counts);
print_r(array_slice($counts, 0, 10, true));

404s with referers

foreach (new LogParser('/var/log/apache2/access.log') as $entry) {
    if ($entry->code === '404') {
        echo "{$entry->page}  <-  {$entry->referer}\n";
    }
}

Re-parse without recreating

The class also exposes parse($logFile) if you want to load a different file onto the same instance:

$log->parse('/var/log/apache2/access.log.1.gz');