Summary
Opening a Laravel daily log file in Log Viewer returns HTTP 500 when the indexed entry is corrupt (e.g. a run of null bytes \x00). The UI fails for the whole file, not just that entry.
Environment
opcodesio/log-viewer v3.24.2
- Laravel 13 / PHP 8.5
- Shared RWX volume with concurrent writers (daily log under
storage/logs/...)
Error
ErrorException: Undefined array key 1 at vendor/opcodesio/log-viewer/src/Logs/LaravelLog.php:41
Relevant stack (abridged):
Opcodes\LogViewer\Logs\LaravelLog->parseText() Opcodes\LogViewer\Logs\Log->__construct('\x00\x00\x00...', ..., $filePosition, $index) Opcodes\LogViewer\Readers\IndexedLogReader->next() Opcodes\LogViewer\Http\Controllers\LogsController->index()
In our case the constructed text was ~328 null bytes at file offset ~512608.
Root cause
In LaravelLog::parseText():
preg_match(static::regexPattern(), array_shift($firstLineSplit), $matches);
$this->datetime = Carbon::parse($matches[1])?->setTimezone(LogViewer::timezone());
If preg_match fails (corrupt / binary / non-Laravel chunk), $matches[1] is undefined. Laravel turns that into an ErrorException, which bubbles up as a 500 on GET /log-viewer/api/logs.
Also, IndexedLogReader::next() only skips empty($text). A string of \x00 is not empty in PHP, so the corrupt chunk is still passed to the parser.
Expected behaviour
Corrupt or non-matching chunks should not take down the API. Prefer one of:
Treat as an unparseable entry (level none, message like [unparseable log entry]), or
Skip the entry and continue pagination
Valid Laravel lines should keep working unchanged.
Suggested fix
Guard before using $matches[1], e.g.:
if text is empty / only null bytes & whitespace → mark unparseable and return
if preg_match(...) !== 1 → mark unparseable and return (do not call Carbon::parse($matches[1]))
Happy to open a PR if that approach works for you.
Workaround
We temporarily register a subclass via LogViewer::extend('laravel', ResilientLaravelLog::class) that catches this case locally.
Summary
Opening a Laravel daily log file in Log Viewer returns HTTP 500 when the indexed entry is corrupt (e.g. a run of null bytes
\x00). The UI fails for the whole file, not just that entry.Environment
opcodesio/log-viewerv3.24.2storage/logs/...)Error
ErrorException: Undefined array key 1 at vendor/opcodesio/log-viewer/src/Logs/LaravelLog.php:41
Relevant stack (abridged):
Opcodes\LogViewer\Logs\LaravelLog->parseText() Opcodes\LogViewer\Logs\Log->__construct('\x00\x00\x00...', ..., $filePosition, $index) Opcodes\LogViewer\Readers\IndexedLogReader->next() Opcodes\LogViewer\Http\Controllers\LogsController->index()
In our case the constructed text was ~328 null bytes at file offset ~512608.
Root cause
In
LaravelLog::parseText():