From 55ab7c533808c6696fdec9b49de220dea781d66b Mon Sep 17 00:00:00 2001 From: Arunas Skirius Date: Sat, 18 Oct 2025 11:52:23 +0300 Subject: [PATCH 1/8] Add tests for stack trace filtering in context Tests verify that context string values are filtered when shorter stack traces feature is enabled, ensuring vendor paths are replaced with ellipsis while app paths remain. --- tests/Unit/LaravelLogs/LaravelLogsTest.php | 61 ++++++++++++++++++++++ 1 file changed, 61 insertions(+) diff --git a/tests/Unit/LaravelLogs/LaravelLogsTest.php b/tests/Unit/LaravelLogs/LaravelLogsTest.php index 65de5bcc..99eae2cf 100644 --- a/tests/Unit/LaravelLogs/LaravelLogsTest.php +++ b/tests/Unit/LaravelLogs/LaravelLogsTest.php @@ -255,3 +255,64 @@ 'size_formatted' => Utils::bytesForHumans(strlen($messageString) - strlen('[2023-08-24 15:51:14] local.DEBUG: ')), ]); }); + +it('filters stack traces in context when shorter stack traces is enabled', function () { + session(['log-viewer:shorter-stack-traces' => true]); + config([ + 'log-viewer.shorter_stack_trace_excludes' => [ + '/vendor/symfony/', + '/vendor/laravel/framework/', + ], + ]); + + $stackTrace = <<<'EOF' +#0 /app/Controllers/UserController.php(25): someFunction() +#1 /vendor/symfony/http-kernel/HttpKernel.php(158): handle() +#2 /vendor/laravel/framework/Illuminate/Pipeline/Pipeline.php(128): process() +#3 /app/Middleware/CustomMiddleware.php(42): handle() +#4 /vendor/symfony/routing/Router.php(89): route() +#5 /app/bootstrap/app.php(15): bootstrap() +EOF; + + $logText = <<context)->toHaveKey('exception') + ->and($log->context['exception'])->toContain('#0 /app/Controllers/UserController.php(25): someFunction()') + ->and($log->context['exception'])->toContain('#3 /app/Middleware/CustomMiddleware.php(42): handle()') + ->and($log->context['exception'])->toContain('#5 /app/bootstrap/app.php(15): bootstrap()') + ->and($log->context['exception'])->toContain(' ...') + ->and($log->context['exception'])->not->toContain('/vendor/symfony/http-kernel/') + ->and($log->context['exception'])->not->toContain('/vendor/laravel/framework/') + ->and($log->context['exception'])->not->toContain('/vendor/symfony/routing/'); +}); + +it('does not filter context when shorter stack traces is disabled', function () { + session(['log-viewer:shorter-stack-traces' => false]); + config([ + 'log-viewer.shorter_stack_trace_excludes' => [ + '/vendor/symfony/', + '/vendor/laravel/framework/', + ], + ]); + + $stackTrace = <<<'EOF' +#0 /app/Controllers/UserController.php(25): someFunction() +#1 /vendor/symfony/http-kernel/HttpKernel.php(158): handle() +#2 /vendor/laravel/framework/Illuminate/Pipeline/Pipeline.php(128): process() +EOF; + + $logText = <<context)->toHaveKey('exception') + ->and($log->context['exception'])->toBe($stackTrace) + ->and($log->context['exception'])->toContain('/vendor/symfony/http-kernel/') + ->and($log->context['exception'])->toContain('/vendor/laravel/framework/'); +}); From 84db08b011da1bd02184bfe0492390ac0488bb61 Mon Sep 17 00:00:00 2001 From: Arunas Skirius Date: Sat, 18 Oct 2025 11:59:21 +0300 Subject: [PATCH 2/8] Normalize line endings for cross-platform compatibility Fixes Windows test failures by converting CRLF and CR line endings to LF before processing stack traces. --- src/Logs/LaravelLog.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/Logs/LaravelLog.php b/src/Logs/LaravelLog.php index e6e48060..f6a3b6a9 100644 --- a/src/Logs/LaravelLog.php +++ b/src/Logs/LaravelLog.php @@ -193,6 +193,10 @@ protected function getJsonStringsFromFullText(): array protected function filterStackTrace(string $text): string { + // Normalize line endings for cross-platform compatibility + $text = str_replace("\r\n", "\n", $text); + $text = str_replace("\r", "\n", $text); + $lines = explode("\n", $text); $filteredLines = []; $emptyLineCharacter = ' ...'; From b5b6e2ee1f0577f375ef1556d63e147fe8e6e4b5 Mon Sep 17 00:00:00 2001 From: Arunas Skirius Date: Sat, 18 Oct 2025 12:01:23 +0300 Subject: [PATCH 3/8] update gitignore --- .gitignore | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/.gitignore b/.gitignore index 772e1015..441f5b5d 100644 --- a/.gitignore +++ b/.gitignore @@ -3,13 +3,13 @@ .phpunit.result.cache .phpunit.cache build -composer.lock -coverage -docs -logs +/composer.lock +/coverage +/docs +/logs phpunit.xml phpstan.neon testbench.yaml -vendor -node_modules -tests/Feature/performance_test.log +/vendor +/node_modules +/tests/Feature/performance_test.log From e814f0bc614d9665fbc1b2bafc38ce32389995fa Mon Sep 17 00:00:00 2001 From: Arunas Skirius Date: Sat, 18 Oct 2025 12:04:46 +0300 Subject: [PATCH 4/8] Fix JSON context extraction on Windows Handle CRLF line endings when JSON contains control characters by replacing both \r\n and \r with escaped newlines during JSON parsing error recovery. --- src/Logs/LaravelLog.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Logs/LaravelLog.php b/src/Logs/LaravelLog.php index f6a3b6a9..707ecf5f 100644 --- a/src/Logs/LaravelLog.php +++ b/src/Logs/LaravelLog.php @@ -108,8 +108,8 @@ protected function extractContextsFromFullText(): void $json_data = json_decode(trim($json_string), true); if (json_last_error() == JSON_ERROR_CTRL_CHAR) { - // might need to escape new lines - $json_data = json_decode(str_replace("\n", '\\n', $json_string), true); + // might need to escape new lines and carriage returns + $json_data = json_decode(str_replace(["\r\n", "\r", "\n"], ['\\n', '\\n', '\\n'], $json_string), true); } if (json_last_error() == JSON_ERROR_NONE) { From 1cef6f75afda6e15d8d79d6704f436484020558c Mon Sep 17 00:00:00 2001 From: Arunas Skirius Date: Sat, 18 Oct 2025 12:11:12 +0300 Subject: [PATCH 5/8] Normalize line endings in test comparison Makes test platform-independent by normalizing line endings when comparing context values on Windows vs Unix systems. --- .github/ISSUE_TEMPLATE/config.yml | 2 +- tests/Unit/LaravelLogs/LaravelLogsTest.php | 5 ++++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml index ec1ca054..037dea16 100644 --- a/.github/ISSUE_TEMPLATE/config.yml +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -1,4 +1,4 @@ -blank_issues_enabled: false +blank_issues_enabled: true contact_links: - name: Ask a question url: https://github.com/opcodesio/log-viewer/discussions/new?category=q-a diff --git a/tests/Unit/LaravelLogs/LaravelLogsTest.php b/tests/Unit/LaravelLogs/LaravelLogsTest.php index 99eae2cf..7442823f 100644 --- a/tests/Unit/LaravelLogs/LaravelLogsTest.php +++ b/tests/Unit/LaravelLogs/LaravelLogsTest.php @@ -311,8 +311,11 @@ $log = new LaravelLog($logText); + // Normalize line endings for cross-platform comparison + $normalizedContext = str_replace(["\r\n", "\r"], "\n", $log->context['exception']); + expect($log->context)->toHaveKey('exception') - ->and($log->context['exception'])->toBe($stackTrace) + ->and($normalizedContext)->toBe($stackTrace) ->and($log->context['exception'])->toContain('/vendor/symfony/http-kernel/') ->and($log->context['exception'])->toContain('/vendor/laravel/framework/'); }); From 0ae56924c8e8994eb1b78f68b681b59c8e09b88d Mon Sep 17 00:00:00 2001 From: Arunas Skirius Date: Sat, 18 Oct 2025 12:16:16 +0300 Subject: [PATCH 6/8] Always normalize context line endings Normalizes line endings in all context values immediately after JSON extraction, ensuring consistent cross-platform behavior regardless of whether filtering is enabled. --- src/Logs/LaravelLog.php | 14 ++++++++++++++ tests/Unit/LaravelLogs/LaravelLogsTest.php | 5 +---- 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/src/Logs/LaravelLog.php b/src/Logs/LaravelLog.php index 707ecf5f..3266c609 100644 --- a/src/Logs/LaravelLog.php +++ b/src/Logs/LaravelLog.php @@ -26,6 +26,7 @@ protected function parseText(array &$matches = []): void $length = strlen($this->text); $this->extractContextsFromFullText(); + $this->normalizeContextLineEndings(); $this->extra['log_size'] = $length; $this->extra['log_size_formatted'] = Utils::bytesForHumans($length); @@ -191,6 +192,19 @@ protected function getJsonStringsFromFullText(): array return $json_strings; } + protected function normalizeContextLineEndings(): void + { + if (empty($this->context)) { + return; + } + + foreach ($this->context as $key => $value) { + if (is_string($value)) { + $this->context[$key] = str_replace(["\r\n", "\r"], "\n", $value); + } + } + } + protected function filterStackTrace(string $text): string { // Normalize line endings for cross-platform compatibility diff --git a/tests/Unit/LaravelLogs/LaravelLogsTest.php b/tests/Unit/LaravelLogs/LaravelLogsTest.php index 7442823f..99eae2cf 100644 --- a/tests/Unit/LaravelLogs/LaravelLogsTest.php +++ b/tests/Unit/LaravelLogs/LaravelLogsTest.php @@ -311,11 +311,8 @@ $log = new LaravelLog($logText); - // Normalize line endings for cross-platform comparison - $normalizedContext = str_replace(["\r\n", "\r"], "\n", $log->context['exception']); - expect($log->context)->toHaveKey('exception') - ->and($normalizedContext)->toBe($stackTrace) + ->and($log->context['exception'])->toBe($stackTrace) ->and($log->context['exception'])->toContain('/vendor/symfony/http-kernel/') ->and($log->context['exception'])->toContain('/vendor/laravel/framework/'); }); From 3408549e651d8a6c9020c93c01fee6e080888887 Mon Sep 17 00:00:00 2001 From: Arunas Skirius Date: Sat, 18 Oct 2025 13:08:05 +0300 Subject: [PATCH 7/8] Normalize heredoc line endings in test Heredocs may contain platform-specific line endings on Windows. Normalize expected value to match the normalized context output. --- tests/Unit/LaravelLogs/LaravelLogsTest.php | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/tests/Unit/LaravelLogs/LaravelLogsTest.php b/tests/Unit/LaravelLogs/LaravelLogsTest.php index 99eae2cf..458e062a 100644 --- a/tests/Unit/LaravelLogs/LaravelLogsTest.php +++ b/tests/Unit/LaravelLogs/LaravelLogsTest.php @@ -311,8 +311,11 @@ $log = new LaravelLog($logText); + // Normalize expected value for cross-platform comparison (heredocs may have platform line endings) + $expectedStackTrace = str_replace(["\r\n", "\r"], "\n", $stackTrace); + expect($log->context)->toHaveKey('exception') - ->and($log->context['exception'])->toBe($stackTrace) + ->and($log->context['exception'])->toBe($expectedStackTrace) ->and($log->context['exception'])->toContain('/vendor/symfony/http-kernel/') ->and($log->context['exception'])->toContain('/vendor/laravel/framework/'); }); From ddfeeb1f8b8f2955a1deeedf821760e96652edab Mon Sep 17 00:00:00 2001 From: Arunas Skirius Date: Sat, 18 Oct 2025 13:14:40 +0300 Subject: [PATCH 8/8] remove potentially unneeded code --- src/Logs/LaravelLog.php | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/src/Logs/LaravelLog.php b/src/Logs/LaravelLog.php index 3266c609..707ecf5f 100644 --- a/src/Logs/LaravelLog.php +++ b/src/Logs/LaravelLog.php @@ -26,7 +26,6 @@ protected function parseText(array &$matches = []): void $length = strlen($this->text); $this->extractContextsFromFullText(); - $this->normalizeContextLineEndings(); $this->extra['log_size'] = $length; $this->extra['log_size_formatted'] = Utils::bytesForHumans($length); @@ -192,19 +191,6 @@ protected function getJsonStringsFromFullText(): array return $json_strings; } - protected function normalizeContextLineEndings(): void - { - if (empty($this->context)) { - return; - } - - foreach ($this->context as $key => $value) { - if (is_string($value)) { - $this->context[$key] = str_replace(["\r\n", "\r"], "\n", $value); - } - } - } - protected function filterStackTrace(string $text): string { // Normalize line endings for cross-platform compatibility