Skip to content

Commit

Permalink
ability to disable stripping of content after JSON is extracted into …
Browse files Browse the repository at this point in the history
…context
  • Loading branch information
arukompas committed Aug 10, 2023
1 parent 91a17c2 commit 583a2fa
Show file tree
Hide file tree
Showing 8 changed files with 66 additions and 7 deletions.
2 changes: 1 addition & 1 deletion composer.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "opcodesio/log-viewer",
"version": "v2.5.3",
"version": "v2.5.4",
"description": "Fast and easy-to-use log viewer for your Laravel application",
"keywords": [
"arukompas",
Expand Down
2 changes: 2 additions & 0 deletions config/log-viewer.php
Original file line number Diff line number Diff line change
Expand Up @@ -213,4 +213,6 @@
*/

'lazy_scan_chunk_size_in_mb' => 50,

'strip_extracted_context' => true,
];
2 changes: 1 addition & 1 deletion public/app.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion public/mix-manifest.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"/app.js": "/app.js?id=2ca3fa12f273bd645611f1acf3d81355",
"/app.js": "/app.js?id=65bcb5cc7b0f371b0d28d1b07e92cc53",
"/app.css": "/app.css?id=93151d8b186ef7758df8582425ff8082",
"/img/log-viewer-128.png": "/img/log-viewer-128.png?id=d576c6d2e16074d3f064e60fe4f35166",
"/img/log-viewer-32.png": "/img/log-viewer-32.png?id=f8ec67d10f996aa8baf00df3b61eea6d",
Expand Down
12 changes: 11 additions & 1 deletion resources/js/components/LogList.vue
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@
<template v-if="log.contexts && log.contexts.length > 0">
<p class="mx-2 lg:mx-8 pt-2 border-t font-semibold text-gray-700 dark:text-gray-400">Context:</p>
<template v-for="context in log.contexts">
<pre class="log-stack" v-html="JSON.stringify(context, null, 2)"></pre>
<pre class="log-stack" v-html="prepareContextForOutput(context)"></pre>
</template>
</template>
<div v-if="log.full_text_incomplete" class="py-4 px-8 text-gray-500 italic">
Expand Down Expand Up @@ -215,6 +215,16 @@ const displayLogs = computed(() => {
return logViewerStore.logs && (logViewerStore.logs.length > 0 || !logViewerStore.hasMoreResults) && (logViewerStore.selectedFile || searchStore.hasQuery);
});
const prepareContextForOutput = (context) => {
return JSON.stringify(context, function (key, value) {
if (typeof value === 'string') {
return value.replaceAll('\n', '<br/>');
}
return value;
}, 2);
}
const clearSelectedFile = () => {
replaceQuery(router, 'file', null);
}
Expand Down
4 changes: 4 additions & 0 deletions src/Http/Resources/LogFileResource.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,11 @@
use Illuminate\Http\Request;
use Illuminate\Http\Resources\Json\JsonResource;
use Illuminate\Support\Facades\Gate;
use Opcodes\LogViewer\LogFile;

