@once @endonce

Statistics

Monitor your server's performance metrics and resource utilization over time.

Loading telemetry data…

Live Telemetry

Processor Utilization

Network Traffic

Memory Utilization

Storage I/O

@php $statisticsExportRows = []; @endphp

Statistics History

New Report
Creating...
@forelse($this->statistics as $stat) @php $networkStats = $this->getCurrentNetworkStats($stat); $diskStats = $this->getCurrentDiskStats($stat); $cpuPercent = $stat->cpumax > 0 ? ($stat->cpuused / $stat->cpumax * 100) : 0; $memPercent = $stat->memorymax > 0 ? ($stat->memoryused / $stat->memorymax * 100) : 0; $diskPercent = ($stat->diskmax ?? 0) > 0 ? (($stat->diskused ?? 0) / ($stat->diskmax ?? 1) * 100) : 0; $statisticsExportRows[] = [ 'date_time' => $stat->DateTime ? $stat->DateTime->format('M d, Y H:i:s') : '-', 'status' => $stat->vmstatus ? ucfirst($stat->vmstatus) : '-', 'cpu' => number_format($cpuPercent, 1) . '%', 'memory' => number_format($memPercent, 1) . '%', 'disk' => (($stat->diskmax ?? 0) > 0 && ($stat->diskused ?? 0) > 0) ? number_format($diskPercent, 1) . '%' : 'N/A', 'network_in' => Illuminate\Support\Number::fileSize(bytes: $networkStats['netin']), 'network_out' => Illuminate\Support\Number::fileSize(bytes: $networkStats['netout']), 'disk_io' => sprintf( '%s / %s', Illuminate\Support\Number::fileSize(bytes: $diskStats['diskread'] ?? 0), Illuminate\Support\Number::fileSize(bytes: $diskStats['diskwrite'] ?? 0) ), 'uptime' => $stat->uptime > 0 ? $this->formatUptime($stat->uptime) : '-', ]; @endphp @empty @endforelse
Date & Time
Status
CPU
Memory
Disk
Network In
Network Out
Disk I/O
Uptime
Actions
{{ $stat->DateTime->format('M d, Y') }}
{{ $stat->DateTime->format('H:i:s') }}
@if($stat->vmstatus) {{ ucfirst($stat->vmstatus) }} @else - @endif
{{ number_format($cpuPercent, 1) }}%
{{ number_format($memPercent, 1) }}%
@if(($stat->diskmax ?? 0) > 0 && ($stat->diskused ?? 0) > 0)
{{ number_format($diskPercent, 1) }}%
@else N/A @endif
{{ Illuminate\Support\Number::fileSize(bytes: $networkStats['netin']) }}
@if($networkStats['netin_rate'] > 0)
{{ Illuminate\Support\Number::fileSize(bytes: (int)$networkStats['netin_rate']) }}/s
@endif
{{ Illuminate\Support\Number::fileSize(bytes: $networkStats['netout']) }}
@if($networkStats['netout_rate'] > 0)
{{ Illuminate\Support\Number::fileSize(bytes: (int)$networkStats['netout_rate']) }}/s
@endif
{{ Illuminate\Support\Number::fileSize(bytes: $diskStats['diskread'] ?? 0) }}
{{ Illuminate\Support\Number::fileSize(bytes: $diskStats['diskwrite'] ?? 0) }}
@if($stat->uptime > 0) {{ $this->formatUptime($stat->uptime) }} @else - @endif

No statistics available

Statistics are collected every 5 minutes automatically.

@if($this->statistics->hasPages())
{{ $this->statistics->links() }}
@endif
@php $taskHistoryExportRows = []; @endphp

Task History

