Skip to content

Commit 2b5403a

Browse files
Replace current panel log viewer with new and improved log viewer (#1834)
1 parent a30c45f commit 2b5403a

File tree

10 files changed

+530
-159
lines changed

10 files changed

+530
-159
lines changed
Lines changed: 130 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,130 @@
1+
<?php
2+
3+
namespace App\Filament\Admin\Pages;
4+
5+
use Boquizo\FilamentLogViewer\Actions\DeleteAction;
6+
use Boquizo\FilamentLogViewer\Actions\DownloadAction;
7+
use Boquizo\FilamentLogViewer\Actions\ViewLogAction;
8+
use Boquizo\FilamentLogViewer\Pages\ListLogs as BaseListLogs;
9+
use Boquizo\FilamentLogViewer\Tables\Columns\LevelColumn;
10+
use Boquizo\FilamentLogViewer\Tables\Columns\NameColumn;
11+
use Boquizo\FilamentLogViewer\Utils\Level;
12+
use Filament\Actions\Action;
13+
use Filament\Notifications\Notification;
14+
use Filament\Support\Enums\IconSize;
15+
use Filament\Tables\Table;
16+
use Illuminate\Support\Facades\Http;
17+
18+
class ListLogs extends BaseListLogs
19+
{
20+
protected string $view = 'filament.components.list-logs';
21+
22+
public function getHeading(): string|null|\Illuminate\Contracts\Support\Htmlable
23+
{
24+
return trans('admin/log.navigation.panel_logs');
25+
}
26+
27+
public static function table(Table $table): Table
28+
{
29+
return parent::table($table)
30+
->emptyStateHeading(trans('admin/log.empty_table'))
31+
->emptyStateIcon('tabler-check')
32+
->columns([
33+
NameColumn::make('date'),
34+
LevelColumn::make(Level::ALL)
35+
->tooltip(trans('admin/log.total_logs')),
36+
LevelColumn::make(Level::Error)
37+
->tooltip(trans('admin/log.error')),
38+
LevelColumn::make(Level::Warning)
39+
->tooltip(trans('admin/log.warning')),
40+
LevelColumn::make(Level::Notice)
41+
->tooltip(trans('admin/log.notice')),
42+
LevelColumn::make(Level::Info)
43+
->tooltip(trans('admin/log.info')),
44+
LevelColumn::make(Level::Debug)
45+
->tooltip(trans('admin/log.debug')),
46+
])
47+
->recordActions([
48+
ViewLogAction::make()
49+
->icon('tabler-file-description')->iconSize(IconSize::Medium),
50+
DownloadAction::make()
51+
->icon('tabler-file-download')->iconSize(IconSize::Medium),
52+
Action::make('uploadLogs')
53+
->button()
54+
->hiddenLabel()
55+
->icon('tabler-world-upload')->iconSize(IconSize::Medium)
56+
->requiresConfirmation()
57+
->modalHeading(trans('admin/log.actions.upload_logs'))
58+
->modalDescription(fn ($record) => trans('admin/log.actions.upload_logs_description', ['file' => $record['date'], 'url' => 'https://logs.pelican.dev']))
59+
->action(function ($record) {
60+
$logPath = storage_path('logs/' . $record['date']);
61+
62+
if (!file_exists($logPath)) {
63+
Notification::make()
64+
->title(trans('admin/log.actions.log_not_found'))
65+
->body(trans('admin/log.actions.log_not_found_description', ['filename' => $record['date']]))
66+
->danger()
67+
->send();
68+
69+
return;
70+
}
71+
72+
$lines = file($logPath, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
73+
$totalLines = count($lines);
74+
$uploadLines = $totalLines <= 1000 ? $lines : array_slice($lines, -1000);
75+
$content = implode("\n", $uploadLines);
76+
77+
$logUrl = 'https://logs.pelican.dev';
78+
try {
79+
$response = Http::timeout(10)->asMultipart()->post($logUrl, [
80+
[
81+
'name' => 'c',
82+
'contents' => $content,
83+
],
84+
[
85+
'name' => 'e',
86+
'contents' => '14d',
87+
],
88+
]);
89+
90+
if ($response->failed()) {
91+
Notification::make()
92+
->title(trans('admin/log.actions.failed_to_upload'))
93+
->body(trans('admin/log.actions.failed_to_upload_description', ['status' => $response->status()]))
94+
->danger()
95+
->send();
96+
97+
return;
98+
}
99+
100+
$data = $response->json();
101+
$url = $data['url'];
102+
103+
Notification::make()
104+
->title(trans('admin/log.actions.log_upload'))
105+
->body("{$url}")
106+
->success()
107+
->actions([
108+
Action::make('viewLogs')
109+
->label(trans('admin/log.actions.view_logs'))
110+
->url($url)
111+
->openUrlInNewTab(true),
112+
])
113+
->persistent()
114+
->send();
115+
116+
} catch (\Exception $e) {
117+
Notification::make()
118+
->title(trans('admin/log.actions.failed_to_upload'))
119+
->body($e->getMessage())
120+
->danger()
121+
->send();
122+
123+
return;
124+
}
125+
}),
126+
DeleteAction::make()
127+
->icon('tabler-trash')->iconSize(IconSize::Medium),
128+
]);
129+
}
130+
}
Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
<?php
2+
3+
namespace App\Filament\Admin\Pages;
4+
5+
use App\Traits\ResolvesRecordDate;
6+
use Boquizo\FilamentLogViewer\Actions\BackAction;
7+
use Boquizo\FilamentLogViewer\Actions\DeleteAction;
8+
use Boquizo\FilamentLogViewer\Actions\DownloadAction;
9+
use Boquizo\FilamentLogViewer\Pages\ViewLog as BaseViewLog;
10+
use Filament\Actions\Action;
11+
use Filament\Notifications\Notification;
12+
use Filament\Support\Enums\IconSize;
13+
use Illuminate\Support\Facades\Http;
14+
15+
class ViewLogs extends BaseViewLog
16+
{
17+
use ResolvesRecordDate;
18+
19+
public function getHeaderActions(): array
20+
{
21+
return [
22+
DeleteAction::make(withTooltip: true)
23+
->icon('tabler-trash')->iconSize(IconSize::Medium),
24+
DownloadAction::make(withTooltip: true)
25+
->icon('tabler-file-download')->iconSize(IconSize::Medium),
26+
Action::make('uploadLogs')
27+
->button()
28+
->hiddenLabel()
29+
->icon('tabler-world-upload')->iconSize(IconSize::Medium)
30+
->requiresConfirmation()
31+
->tooltip(trans('admin/log.actions.upload_tooltip', ['url' => 'logs.pelican.dev']))
32+
->modalHeading(trans('admin/log.actions.upload_logs'))
33+
->modalDescription(fn () => trans('admin/log.actions.upload_logs_description', ['file' => $this->resolveRecordDate(), 'url' => 'https://logs.pelican.dev']))
34+
->action(function () {
35+
$logPath = storage_path('logs/' . $this->resolveRecordDate());
36+
37+
if (!file_exists($logPath)) {
38+
Notification::make()
39+
->title(trans('admin/log.actions.log_not_found'))
40+
->body(trans('admin/log.actions.log_not_found_description', ['filename' => $this->resolveRecordDate()]))
41+
->danger()
42+
->send();
43+
44+
return;
45+
}
46+
47+
$lines = file($logPath, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
48+
$totalLines = count($lines);
49+
$uploadLines = $totalLines <= 1000 ? $lines : array_slice($lines, -1000);
50+
$content = implode("\n", $uploadLines);
51+
52+
$logUrl = 'https://logs.pelican.dev';
53+
try {
54+
$response = Http::timeout(10)->asMultipart()->post($logUrl, [
55+
[
56+
'name' => 'c',
57+
'contents' => $content,
58+
],
59+
[
60+
'name' => 'e',
61+
'contents' => '14d',
62+
],
63+
]);
64+
65+
if ($response->failed()) {
66+
Notification::make()
67+
->title(trans('admin/log.actions.failed_to_upload'))
68+
->body(trans('admin/log.actions.failed_to_upload_description', ['status' => $response->status()]))
69+
->danger()
70+
->send();
71+
72+
return;
73+
}
74+
75+
$data = $response->json();
76+
$url = $data['url'];
77+
78+
Notification::make()
79+
->title(trans('admin/log.actions.log_upload'))
80+
->body("{$url}")
81+
->success()
82+
->actions([
83+
Action::make('viewLogs')
84+
->label(trans('admin/log.actions.view_logs'))
85+
->url($url)
86+
->openUrlInNewTab(true),
87+
])
88+
->persistent()
89+
->send();
90+
91+
} catch (\Exception $e) {
92+
Notification::make()
93+
->title(trans('admin/log.actions.failed_to_upload'))
94+
->body($e->getMessage())
95+
->danger()
96+
->send();
97+
98+
return;
99+
}
100+
}),
101+
BackAction::make()
102+
->icon('tabler-arrow-left')->iconSize(IconSize::Medium),
103+
];
104+
}
105+
}

app/Providers/Filament/AdminPanelProvider.php

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,9 @@
22

33
namespace App\Providers\Filament;
44

5-
use AchyutN\FilamentLogViewer\FilamentLogViewer;
5+
use App\Filament\Admin\Pages\ListLogs;
6+
use App\Filament\Admin\Pages\ViewLogs;
7+
use Boquizo\FilamentLogViewer\FilamentLogViewerPlugin;
68
use Filament\Actions\Action;
79
use Filament\Facades\Filament;
810
use Filament\Navigation\NavigationGroup;
@@ -35,8 +37,11 @@ public function panel(Panel $panel): Panel
3537
->discoverPages(in: app_path('Filament/Admin/Pages'), for: 'App\\Filament\\Admin\\Pages')
3638
->discoverWidgets(in: app_path('Filament/Admin/Widgets'), for: 'App\\Filament\\Admin\\Widgets')
3739
->plugins([
38-
FilamentLogViewer::make()
40+
FilamentLogViewerPlugin::make()
3941
->authorize(fn () => user()->can('view panelLog'))
42+
->listLogs(ListLogs::class)
43+
->viewLog(ViewLogs::class)
44+
->navigationLabel(fn () => trans('admin/log.navigation.panel_logs'))
4045
->navigationGroup(fn () => trans('admin/dashboard.advanced'))
4146
->navigationIcon('tabler-file-info'),
4247
]);

app/Providers/Filament/AppPanelProvider.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
namespace App\Providers\Filament;
44

5-
use AchyutN\FilamentLogViewer\FilamentLogViewer;
5+
use Boquizo\FilamentLogViewer\FilamentLogViewerPlugin;
66
use Filament\Actions\Action;
77
use Filament\Facades\Filament;
88
use Filament\Panel;
@@ -26,7 +26,7 @@ public function panel(Panel $panel): Panel
2626
])
2727
->discoverResources(in: app_path('Filament/App/Resources'), for: 'App\\Filament\\App\\Resources')
2828
->plugins([
29-
FilamentLogViewer::make()
29+
FilamentLogViewerPlugin::make()
3030
->authorize(false),
3131
]);
3232
}

