Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions src/Rap2hpoutre/LaravelLogViewer/LaravelLogViewer.php
Original file line number Diff line number Diff line change
Expand Up @@ -184,8 +184,9 @@ public function all()
foreach ($headings as $h) {
for ($i = 0, $j = count($h); $i < $j; $i++) {
foreach ($this->level->all() as $level) {
if (strpos(strtolower($h[$i]), '.' . $level) || strpos(strtolower($h[$i]), $level . ':')) {

// Check if level appears in correct position (after context or right after timestamp)
$levelPattern = '/\]\s*(?:\w+\.)?' . preg_quote($level, '/') . ':/i';
if (preg_match($levelPattern, $h[$i])) {
preg_match($this->pattern->getPattern('current_log', 0) . $level . $this->pattern->getPattern('current_log', 1), $h[$i], $current);
if (!isset($current[4])) {
continue;
Expand Down
72 changes: 61 additions & 11 deletions tests/LaravelLogViewerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -48,24 +48,24 @@ public function testSetFolderWithCorrectPath()
public function testSetFolderWithArrayStoragePath()
{
$path = __DIR__;

$laravel_log_viewer = new LaravelLogViewer();
$laravel_log_viewer->setStoragePath([$path]);
if(!File::exists("$path/samuel")) File::makeDirectory("$path/samuel");
$laravel_log_viewer->setFolder('samuel');

$this->assertEquals("samuel", $laravel_log_viewer->getFolderName());

}

public function testSetFolderWithDefaultStoragePath()
{

$laravel_log_viewer = new LaravelLogViewer();
$laravel_log_viewer->setStoragePath(storage_path());
$laravel_log_viewer->setFolder('logs');


$this->assertEquals("logs", $laravel_log_viewer->getFolderName());

}
Expand All @@ -84,7 +84,7 @@ public function testPathToLogFile()

$laravel_log_viewer = new LaravelLogViewer();
$pathToLogFile = $laravel_log_viewer->pathToLogFile(storage_path(('logs/laravel.log')));

$this->assertEquals($pathToLogFile, storage_path('logs/laravel.log'));
}

Expand Down Expand Up @@ -126,7 +126,7 @@ public function testAllWithEmptyFileName()
{
$laravel_log_viewer = new LaravelLogViewer();
$laravel_log_viewer->setStoragePath(__DIR__);

$data = $laravel_log_viewer->all();
$this->assertEquals('local', $data[0]['context']);
$this->assertEquals('error', $data[0]['level']);
Expand All @@ -144,7 +144,7 @@ public function testFolderFiles()

$this->assertIsArray($data);
$this->assertNotEmpty($data);

$this->assertStringContainsString('tests', $data[count(explode($data[0], '/')) - 1]);
}

Expand All @@ -153,7 +153,7 @@ public function testGetFolderFiles()
$laravel_log_viewer = new LaravelLogViewer();
$laravel_log_viewer->setStoragePath(__DIR__);
$data = $laravel_log_viewer->getFolderFiles();

$this->assertIsArray($data);
$this->assertNotEmpty($data, "Folder files is null");
}
Expand All @@ -163,7 +163,7 @@ public function testGetFiles()
$laravel_log_viewer = new LaravelLogViewer();
$laravel_log_viewer->setStoragePath(storage_path());
$data = $laravel_log_viewer->getFiles();

$this->assertIsArray($data);
$this->assertNotEmpty($data, "Folder files is null");
}
Expand All @@ -173,7 +173,7 @@ public function testGetFolders()
$laravel_log_viewer = new LaravelLogViewer();
$laravel_log_viewer->setStoragePath(storage_path());
$data = $laravel_log_viewer->getFolders();

$this->assertIsArray($data);
$this->assertNotEmpty($data, "files is null");
}
Expand All @@ -184,10 +184,60 @@ public function testDirectoryStructure()
ob_start();
$log_viewer->directoryTreeStructure(storage_path('logs'), $log_viewer->foldersAndFiles());
$data = ob_get_clean();

$this->assertIsString($data);
$this->assertNotEmpty($data);
}

/**
* Test that level names appearing in log message text are not incorrectly
* parsed as separate log levels. This tests the fix for the bug where
* words like "processed" or "failed" in messages were creating false log entries.
*/
public function testLevelNamesInMessageTextNotParsedAsLevels()
{
// Create a temporary log file with entries containing level names in the message
$testLogPath = storage_path('logs/test-level-parsing.log');
$testLogContent = <<<'LOG'
[2025-10-28 20:59:22] local.INFO: Redirect map successfully rebuilt and cached. Entries processed: 6866, Aliases mapped: 15918
[2025-10-28 20:59:23] local.WARNING: Job processing failed with error code 500
[2025-10-28 20:59:24] local.DEBUG: Processing diagnostic information
LOG;

File::put($testLogPath, $testLogContent);

try {
$laravel_log_viewer = new LaravelLogViewer();
$laravel_log_viewer->setFile($testLogPath);
$data = $laravel_log_viewer->all();

// Should only have 3 log entries (not more due to false "processed" or "failed" matches)
$this->assertCount(3, $data, 'Should only parse 3 log entries, not create false entries from level names in message text');

// Verify the first entry is correctly parsed as INFO level, not "processed"
$this->assertEquals('info', $data[2]['level'], 'First entry should be INFO level');
$this->assertEquals('local', $data[2]['context']);
$this->assertStringContainsString('Entries processed: 6866', $data[2]['text'], 'Message text should contain "processed" but not be parsed as a level');

// Verify the second entry is correctly parsed as WARNING level, not "failed"
$this->assertEquals('warning', $data[1]['level'], 'Second entry should be WARNING level');
$this->assertEquals('local', $data[1]['context']);
$this->assertStringContainsString('Job processing failed', $data[1]['text'], 'Message text should contain "failed" but not be parsed as a level');

// Verify the third entry is correctly parsed as DEBUG level
$this->assertEquals('debug', $data[0]['level'], 'Third entry should be DEBUG level');

// Ensure no entries have "processed" or "failed" as their level
foreach ($data as $entry) {
$this->assertNotEquals('processed', $entry['level'], 'No entry should have "processed" as a level');
$this->assertNotEquals('failed', $entry['level'], 'No entry should have "failed" as a level');
}
} finally {
// Clean up the test log file
if (File::exists($testLogPath)) {
File::delete($testLogPath);
}
}
}

}