@forelse($this->taskHistory as $task) @php $startTime = isset($task['starttime']) ? \Carbon\Carbon::createFromTimestamp($task['starttime']) : null; $endTime = isset($task['endtime']) && $task['endtime'] > 0 ? \Carbon\Carbon::createFromTimestamp($task['endtime']) : null; $duration = null; if ($startTime && $endTime) { $duration = $startTime->diffInSeconds($endTime); } elseif ($startTime && isset($task['status']) && $task['status'] === 'running') { $duration = $startTime->diffInSeconds(now()); } $taskUpid = $task['upid'] ?? $task['id'] ?? ''; $taskKey = md5($taskUpid . ($task['starttime'] ?? '')); $isExpanded = in_array($taskUpid, $this->expandedTaskUpids ?? []); $taskHistoryExportRows[] = [ 'type' => $task['type'] ?? 'N/A', 'status' => $task['status'] ?? '-', 'start_time' => $startTime ? $startTime->format('M d, Y H:i:s') : '-', 'end_time' => $endTime ? $endTime->format('M d, Y H:i:s') : '-', 'duration' => $duration !== null ? $this->formatUptime($duration) : '-', ]; @endphp @empty @endforelse
Type
Status
Start Time
End Time
Duration
{{ $task['type'] ?? 'N/A' }} @if(isset($task['status'])) @if($task['status'] === 'OK') Success @else Failure @endif @else - @endif @if($startTime)
{{ $startTime->format('M d, Y') }}
{{ $startTime->format('H:i:s') }}
@else - @endif
@if($endTime)
{{ $endTime->format('M d, Y') }}
{{ $endTime->format('H:i:s') }}
@else - @endif
@if($duration !== null) {{ $this->formatUptime($duration) }} @else - @endif

Task Information

Loading task details...

No detailed information available for this task.

No task history available

Task history will appear here as tasks are executed on the server.

@php $lifecycleEventsExportRows = []; @endphp

Recent Lifecycle Events

@forelse(collect($this->chartEvents)->take(20) as $index => $event) @php $startTime = isset($event['starttime']) ? \Carbon\Carbon::createFromTimestamp($event['starttime']) : null; $endTime = isset($event['endtime']) && $event['endtime'] > 0 ? \Carbon\Carbon::createFromTimestamp($event['endtime']) : null; $duration = $event['duration'] ?? null; $eventUpid = $event['upid'] ?? $event['timestamp'] ?? ''; $eventKey = md5($eventUpid . ($event['starttime'] ?? '')); $isExpanded = in_array($eventUpid, $this->expandedTaskUpids ?? []); $eventColorMap = [ 'start' => 'text-success', 'shutdown' => 'text-danger', 'reboot' => 'text-info', 'reset' => 'text-warning', 'backup' => 'text-purple-200', ]; $eventColor = $eventColorMap[$event['type']] ?? 'text-base/70'; $lifecycleEventsExportRows[] = [ 'type' => $event['label'] ?? 'N/A', 'status' => ucfirst($event['status'] ?? '-'), 'start_time' => $startTime ? $startTime->format('M d, Y H:i:s') : '-', 'end_time' => $endTime ? $endTime->format('M d, Y H:i:s') : '-', 'duration' => $duration !== null ? $this->formatUptime($duration) : '-', ]; @endphp @empty @endforelse
Type
Status
Start Time
End Time
Duration
{{ $event['label'] ?? 'N/A' }} @if(isset($event['status'])) @if(strtolower($event['status']) === 'ok') Success @elseif(strtolower($event['status']) === 'running') Running @else Failure @endif @else - @endif @if($startTime)
{{ $startTime->format('M d, Y') }}
{{ $startTime->format('H:i:s') }}
@else - @endif
@if($endTime)
{{ $endTime->format('M d, Y') }}
{{ $endTime->format('H:i:s') }}
@else - @endif
@if($duration !== null) {{ $this->formatUptime($duration) }} @else - @endif

Event Information

Type {{ $event['original_type'] ?? 'N/A' }}
Status {{ ucfirst($event['status'] ?? 'Unknown') }}
Event Type {{ $event['label'] ?? 'N/A' }}
@if(isset($event['upid']))
Task ID {{ str_replace([':root@pam!paymenter:', ':root@pam:'], '', $event['upid']) }}
@endif

No lifecycle events available

Lifecycle events will appear here as operations are performed on the server.

@php $historicalComparison = $this->historicalComparison; @endphp

Historical Data Comparison