app/Traits/ResolvesRecordDate.php

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
<?php
2+
3+
namespace App\Traits;
4+
5+
use Illuminate\Support\Arr;
6+
7+
trait ResolvesRecordDate
8+
{
9+
/**
10+
* @param mixed|null $record
11+
*/
12+
protected function resolveRecordDate($record = null): ?string
13+
{
14+
$r = $record ?? ($this->record ?? null);
15+
16+
if (is_scalar($r)) {
17+
return (string) $r;
18+
}
19+
20+
if (is_array($r)) {
21+
return Arr::get($r, 'date') !== null ? (string) Arr::get($r, 'date') : null;
22+
}
23+
24+
if (is_object($r)) {
25+
if (method_exists($r, 'getAttribute')) {
26+
$val = $r->getAttribute('date');
27+
if ($val !== null) {
28+
return (string) $val;
29+
}
30+
}
31+
32+
if (isset($r->date) || property_exists($r, 'date')) {
33+
return (string) $r->date;
34+
}
35+
36+
if (method_exists($r, 'toArray')) {
37+
$arr = $r->toArray();
38+
39+
return Arr::get($arr, 'date') !== null ? (string) Arr::get($arr, 'date') : null;
40+
}
41+
}
42+
43+
return null;
44+
}
45+
}

composer.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,11 @@
99
"ext-mbstring": "*",
1010
"ext-pdo": "*",
1111
"ext-zip": "*",
12-
"achyutn/filament-log-viewer": "^1.4",
1312
"aws/aws-sdk-php": "^3.356",
1413
"calebporzio/sushi": "^2.5",
1514
"dedoc/scramble": "^0.12.10",
1615
"filament/filament": "~4.0",
16+
"gboquizosanchez/filament-log-viewer": "^2.1",
1717
"guzzlehttp/guzzle": "^7.10",
1818
"laravel/framework": "^12.37",
1919
"laravel/helpers": "^1.7",

0 commit comments

Comments
 (0)