Skip to content

Commit 583a2fa

Browse files
committed
ability to disable stripping of content after JSON is extracted into context
1 parent 91a17c2 commit 583a2fa

File tree

8 files changed

+66
-7
lines changed

8 files changed

+66
-7
lines changed

composer.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "opcodesio/log-viewer",
3-
"version": "v2.5.3",
3+
"version": "v2.5.4",
44
"description": "Fast and easy-to-use log viewer for your Laravel application",
55
"keywords": [
66
"arukompas",

config/log-viewer.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -213,4 +213,6 @@
213213
*/
214214

215215
'lazy_scan_chunk_size_in_mb' => 50,
216+
217+
'strip_extracted_context' => true,
216218
];

public/app.js

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

public/mix-manifest.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
{
2-
"/app.js": "/app.js?id=2ca3fa12f273bd645611f1acf3d81355",
2+
"/app.js": "/app.js?id=65bcb5cc7b0f371b0d28d1b07e92cc53",
33
"/app.css": "/app.css?id=93151d8b186ef7758df8582425ff8082",
44
"/img/log-viewer-128.png": "/img/log-viewer-128.png?id=d576c6d2e16074d3f064e60fe4f35166",
55
"/img/log-viewer-32.png": "/img/log-viewer-32.png?id=f8ec67d10f996aa8baf00df3b61eea6d",

resources/js/components/LogList.vue

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,7 @@
109109
<template v-if="log.contexts && log.contexts.length > 0">
110110
<p class="mx-2 lg:mx-8 pt-2 border-t font-semibold text-gray-700 dark:text-gray-400">Context:</p>
111111
<template v-for="context in log.contexts">
112-
<pre class="log-stack" v-html="JSON.stringify(context, null, 2)"></pre>
112+
<pre class="log-stack" v-html="prepareContextForOutput(context)"></pre>
113113
</template>
114114
</template>
115115
<div v-if="log.full_text_incomplete" class="py-4 px-8 text-gray-500 italic">
@@ -215,6 +215,16 @@ const displayLogs = computed(() => {
215215
return logViewerStore.logs && (logViewerStore.logs.length > 0 || !logViewerStore.hasMoreResults) && (logViewerStore.selectedFile || searchStore.hasQuery);
216216
});
217217
218+
const prepareContextForOutput = (context) => {
219+
return JSON.stringify(context, function (key, value) {
220+
if (typeof value === 'string') {
221+
return value.replaceAll('\n', '<br/>');
222+
}
223+
224+
return value;
225+
}, 2);
226+
}
227+
218228
const clearSelectedFile = () => {
219229
replaceQuery(router, 'file', null);
220230
}

src/Http/Resources/LogFileResource.php

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,11 @@
55
use Illuminate\Http\Request;
66
use Illuminate\Http\Resources\Json\JsonResource;
77
use Illuminate\Support\Facades\Gate;
8+
use Opcodes\LogViewer\LogFile;
89

10+
/**
11+
* @mixin LogFile
12+
*/
913
class LogFileResource extends JsonResource
1014
{
1115
/**

src/Log.php

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -148,7 +148,7 @@ public function extractContextsFromFullText(): void
148148
// Loop through the matches.
149149
foreach ($matches[0] as $json_string) {
150150
// Try to decode the JSON string. If it fails, json_last_error() will return a non-zero value.
151-
$json_data = json_decode($json_string, true);
151+
$json_data = json_decode(trim($json_string), true);
152152

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

158158
if (json_last_error() == JSON_ERROR_NONE) {
159159
$this->contexts[] = $json_data;
160-
$this->fullText = str_replace($json_string, '', $this->fullText);
160+
161+
if (config('log-viewer.strip_extracted_context', false)) {
162+
$this->fullText = str_replace($json_string, '', $this->fullText);
163+
}
161164
}
162165
}
163166
}

tests/Unit/LogTest.php

Lines changed: 41 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,10 +34,11 @@
3434
});
3535

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

54+
it('extracts JSON, but does not remove from the log text if the config is set to false', function () {
55+
config(['log-viewer.strip_extracted_context' => false]);
56+
$logText = <<<'EOF'
57+
Example log entry for the level debug
58+
with multiple lines of content.
59+
{"one":1,"two":"two","three":[1,2,3]}
60+
can contain dumped objects or JSON as well - it's all part of the contents.
61+
EOF;
62+
$text = '[2022-08-25 11:16:17] local.DEBUG: '.$logText;
63+
64+
$log = new Log(0, $text, 'laravel.log', 0);
65+
66+
assertEquals('Example log entry for the level debug', $log->text);
67+
assertEquals($logText, $log->fullText);
68+
assertEquals(json_decode('{"one":1,"two":"two","three":[1,2,3]}', true), $log->contexts[0]);
69+
});
70+
71+
it('extracts JSON from a complex log', function () {
72+
config(['log-viewer.strip_extracted_context' => true]);
73+
$logText = <<<'EOF'
74+
Initiating facebook login.
75+
[HTTP request]
76+
*User ID:* guest
77+
*Request:* GET https://system.test/book/arunas/submit-facebook
78+
*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]
79+
{"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]"}
80+
EOF;
81+
82+
$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]"}';
83+
$text = '[2022-08-25 11:16:17] local.DEBUG: '.$logText;
84+
85+
$log = new Log(0, $text, 'laravel.log', 0);
86+
87+
assertEquals('arunas', $log->contexts[0]['permalink'] ?? null);
88+
assertEquals('Initiating facebook login.', $log->text);
89+
assertEquals(str_replace($jsonString, '', $logText), $log->fullText);
90+
assertEquals(json_decode($jsonString, true), $log->contexts[0]);
91+
});
92+
5393
it('can understand the optional microseconds in the timestamp', function () {
5494
$text = '[2022-08-25 11:16:17.125000] local.DEBUG: Example log entry for the level debug';
5595

0 commit comments

Comments
 (0)