@if($historicalPeriod === 'custom') @endif
@if($currentPeriod === 'custom') @endif
@if($historicalComparison) @php $current = $historicalComparison['current']; $historical = $historicalComparison['historical']; $diff = $historicalComparison['differences']; @endphp
Metric
Historical ({{ $historical->DateTime->format('M d, Y H:i') }})
Current ({{ $current->DateTime->format('M d, Y H:i') }})
Change
Processor Utilization
{{ number_format($diff['cpu']['historical_percent'], 1) }}% {{ number_format($diff['cpu']['current_percent'], 1) }}% {{ $diff['cpu']['percent_change'] > 0 ? '+' : '' }}{{ number_format($diff['cpu']['percent_change'], 1) }}%
Memory Utilization
{{ number_format($diff['memory']['historical_percent'], 1) }}% {{ number_format($diff['memory']['current_percent'], 1) }}% {{ $diff['memory']['percent_change'] > 0 ? '+' : '' }}{{ number_format($diff['memory']['percent_change'], 1) }}%
Disk Read Rate
{{ $this->formatBytes($diff['disk_read']['historical_rate']) }}/s {{ $this->formatBytes($diff['disk_read']['current_rate']) }}/s {{ $diff['disk_read']['percent_change'] > 0 ? '+' : '' }}{{ number_format($diff['disk_read']['percent_change'], 1) }}%
Disk Write Rate
{{ $this->formatBytes($diff['disk_write']['historical_rate']) }}/s {{ $this->formatBytes($diff['disk_write']['current_rate']) }}/s {{ $diff['disk_write']['percent_change'] > 0 ? '+' : '' }}{{ number_format($diff['disk_write']['percent_change'], 1) }}%
Network Download Rate
{{ $this->formatBytes($diff['network_in']['historical_rate']) }}/s {{ $this->formatBytes($diff['network_in']['current_rate']) }}/s {{ $diff['network_in']['percent_change'] > 0 ? '+' : '' }}{{ number_format($diff['network_in']['percent_change'], 1) }}%
Network Upload Rate
{{ $this->formatBytes($diff['network_out']['historical_rate']) }}/s {{ $this->formatBytes($diff['network_out']['current_rate']) }}/s {{ $diff['network_out']['percent_change'] > 0 ? '+' : '' }}{{ number_format($diff['network_out']['percent_change'], 1) }}%
@else

No comparison data available

Please select periods with available statistics data.

@endif

Loading network analysis…

Network Analysis

Deep visibility into firewall sessions, security threats, and top consumers of bandwidth powered by the Core Router API.

@if($networkAnalysisLoading || ($networkAnalysis['lastUpdated'] === null && $networkAnalysis['error'] === null))

Fetching data from Core Router... reload page

@elseif($networkAnalysis['error'])

{{ $networkAnalysis['error'] }}

Ensure the Core Router API credentials are configured in your environment.

