From bf9151a26fa5a2c608ffc959701f6f840afc7af8 Mon Sep 17 00:00:00 2001 From: Arunas Skirius Date: Fri, 1 Mar 2024 18:46:29 +0200 Subject: [PATCH] support for unicode character case-sensitivity when searching --- .../LogReader/CanFilterUsingIndex.php | 2 +- src/Readers/IndexedLogReader.php | 2 + tests/Feature/LogsControllerTest.php | 47 +++++++++++++++++++ 3 files changed, 50 insertions(+), 1 deletion(-) diff --git a/src/Concerns/LogReader/CanFilterUsingIndex.php b/src/Concerns/LogReader/CanFilterUsingIndex.php index 82b90269..bd00dea5 100644 --- a/src/Concerns/LogReader/CanFilterUsingIndex.php +++ b/src/Concerns/LogReader/CanFilterUsingIndex.php @@ -90,7 +90,7 @@ protected function setQuery(?string $query = null): static $this->only(null); $this->onlyShowIndex = intval(explode(':', $query)[1]); } elseif (! empty($query)) { - $query = '~'.$query.'~i'; + $query = '~'.$query.'~iu'; Utils::validateRegex($query); diff --git a/src/Readers/IndexedLogReader.php b/src/Readers/IndexedLogReader.php index 86b1ed90..dac753e2 100644 --- a/src/Readers/IndexedLogReader.php +++ b/src/Readers/IndexedLogReader.php @@ -96,6 +96,7 @@ public function scan(?int $maxBytesToScan = null, bool $force = false): static $lvl = null; try { + // first, let's see if it matches the new log entry. Does not take search query into account yet. $lineMatches = $this->logClass::matches(trim($line), $ts, $lvl); } catch (SkipLineException $exception) { continue; @@ -103,6 +104,7 @@ public function scan(?int $maxBytesToScan = null, bool $force = false): static if ($lineMatches) { if ($currentLog !== '') { + // Now, let's see if it matches the search query if set. if (is_null($this->query) || preg_match($this->query, $currentLog)) { $logIndex->addToIndex($currentLogPosition, $currentTimestamp ?? 0, $currentLogLevel, $currentIndex); } diff --git a/tests/Feature/LogsControllerTest.php b/tests/Feature/LogsControllerTest.php index 9b71f2c5..7a4dddf7 100644 --- a/tests/Feature/LogsControllerTest.php +++ b/tests/Feature/LogsControllerTest.php @@ -14,3 +14,50 @@ expect($response->json('logs'))->toHaveCount(count($logEntries)); }); + +test('simple characters can be searched case-insensitive', function () { + $logEntries = [ + makeLaravelLogEntry(message: 'error'), + makeLaravelLogEntry(message: 'Error'), + makeLaravelLogEntry(message: 'eRrOr'), + makeLaravelLogEntry(message: 'ERROR'), + makeLaravelLogEntry(message: 'simple text'), + ]; + $file = generateLogFile('logsearchtest.log', implode(PHP_EOL, $logEntries)); + + // first, just to be sure that we're getting all the logs without any query + $response = getJson(route('log-viewer.logs', ['file' => $file->identifier])); + expect($response->json('logs'))->toHaveCount(count($logEntries)); + + // now, with the query. Re-instantiate the log reader to make sure we don't have anything cached. + \Opcodes\LogViewer\Readers\IndexedLogReader::clearInstance($file); + $response = getJson(route('log-viewer.logs', [ + 'file' => $file->identifier, + 'query' => 'error', + ])); + expect($response->json('logs'))->toHaveCount(4); + +}); + +test('unicode characters can be searched case-insensitive', function () { + $logEntries = [ + makeLaravelLogEntry(message: 'ошибка'), + makeLaravelLogEntry(message: 'Ошибка'), + makeLaravelLogEntry(message: 'ошибкА'), + makeLaravelLogEntry(message: 'ОШИБКА'), + makeLaravelLogEntry(message: 'simple text'), + ]; + $file = generateLogFile('logunicodetest.log', implode(PHP_EOL, $logEntries)); + + // first, just to be sure that we're getting all the logs without any query + $response = getJson(route('log-viewer.logs', ['file' => $file->identifier])); + expect($response->json('logs'))->toHaveCount(count($logEntries)); + + // now, with the query. Re-instantiate the log reader to make sure we don't have anything cached. + \Opcodes\LogViewer\Readers\IndexedLogReader::clearInstance($file); + $response = getJson(route('log-viewer.logs', [ + 'file' => $file->identifier, + 'query' => 'ошибка', + ])); + expect($response->json('logs'))->toHaveCount(4); +});