Gryfon
Using Sushi with Filament Table and refresh the data
public function table(Table $table): Table
{
return $table
->query( Log::query() )
->poll('10')
->columns([
//
])
->filters([
SelectFilter::make('level')->options(LogLevel::class),
]);
}
public function table(Table $table): Table
{
return $table
->query( Log::query() )
->poll('10')
->columns([
//
])
->filters([
SelectFilter::make('level')->options(LogLevel::class),
]);
}
$this->logFilePath
was empty...
In my Model class :
public function getRows(): array {
$rows = [];
// I added this :
if(!$this->logFilePath) {
$this->logFilePath = storage_path('logs/laravel.log');
}
if ($this->logFilePath && File::exists($this->logFilePath)) {
$fileContent = File::get($this->logFilePath);
$lines = explode("\n", $fileContent);
$currentEntry = null;
foreach ($lines as $line) {
if (preg_match('/\[(.*?)\] (\w+)\.([A-Z]+): (.*)/', $line, $matches)) {
if ($currentEntry) {
$rows[] = $currentEntry;
}
$currentEntry = [
'timestamp' => $matches[1],
'environment' => $matches[2],
'level' => strtolower($matches[3]),
'message' => $matches[4],
];
} elseif ($currentEntry && trim($line) !== '') {
$currentEntry['message'] .= "\n" . $line;
}
}
if ($currentEntry) {
$rows[] = $currentEntry;
}
}
return $rows;
}
public function getRows(): array {
$rows = [];
// I added this :
if(!$this->logFilePath) {
$this->logFilePath = storage_path('logs/laravel.log');
}
if ($this->logFilePath && File::exists($this->logFilePath)) {
$fileContent = File::get($this->logFilePath);
$lines = explode("\n", $fileContent);
$currentEntry = null;
foreach ($lines as $line) {
if (preg_match('/\[(.*?)\] (\w+)\.([A-Z]+): (.*)/', $line, $matches)) {
if ($currentEntry) {
$rows[] = $currentEntry;
}
$currentEntry = [
'timestamp' => $matches[1],
'environment' => $matches[2],
'level' => strtolower($matches[3]),
'message' => $matches[4],
];
} elseif ($currentEntry && trim($line) !== '') {
$currentEntry['message'] .= "\n" . $line;
}
}
if ($currentEntry) {
$rows[] = $currentEntry;
}
}
return $rows;
}
8 replies
Using Sushi with Filament Table and refresh the data
Ok with somes test, I have new... Here, everything work well :
The dd() shows me the contents of the log file I've selected.
I guess the problem is here:
How can I refresh the data in my table according to the getRows() updated in my Model?
return $form->schema([
Select::make('selectedLogfile')
->label(false)
->options($this->logsFiles)
->placeholder('Select a log file')
->searchable()
->live()
->afterStateUpdated(function (string $state) {
$this->selectedLogfile = $this->logsFiles[$state];
$this->log->setLogFile('/logs/' . $this->selectedLogfile);
dd($this->log->getRows()); //Here, all good ! :)
$this->dispatch('refresh');
}),
]);
return $form->schema([
Select::make('selectedLogfile')
->label(false)
->options($this->logsFiles)
->placeholder('Select a log file')
->searchable()
->live()
->afterStateUpdated(function (string $state) {
$this->selectedLogfile = $this->logsFiles[$state];
$this->log->setLogFile('/logs/' . $this->selectedLogfile);
dd($this->log->getRows()); //Here, all good ! :)
$this->dispatch('refresh');
}),
]);
public function table(Table $table): Table
{
return $table
->query(Log::query()) //Here :(
->columns([
TextColumn::make('timestamp')->label('Timestamp'),
TextColumn::make('environment')->label('Environment'),
TextColumn::make('level')->label('Level')->badge(),
TextColumn::make('message')->label('Message')->limit(100)->searchable(),
])
->filters([
SelectFilter::make('level')->options(LogLevel::class),
]);
}
public function table(Table $table): Table
{
return $table
->query(Log::query()) //Here :(
->columns([
TextColumn::make('timestamp')->label('Timestamp'),
TextColumn::make('environment')->label('Environment'),
TextColumn::make('level')->label('Level')->badge(),
TextColumn::make('message')->label('Message')->limit(100)->searchable(),
])
->filters([
SelectFilter::make('level')->options(LogLevel::class),
]);
}
8 replies
Using Sushi with Filament Table and refresh the data
And my Component :
Thanks for your help 😅
class LogViewer extends Component implements HasTable, HasForms
{
use InteractsWithTable;
use InteractsWithForms;
public ?array $logsFiles = [];
public string $selectedLogfile = '';
public Model $log;
public function mount(): void
{
$this->logsFiles = $this->getLogFiles();
$this->selectedLogfile = $this->logsFiles[0];
$this->log = new Log();
}
public function form(Form $form): Form {
return $form->schema([
Select::make('selectedLogfile')
->label(false)
->options($this->logsFiles)
->placeholder('Select a log file')
->searchable()
->live()
->afterStateUpdated(function (string $state) {
$this->log->getRows('/logs/'.$this->logsFiles[$state]);
}),
]);
}
public function table(Table $table): Table
{
return $table
->query(Log::query())
->columns([
TextColumn::make('timestamp')->label('Timestamp'),
TextColumn::make('environment')->label('Environment'),
TextColumn::make('level')->label('Level')->badge(),
TextColumn::make('message')->label('Message')->limit(100)->searchable(),
])
->filters([
SelectFilter::make('level')->options(LogLevel::class),
]);
}
public function render()
{
return view('livewire.admin.log-viewer');
}
public function getLogFiles(): array
{
$logPath = storage_path('logs');
$logFiles = File::files($logPath);
return array_map(fn ($file) => $file->getFilename(),
array_filter($logFiles, fn ($file) => $file->isFile() && str_ends_with($file->getFilename(), '.log')));
}
}
class LogViewer extends Component implements HasTable, HasForms
{
use InteractsWithTable;
use InteractsWithForms;
public ?array $logsFiles = [];
public string $selectedLogfile = '';
public Model $log;
public function mount(): void
{
$this->logsFiles = $this->getLogFiles();
$this->selectedLogfile = $this->logsFiles[0];
$this->log = new Log();
}
public function form(Form $form): Form {
return $form->schema([
Select::make('selectedLogfile')
->label(false)
->options($this->logsFiles)
->placeholder('Select a log file')
->searchable()
->live()
->afterStateUpdated(function (string $state) {
$this->log->getRows('/logs/'.$this->logsFiles[$state]);
}),
]);
}
public function table(Table $table): Table
{
return $table
->query(Log::query())
->columns([
TextColumn::make('timestamp')->label('Timestamp'),
TextColumn::make('environment')->label('Environment'),
TextColumn::make('level')->label('Level')->badge(),
TextColumn::make('message')->label('Message')->limit(100)->searchable(),
])
->filters([
SelectFilter::make('level')->options(LogLevel::class),
]);
}
public function render()
{
return view('livewire.admin.log-viewer');
}
public function getLogFiles(): array
{
$logPath = storage_path('logs');
$logFiles = File::files($logPath);
return array_map(fn ($file) => $file->getFilename(),
array_filter($logFiles, fn ($file) => $file->isFile() && str_ends_with($file->getFilename(), '.log')));
}
}
8 replies
Using Sushi with Filament Table and refresh the data
Here, the Model :
<?php
namespace App\Models;
use App\Enums\LogLevel;
use Illuminate\Database\Eloquent\Model;
use Sushi\Sushi;
use Illuminate\Support\Facades\File;
class Log extends Model
{
use Sushi;
protected $schema = [
'timestamp' => 'string',
'level' => 'string',
'environment' => 'string',
'message' => 'text',
];
protected $casts = [
'level' => LogLevel::class,
];
protected ?string $logFilePath = null;
public function getRows($logFile = '/logs/laravel.log'): array
{
$rows = [];
if($logFile === null) {
$this->logFilePath = storage_path() . '/logs/laravel.log';
} else {
$this->logFilePath = storage_path() . $logFile;
}
if ($this->logFilePath && File::exists($this->logFilePath)) {
$fileContent = File::get($this->logFilePath);
$lines = explode("\n", $fileContent);
$currentEntry = null;
foreach ($lines as $line) {
if (preg_match('/\[(.*?)\] (\w+)\.([A-Z]+): (.*)/', $line, $matches)) {
if ($currentEntry) {
$rows[] = $currentEntry;
}
$currentEntry = [
'timestamp' => $matches[1],
'environment' => $matches[2],
'level' => strtolower($matches[3]),
'message' => $matches[4],
];
} elseif ($currentEntry && trim($line) !== '') {
$currentEntry['message'] .= "\n" . $line;
}
}
if ($currentEntry) {
$rows[] = $currentEntry;
}
}
return $rows;
}
protected function sushiShouldCache(): bool
{
return false;
}
}
<?php
namespace App\Models;
use App\Enums\LogLevel;
use Illuminate\Database\Eloquent\Model;
use Sushi\Sushi;
use Illuminate\Support\Facades\File;
class Log extends Model
{
use Sushi;
protected $schema = [
'timestamp' => 'string',
'level' => 'string',
'environment' => 'string',
'message' => 'text',
];
protected $casts = [
'level' => LogLevel::class,
];
protected ?string $logFilePath = null;
public function getRows($logFile = '/logs/laravel.log'): array
{
$rows = [];
if($logFile === null) {
$this->logFilePath = storage_path() . '/logs/laravel.log';
} else {
$this->logFilePath = storage_path() . $logFile;
}
if ($this->logFilePath && File::exists($this->logFilePath)) {
$fileContent = File::get($this->logFilePath);
$lines = explode("\n", $fileContent);
$currentEntry = null;
foreach ($lines as $line) {
if (preg_match('/\[(.*?)\] (\w+)\.([A-Z]+): (.*)/', $line, $matches)) {
if ($currentEntry) {
$rows[] = $currentEntry;
}
$currentEntry = [
'timestamp' => $matches[1],
'environment' => $matches[2],
'level' => strtolower($matches[3]),
'message' => $matches[4],
];
} elseif ($currentEntry && trim($line) !== '') {
$currentEntry['message'] .= "\n" . $line;
}
}
if ($currentEntry) {
$rows[] = $currentEntry;
}
}
return $rows;
}
protected function sushiShouldCache(): bool
{
return false;
}
}
8 replies