@else
@if(empty($networkAnalysis['connections']))
No matching connections tracked for this server.
@else
@foreach($networkAnalysis['connections'] as $index => $connection) @php // Calculate bytes for sorting (extract numeric value) $bytesForSort = 0; if (isset($connection['bytes_human'])) { $bytesHuman = $connection['bytes_human']; // Extract number and unit, convert to bytes if (preg_match('/([\d.]+)\s*(Bytes|KiB|MiB|GiB|TiB)/i', $bytesHuman, $matches)) { $value = (float)$matches[1]; $unit = strtoupper($matches[2]); $bytesForSort = match($unit) { 'KIB' => $value * 1024, 'MIB' => $value * 1024 * 1024, 'GIB' => $value * 1024 * 1024 * 1024, 'TIB' => $value * 1024 * 1024 * 1024 * 1024, default => $value }; } } @endphp @endforeach
Direction
Protocol
Source
Destination
State
Traffic
@php $direction = $connection['direction'] ?? '—'; @endphp @if($direction !== '—')
{{ $direction }}
@else — @endif
@php $protocol = $connection['protocol'] ?? '—'; @endphp @if($protocol !== '—')
{{ $protocol }}
@else — @endif
@php $sourceIP = $connection['source'] ?? '—'; $isSourcePublic = $sourceIP !== '—' && $this->checkIsPublicIP($sourceIP); @endphp
{{ $sourceIP }} @if($isSourcePublic)
@endif
@if(isset($connection['source_port'])) {{ $connection['source_port'] }} @endif
@php $destIP = $connection['destination'] ?? '—'; $isDestPublic = $destIP !== '—' && $this->checkIsPublicIP($destIP); @endphp
{{ $destIP }} @if($isDestPublic)
@endif
@if(isset($connection['destination_port'])) {{ $connection['destination_port'] }} @endif
@php $state = $connection['state'] ?? '—'; @endphp @if($state !== '—')
{{ $state }}
@else — @endif
{{ $connection['bytes_human'] ?? '—' }} @if(isset($connection['packets'])) {{ number_format($connection['packets']) }} packets @endif
@endif
@if(empty($networkAnalysis['topConnections']))
No connection data available.
@else
@foreach($networkAnalysis['topConnections'] as $index => $row) @php $endpointIP = $row['endpoint'] ?? '—'; $port = $row['port'] ?? 0; $connections = $row['count'] ?? 0; $bytes = $row['bytes'] ?? 0; $bytesForSort = $bytes; @endphp @endforeach
Endpoint
Port
Connections
Traffic
@php $isEndpointPublic = $endpointIP !== '—' && $this->checkIsPublicIP($endpointIP); @endphp
{{ $endpointIP }} @if($isEndpointPublic)
@endif
@if(isset($row['port']) && $row['port'] !== '—')
{{ $row['port'] }}
@else — @endif
{{ number_format($row['count']) }}
{{ $row['bytes_human'] }} {{ number_format($row['packets']) }} packets
@endif
@if(empty($networkAnalysis['topPorts']))
No port statistics are available.
@else
@foreach($networkAnalysis['topPorts'] as $index => $row) @php $port = $row['port'] ?? 0; $connections = $row['connections'] ?? 0; $bytes = $row['bytes'] ?? 0; $bytesForSort = $bytes; @endphp @endforeach
Port
Connections
Traffic
{{ $row['port'] }}
{{ number_format($row['connections']) }}
{{ $row['bytes_human'] }} {{ number_format($row['packets']) }} packets
@endif
@if(empty($networkAnalysis['security']))
No security threats detected. All connections appear to be safe.
@else
@foreach($networkAnalysis['security'] as $warning) @php $conn = $warning['connection'] ?? []; @endphp @php $riskLevel = $warning['risk_level'] ?? 'Medium'; $attackType = $warning['attack_type'] ?? 'Unknown Threat'; $riskDescription = $warning['risk_description'] ?? 'Malicious IP detected from blocklist'; $riskBadgeClass = match($riskLevel) { 'Critical' => 'bg-danger/20 text-danger border-danger/30', 'High' => 'bg-warning/20 text-warning border-warning/30', 'Medium' => 'bg-warning/10 text-warning border-warning/20', 'Low' => 'bg-base/10 text-base/70 border-base/20', default => 'bg-warning/10 text-warning border-warning/20', }; @endphp
Security Threat Detected {{ $warning['type'] }} {{ $riskLevel }} Risk {{ $attackType }} @if(isset($warning['quantity']) && $warning['quantity'] > 1) {{ $warning['quantity'] }}x Repeated @endif

{{ $warning['threat'] }} @if(isset($warning['quantity']) && $warning['quantity'] > 1) ({{ $warning['quantity'] }} similar connection{{ $warning['quantity'] > 1 ? 's' : '' }} detected) @endif

@php $threatIP = $warning['ip'] ?? '—'; $isThreatPublic = $threatIP !== '—' && $this->checkIsPublicIP($threatIP); @endphp
IP Address: {{ $threatIP }} @if($isThreatPublic)
@endif
@endforeach
@endif
@endif

Delete Statistics Entry

This action cannot be undone.

@php $statToDelete = $this->statisticToDelete; @endphp @if($statToDelete)

You are about to delete the following statistics entry:

Date & Time: {{ $statToDelete->DateTime->format('Y-m-d H:i:s') }}
Processor Utilization: {{ number_format($statToDelete->cpumax > 0 ? ($statToDelete->cpuused / $statToDelete->cpumax * 100) : 0, 2) }}%
Memory Utilization: {{ number_format($statToDelete->memorymax > 0 ? ($statToDelete->memoryused / $statToDelete->memorymax * 100) : 0, 2) }}%
Storage I/O: {{ number_format(($statToDelete->diskmax ?? 0) > 0 ? (($statToDelete->diskused ?? 0) / ($statToDelete->diskmax ?? 1) * 100) : 0, 2) }}%
@if($statToDelete->vmstatus)
VM Status: {{ ucfirst($statToDelete->vmstatus) }}
@endif
@endif
Cancel
Delete
Deleting...

Clear Statistics History

This action removes every statistics entry for this server.

All automatic and manual statistics snapshots will be permanently deleted.

This cannot be undone.

Cancel
Clear History
Clearing...

Nothing to Export

We couldn't find any rows to include in the export.

{{ $exportInfoMessage }}

Close
@script @endscript