/**
* @mixin LogFile
*/
class LogFileResource extends JsonResource
{
/**
Expand Down
7 changes: 5 additions & 2 deletions src/Log.php
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,7 @@ public function extractContextsFromFullText(): void
// Loop through the matches.
foreach ($matches[0] as $json_string) {
// Try to decode the JSON string. If it fails, json_last_error() will return a non-zero value.
$json_data = json_decode($json_string, true);
$json_data = json_decode(trim($json_string), true);

if (json_last_error() == JSON_ERROR_CTRL_CHAR) {
// might need to escape new lines
Expand All @@ -157,7 +157,10 @@ public function extractContextsFromFullText(): void

if (json_last_error() == JSON_ERROR_NONE) {
$this->contexts[] = $json_data;
$this->fullText = str_replace($json_string, '', $this->fullText);

if (config('log-viewer.strip_extracted_context', false)) {
$this->fullText = str_replace($json_string, '', $this->fullText);
}
}
}
}
Expand Down
42 changes: 41 additions & 1 deletion tests/Unit/LogTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -34,10 +34,11 @@
});

it('extracts JSON from the log text', function () {
config(['log-viewer.strip_extracted_context' => true]);
$logText = <<<'EOF'
Example log entry for the level debug
with multiple lines of content.
{"one":1,"two":"two","three":[1,2,3]}
{"one":1,"two":"two","three":[1,2,3]}
can contain dumped objects or JSON as well - it's all part of the contents.
EOF;
$jsonString = '{"one":1,"two":"two","three":[1,2,3]}';
Expand All @@ -50,6 +51,45 @@
assertEquals(json_decode($jsonString, true), $log->contexts[0]);
});

it('extracts JSON, but does not remove from the log text if the config is set to false', function () {
config(['log-viewer.strip_extracted_context' => false]);
$logText = <<<'EOF'
Example log entry for the level debug
with multiple lines of content.
{"one":1,"two":"two","three":[1,2,3]}
can contain dumped objects or JSON as well - it's all part of the contents.
EOF;
$text = '[2022-08-25 11:16:17] local.DEBUG: '.$logText;

$log = new Log(0, $text, 'laravel.log', 0);

assertEquals('Example log entry for the level debug', $log->text);
assertEquals($logText, $log->fullText);
assertEquals(json_decode('{"one":1,"two":"two","three":[1,2,3]}', true), $log->contexts[0]);
});

it('extracts JSON from a complex log', function () {
config(['log-viewer.strip_extracted_context' => true]);
$logText = <<<'EOF'
Initiating facebook login.
[HTTP request]
*User ID:* guest
*Request:* GET https://system.test/book/arunas/submit-facebook
*Agent:* Mozilla/5.0 (iPhone; CPU iPhone OS 15_6_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/19G82 [FBAN/FBIOS;FBDV/iPhone9,3;FBMD/iPhone;FBSN/iOS;FBSV/15.6.1;FBSS/2;FBID/phone;FBLC/da_DK;FBOP/5]
{"permalink":"arunas","session":{"_token":"BpqyiNyinnLamzer4jqzrh9NTyC6emFR41FitMpv","_previous":{"url":"https://system.test/book/arunas/center"},"_flash":{"old":[],"new":[]},"latest_permalink":"arunas"},"ip":"127.0.0.1","user_agent":"Mozilla/5.0 (iPhone; CPU iPhone OS 15_6_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/19G82 [FBAN/FBIOS;FBDV/iPhone9,3;FBMD/iPhone;FBSN/iOS;FBSV/15.6.1;FBSS/2;FBID/phone;FBLC/da_DK;FBOP/5]"}
EOF;

$jsonString = '{"permalink":"arunas","session":{"_token":"BpqyiNyinnLamzer4jqzrh9NTyC6emFR41FitMpv","_previous":{"url":"https://system.test/book/arunas/center"},"_flash":{"old":[],"new":[]},"latest_permalink":"arunas"},"ip":"127.0.0.1","user_agent":"Mozilla/5.0 (iPhone; CPU iPhone OS 15_6_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/19G82 [FBAN/FBIOS;FBDV/iPhone9,3;FBMD/iPhone;FBSN/iOS;FBSV/15.6.1;FBSS/2;FBID/phone;FBLC/da_DK;FBOP/5]"}';
$text = '[2022-08-25 11:16:17] local.DEBUG: '.$logText;

$log = new Log(0, $text, 'laravel.log', 0);

assertEquals('arunas', $log->contexts[0]['permalink'] ?? null);
assertEquals('Initiating facebook login.', $log->text);
assertEquals(str_replace($jsonString, '', $logText), $log->fullText);
assertEquals(json_decode($jsonString, true), $log->contexts[0]);
});

it('can understand the optional microseconds in the timestamp', function () {
$text = '[2022-08-25 11:16:17.125000] local.DEBUG: Example log entry for the level debug';

Expand Down

0 comments on commit 583a2fa

Please sign in to comment.