Files
jabali-panel/app/Filament/Admin/Widgets/SystemInfoTableWidget.php
2026-02-02 03:11:45 +02:00

217 lines
7.1 KiB
PHP

<?php
declare(strict_types=1);
namespace App\Filament\Admin\Widgets;
use App\Services\Agent\AgentClient;
use Filament\Actions\Concerns\InteractsWithActions;
use Filament\Actions\Contracts\HasActions;
use Filament\Schemas\Concerns\InteractsWithSchemas;
use Filament\Schemas\Contracts\HasSchemas;
use Filament\Tables\Columns\TextColumn;
use Filament\Tables\Concerns\InteractsWithTable;
use Filament\Tables\Contracts\HasTable;
use Filament\Tables\Table;
use Livewire\Component;
class SystemInfoTableWidget extends Component implements HasActions, HasSchemas, HasTable
{
use InteractsWithActions;
use InteractsWithSchemas;
use InteractsWithTable;
public array $info = [];
public function mount(): void
{
$this->loadInfo();
}
protected function loadInfo(): void
{
try {
$agent = new AgentClient;
$overview = $agent->metricsOverview();
$network = $agent->metricsNetwork()['data'] ?? [];
// Get primary interface IP
$primaryIp = '127.0.0.1';
$interfaces = $network['interfaces'] ?? [];
foreach ($interfaces as $name => $iface) {
if ($name !== 'lo' && ! empty($iface['ip'])) {
$primaryIp = explode('/', $iface['ip'])[0];
break;
}
}
// Parse OS info
$osInfo = $overview['os'] ?? [];
$osName = is_array($osInfo) ? ($osInfo['name'] ?? 'Linux') : 'Linux';
$osVersion = is_array($osInfo) ? ($osInfo['version'] ?? '') : '';
// Format memory
$ramTotal = $overview['memory']['total'] ?? 0;
$ramUsed = $overview['memory']['used'] ?? 0;
$ramPercent = round($overview['memory']['usage_percent'] ?? 0, 1);
// Shorten CPU model
$cpuModel = $overview['cpu']['model'] ?? 'Unknown';
$cpuModel = str_replace(['(R)', '(TM)', 'CPU', '@'], '', $cpuModel);
$cpuModel = preg_replace('/\s+/', ' ', trim($cpuModel));
if (strlen($cpuModel) > 35) {
$cpuModel = substr($cpuModel, 0, 32).'...';
}
$this->info = [
[
'category' => __('Server'),
'property' => __('Hostname'),
'value' => $overview['hostname'] ?? gethostname(),
],
[
'category' => __('Server'),
'property' => __('Uptime'),
'value' => $overview['uptime']['human'] ?? 'N/A',
],
[
'category' => __('Server'),
'property' => __('OS'),
'value' => trim("$osName $osVersion") ?: 'Linux',
],
[
'category' => __('Server'),
'property' => __('IP Address'),
'value' => $primaryIp,
],
[
'category' => __('Server'),
'property' => __('Connections'),
'value' => number_format($network['connections'] ?? 0),
],
[
'category' => __('Hardware'),
'property' => __('Processor'),
'value' => $cpuModel,
],
[
'category' => __('Hardware'),
'property' => __('CPU Cores'),
'value' => (string) ($overview['cpu']['cores'] ?? 1),
],
[
'category' => __('Hardware'),
'property' => __('Memory'),
'value' => $this->formatMb($ramUsed).' / '.$this->formatMb($ramTotal)." ({$ramPercent}%)",
],
[
'category' => __('Software'),
'property' => 'PHP',
'value' => PHP_VERSION,
],
[
'category' => __('Software'),
'property' => __('Database'),
'value' => $this->getDatabaseVersion(),
],
[
'category' => __('Software'),
'property' => __('Web Server'),
'value' => $this->getWebserverVersion(),
],
[
'category' => __('Software'),
'property' => 'Laravel',
'value' => app()->version(),
],
];
} catch (\Exception $e) {
$this->info = [];
}
}
protected function formatMb(int $mb): string
{
if ($mb >= 1024) {
return round($mb / 1024, 1).' GB';
}
return $mb.' MB';
}
protected function getDatabaseVersion(): string
{
// Try SQL query first
try {
$version = \DB::select('SELECT VERSION() as version')[0]->version ?? '';
if (preg_match('/^(\d+\.\d+\.\d+)/', $version, $matches)) {
$dbType = str_contains(strtolower($version), 'mariadb') ? 'MariaDB' : 'MySQL';
return "$dbType {$matches[1]}";
}
if ($version) {
return $version;
}
} catch (\Exception $e) {
// Fall through to command line fallback
}
// Fallback to mysqld --version command
$output = shell_exec('mysqld --version 2>/dev/null');
if ($output && preg_match('/Ver\s+(\d+\.\d+\.\d+)-?(MariaDB)?/i', $output, $matches)) {
$dbType = ! empty($matches[2]) ? 'MariaDB' : 'MySQL';
return "$dbType {$matches[1]}";
}
return 'N/A';
}
protected function getWebserverVersion(): string
{
$version = shell_exec('nginx -v 2>&1');
if ($version && preg_match('/nginx\/(\d+\.\d+\.\d+)/', $version, $matches)) {
return "Nginx {$matches[1]}";
}
return 'Nginx';
}
public function makeFilamentTranslatableContentDriver(): ?\Filament\Support\Contracts\TranslatableContentDriver
{
return null;
}
public function table(Table $table): Table
{
return $table
->records(fn () => $this->info)
->columns([
TextColumn::make('category')
->label(__('Category'))
->badge()
->color(fn (string $state): string => match ($state) {
__('Server') => 'primary',
__('Hardware') => 'warning',
__('Software') => 'success',
default => 'gray',
}),
TextColumn::make('property')
->label(__('Property'))
->weight('medium'),
TextColumn::make('value')
->label(__('Value'))
->fontFamily('mono')
->color('gray'),
])
->paginated(false)
->striped();
}
public function render()
{
return $this->getTable()->render();
}
}