chore(proxmox): remove Statistics page, Livewire component, and related UI

Made-with: Cursor
This commit is contained in:
2026-03-28 12:15:24 -04:00
parent 85783f8047
commit 5b61b75729
17 changed files with 6 additions and 13393 deletions

View File

@@ -74,7 +74,7 @@
this.expandedCategories[key] = true;
});
// Auto-switch to first matching section
const sections = ['overview', 'quick-start', 'reinstall', 'boot-settings', 'network', 'subdomain', 'cloud-init', 'display', 'statistics', 'system', 'backups', 'console', 'bgp', 'glossary', 'rfc-standards', 'troubleshooting'];
const sections = ['overview', 'quick-start', 'reinstall', 'boot-settings', 'network', 'subdomain', 'cloud-init', 'display', 'system', 'backups', 'console', 'bgp', 'glossary', 'rfc-standards', 'troubleshooting'];
for (const section of sections) {
const sectionElement = document.querySelector(`[data-section-id='${section}']`);
if (sectionElement) {
@@ -148,7 +148,7 @@
</div>
<!-- Configuration -->
<div x-show="matchesQuery('configuration network subdomain cloud-init display statistics')">
<div x-show="matchesQuery('configuration network subdomain cloud-init display')">
<button @click="expandedCategories['configuration'] = !expandedCategories['configuration']"
class="w-full flex items-center justify-between px-3 py-2 rounded-md text-base font-semibold hover:bg-background transition-colors">
<div class="flex items-center gap-2">
@@ -202,13 +202,6 @@
<x-ri-computer-line class="size-4" />
<span>Display</span>
</button>
<button @click="activeSection = 'statistics'"
x-show="shouldShowSection('statistics', 'statistics graphs telemetry cpu memory disk network analysis', 'statistics graphs telemetry cpu memory disk network analysis')"
:class="activeSection === 'statistics' ? 'bg-background text-base font-semibold' : 'text-base/70 hover:text-base'"
class="w-full text-left px-3 py-2 rounded-md transition-colors flex items-center gap-2">
<x-ri-bar-chart-line class="size-4" />
<span>Statistics</span>
</button>
</div>
</div>
@@ -315,7 +308,6 @@
<option value="subdomain">Subdomain</option>
<option value="cloud-init">Cloud-init</option>
<option value="display">Display</option>
<option value="statistics">Statistics</option>
</optgroup>
<optgroup label="Advanced">
<option value="system">System</option>
@@ -345,7 +337,6 @@
'subdomain': 'Subdomain',
'cloud-init': 'Cloud-init',
'display': 'Display',
'statistics': 'Statistics',
'system': 'System',
'backups': 'Backups',
'console': 'Console Access',
@@ -3220,397 +3211,6 @@ network:
</div>
</div>
<!-- Statistics Section -->
<div x-show="activeSection === 'statistics'" x-transition style="display: none;" data-section-id="statistics">
<div class="flex items-center gap-3 mb-4">
<div class="flex items-center justify-center w-10 h-10 rounded-lg bg-primary/10">
<x-ri-bar-chart-line class="size-5 text-primary" />
</div>
<h2 class="text-2xl font-bold">Statistics Tab</h2>
</div>
<p class="text-base/80 mb-6">
The Statistics tab provides comprehensive performance monitoring and historical data tracking for your virtual machine. It automatically collects metrics hourly and allows you to create manual snapshots for detailed analysis.
</p>
<h3 class="text-xl font-semibold mt-6 mb-4 flex items-center gap-2">
<x-ri-history-line class="size-5 text-base/60" />
Automatic Statistics Collection
</h3>
<div class="bg-background border border-neutral rounded-lg p-5 mb-4">
<p class="text-sm text-base/70 mb-3">
The system automatically collects statistics once every hour for all VPS, regardless of their power state or status. This ensures you have a continuous record of your server's performance over time.
</p>
<table class="w-full text-sm mb-3">
<tbody class="text-base/70">
<tr class="border-b border-neutral/20">
<td class="py-2 px-4 font-semibold w-1/3">Collection Frequency</td>
<td class="py-2 px-4">Once every hour (24 times per day)</td>
</tr>
<tr class="border-b border-neutral/20">
<td class="py-2 px-4 font-semibold">Maximum Entries</td>
<td class="py-2 px-4">24 automatic statistics per server</td>
</tr>
<tr class="border-b border-neutral/20">
<td class="py-2 px-4 font-semibold">Retention Policy</td>
<td class="py-2 px-4">Oldest entries are automatically removed when limit is reached</td>
</tr>
<tr class="border-b border-neutral/20">
<td class="py-2 px-4 font-semibold">Power State</td>
<td class="py-2 px-4">Statistics collected regardless of VM power state (running, stopped, etc.)</td>
</tr>
<tr>
<td class="py-2 px-4 font-semibold">Background Process</td>
<td class="py-2 px-4">Runs automatically via Laravel task scheduler</td>
</tr>
</tbody>
</table>
</div>
<h3 class="text-xl font-semibold mt-6 mb-4 flex items-center gap-2">
<x-ri-refresh-line class="size-5 text-base/60" />
Manual Statistics Snapshots
</h3>
<div class="bg-background border border-neutral rounded-lg p-5 mb-4">
<p class="text-sm text-base/70 mb-3">
In addition to automatic collection, you can create up to 5 manual statistics snapshots at any time. These are useful for capturing performance data at specific moments.
</p>
<table class="w-full text-sm mb-3">
<tbody class="text-base/70">
<tr class="border-b border-neutral/20">
<td class="py-2 px-4 font-semibold w-1/3">Maximum Manual Entries</td>
<td class="py-2 px-4">5 per server</td>
</tr>
<tr class="border-b border-neutral/20">
<td class="py-2 px-4 font-semibold">Use Cases</td>
<td class="py-2 px-4">Before/after configuration changes, troubleshooting, performance analysis</td>
</tr>
<tr class="border-b border-neutral/20">
<td class="py-2 px-4 font-semibold">Deletion</td>
<td class="py-2 px-4">Manual statistics can be deleted individually to free up space</td>
</tr>
<tr>
<td class="py-2 px-4 font-semibold">Data Captured</td>
<td class="py-2 px-4">Same metrics as automatic statistics (CPU, memory, disk, network, etc.)</td>
</tr>
</tbody>
</table>
</div>
<h3 class="text-xl font-semibold mt-6 mb-4 flex items-center gap-2">
<x-ri-database-line class="size-5 text-base/60" />
Metrics Tracked
</h3>
<table class="w-full border border-neutral rounded-md mb-4">
<thead class="bg-background">
<tr>
<th class="text-left py-3 px-4 font-semibold border-b border-neutral">Metric</th>
<th class="text-left py-3 px-4 font-semibold border-b border-neutral">Description</th>
<th class="text-left py-3 px-4 font-semibold border-b border-neutral">Display Format</th>
</tr>
</thead>
<tbody class="text-sm text-base/70">
<tr class="border-b border-neutral/20">
<td class="py-2 px-4 font-semibold">CPU Usage</td>
<td class="py-2 px-4">Current CPU utilization as a percentage of allocated CPU resources</td>
<td class="py-2 px-4">Percentage (0-100%)</td>
</tr>
<tr class="border-b border-neutral/20">
<td class="py-2 px-4 font-semibold">Memory Usage</td>
<td class="py-2 px-4">Current RAM utilization compared to maximum allocated memory</td>
<td class="py-2 px-4">Percentage (0-100%)</td>
</tr>
<tr class="border-b border-neutral/20">
<td class="py-2 px-4 font-semibold">Disk Usage</td>
<td class="py-2 px-4">Disk space used compared to total allocated disk space</td>
<td class="py-2 px-4">Percentage (0-100%)</td>
</tr>
<tr class="border-b border-neutral/20">
<td class="py-2 px-4 font-semibold">Network In</td>
<td class="py-2 px-4">Total bytes received since VM start (difference shown between statistics)</td>
<td class="py-2 px-4">Bytes with rate (bytes/s)</td>
</tr>
<tr class="border-b border-neutral/20">
<td class="py-2 px-4 font-semibold">Network Out</td>
<td class="py-2 px-4">Total bytes transmitted since VM start (difference shown between statistics)</td>
<td class="py-2 px-4">Bytes with rate (bytes/s)</td>
</tr>
<tr class="border-b border-neutral/20">
<td class="py-2 px-4 font-semibold">Disk I/O</td>
<td class="py-2 px-4">Disk read and write operations (difference shown between statistics)</td>
<td class="py-2 px-4">Bytes (read/write)</td>
</tr>
<tr class="border-b border-neutral/20">
<td class="py-2 px-4 font-semibold">Uptime</td>
<td class="py-2 px-4">Total time the VM has been running since last boot</td>
<td class="py-2 px-4">Formatted (days, hours, minutes, seconds)</td>
</tr>
<tr>
<td class="py-2 px-4 font-semibold">VM Status</td>
<td class="py-2 px-4">Current power state of the virtual machine</td>
<td class="py-2 px-4">Running, Stopped, etc.</td>
</tr>
</tbody>
</table>
<h3 class="text-xl font-semibold mt-6 mb-4 flex items-center gap-2">
<x-ri-task-line class="size-5 text-base/60" />
Task History
</h3>
<div class="bg-background border border-neutral rounded-lg p-5 mb-4">
<p class="text-sm text-base/70 mb-3">
The Task History section displays all tasks executed on your virtual machine through the Proxmox API. This includes operations like VM management, configuration changes, backups, and other administrative tasks.
</p>
<table class="w-full text-sm mb-3">
<tbody class="text-base/70">
<tr class="border-b border-neutral/20">
<td class="py-2 px-4 font-semibold w-1/3">Auto-Refresh</td>
<td class="py-2 px-4">Task list refreshes every 10 seconds automatically</td>
</tr>
<tr class="border-b border-neutral/20">
<td class="py-2 px-4 font-semibold">Task Details</td>
<td class="py-2 px-4">Click the expand arrow to view detailed task information and logs</td>
</tr>
<tr class="border-b border-neutral/20">
<td class="py-2 px-4 font-semibold">Status Indicators</td>
<td class="py-2 px-4">Tasks show completion status (Success/Failure) with timestamps</td>
</tr>
<tr>
<td class="py-2 px-4 font-semibold">Task Types</td>
<td class="py-2 px-4">VM operations, configuration changes, backups, migrations, etc.</td>
</tr>
</tbody>
</table>
</div>
<h3 class="text-xl font-semibold mt-6 mb-4 flex items-center gap-2">
<x-ri-information-line class="size-5 text-base/60" />
Understanding Statistics Data
</h3>
<div class="space-y-4 mb-6">
<div class="bg-background border border-neutral rounded-lg p-5">
<h4 class="text-md font-semibold mb-2 flex items-center gap-2">
<x-ri-question-line class="size-4 text-primary" />
Network and Disk I/O Values
</h4>
<p class="text-sm text-base/70">
Network In/Out and Disk I/O values displayed in the statistics table represent the <strong>difference</strong> between the current statistic and the previous one. This shows the amount of data transferred or disk operations performed during the time period between statistics. The rate (bytes/s) is calculated based on the time difference between statistics.
</p>
</div>
<div class="bg-background border border-neutral rounded-lg p-5">
<h4 class="text-md font-semibold mb-2 flex items-center gap-2">
<x-ri-time-line class="size-4 text-primary" />
Statistics Retention
</h4>
<p class="text-sm text-base/70">
Automatic statistics are maintained at a maximum of 24 entries per server. When this limit is reached, the oldest automatic statistic is automatically removed when a new one is created. Manual statistics are separate and can be individually deleted. This ensures you always have the most recent 24 hours of automatic performance data while allowing flexibility for manual snapshots.
</p>
</div>
<div class="bg-background border border-neutral rounded-lg p-5">
<h4 class="text-md font-semibold mb-2 flex items-center gap-2">
<x-ri-server-line class="size-4 text-primary" />
Statistics Collection for All VPS
</h4>
<p class="text-sm text-base/70">
Statistics are collected for all virtual machines regardless of their power state (running, stopped, suspended) or service status. This ensures you have a complete historical record of your server's state and can track performance even when the VM is not actively running. Some metrics (like CPU usage) will be zero or minimal when the VM is stopped, but the data point is still valuable for historical tracking.
</p>
</div>
</div>
<h3 class="text-xl font-semibold mt-6 mb-4 flex items-center gap-2">
<x-ri-code-s-slash-line class="size-5 text-base/60" />
Technical Implementation
</h3>
<div class="bg-background border border-neutral rounded-md p-4 mb-4">
<p class="text-sm font-semibold mb-2 flex items-center gap-2">
<x-ri-terminal-box-line class="size-4 text-secondary" />
Background Statistics Collection
</p>
<pre class="bg-background-secondary p-3 rounded text-xs overflow-x-auto"><code># Statistics collection runs via Laravel scheduler
# Scheduled command: proxmox:poll-statistics
# Frequency: Hourly (every hour on the hour)
# Command implementation:
php artisan schedule:run
# The scheduler executes:
Schedule::command(PollServerStatistics::class)
->description('Poll Proxmox server statistics hourly')
->hourly();
# Statistics are stored in database table:
# ext_proxmox_servers_statistics
# Fields tracked:
# - server_id: Foreign key to server
# - netin, netout: Network traffic counters
# - diskread, diskwrite: Disk I/O counters
# - diskused, diskmax: Disk space usage
# - memoryused, memorymax: Memory usage
# - cpuused, cpumax: CPU usage
# - uptime: VM uptime in seconds
# - vmstatus: Current VM power state
# - DateTime: Timestamp of statistic
# - is_automatic: Boolean flag (true for automatic, false for manual)</code></pre>
</div>
<div class="bg-background border border-neutral rounded-md p-4 mb-4">
<p class="text-sm font-semibold mb-2 flex items-center gap-2">
<x-ri-database-line class="size-4 text-secondary" />
Statistics Data Management
</p>
<pre class="bg-background-secondary p-3 rounded text-xs overflow-x-auto"><code># Automatic statistics cleanup logic:
# When creating a new automatic statistic:
1. Create new statistic with is_automatic = true
2. Count total automatic statistics for server
3. If count > 24:
- Find oldest automatic statistics (order by DateTime ASC)
- Delete excess entries (count - 24)
- Keep exactly 24 automatic statistics
# Manual statistics management:
# - Users can create up to 5 manual statistics
# - Manual statistics are marked with is_automatic = false
# - Manual statistics can be deleted individually
# - Manual statistics are NOT automatically cleaned up
# Query examples:
# Get all statistics for a server:
SELECT * FROM ext_proxmox_servers_statistics
WHERE server_id = ?
ORDER BY DateTime DESC;
# Get only automatic statistics:
SELECT * FROM ext_proxmox_servers_statistics
WHERE server_id = ? AND is_automatic = true
ORDER BY DateTime DESC
LIMIT 24;
# Get manual statistics:
SELECT * FROM ext_proxmox_servers_statistics
WHERE server_id = ? AND is_automatic = false
ORDER BY DateTime DESC;</code></pre>
</div>
<h3 class="text-xl font-semibold mt-6 mb-4 flex items-center gap-2">
<x-ri-line-chart-line class="size-5 text-base/60" />
Live Telemetry Graphs
</h3>
<div class="bg-background border border-neutral rounded-md p-4 mb-4">
<p class="text-sm text-base/70 mb-3">
The Live Telemetry section at the top of the Statistics tab shows real-time performance graphs sourced directly from the Proxmox RRD API. These graphs are optimized to load quickly and to avoid overloading either the browser or the API.
</p>
<table class="w-full text-sm mb-3">
<tbody class="text-base/70">
<tr class="border-b border-neutral/20">
<td class="py-2 px-4 font-semibold w-1/3">Graphs</td>
<td class="py-2 px-4">Processor Utilization, Network Traffic, Memory Utilization, Storage I/O</td>
</tr>
<tr class="border-b border-neutral/20">
<td class="py-2 px-4 font-semibold">Update Source</td>
<td class="py-2 px-4">Proxmox RRD API (<code>/nodes/{node}/qemu/{vmid}/rrddata</code>)</td>
</tr>
<tr class="border-b border-neutral/20">
<td class="py-2 px-4 font-semibold">Auto-Refresh</td>
<td class="py-2 px-4">Graphs request fresh data every 2 minutes while the Statistics tab is open.</td>
</tr>
<tr class="border-b border-neutral/20">
<td class="py-2 px-4 font-semibold">Data Sampling</td>
<td class="py-2 px-4">Each graph is sampled down to a maximum of 40 data points to keep rendering smooth and payloads small.</td>
</tr>
<tr>
<td class="py-2 px-4 font-semibold">Aggregation</td>
<td class="py-2 px-4"><strong>Average</strong> uses RRD's AVERAGE consolidation function, and <strong>Maximum</strong> uses the MAX function.</td>
</tr>
</tbody>
</table>
</div>
<div class="bg-background border border-neutral rounded-md p-4 mb-4">
<p class="text-sm font-semibold mb-2 flex items-center gap-2">
<x-ri-ram-line class="size-4 text-secondary" />
Memory Utilization Graph Details
</p>
<ul class="list-disc list-inside text-sm text-base/70 space-y-1 ml-4">
<li>The Memory Utilization graph displays a single series showing current RAM usage over time.</li>
<li>The vertical axis locks to the VM's configured maximum memory when a valid value is available; otherwise it auto-scales to fit the data so the graph is never flat.</li>
<li>Values are shown in bytes and converted to human-readable units (KiB, MiB, GiB) on the y-axis using binary prefixes.</li>
<li>Export actions download the currently displayed memory data points as a CSV file.</li>
</ul>
</div>
<h3 class="text-xl font-semibold mt-6 mb-4 flex items-center gap-2">
<x-ri-router-line class="size-5 text-base/60" />
Network Analysis (Core Router)
</h3>
<div class="bg-background border border-neutral rounded-lg p-5 mb-4">
<p class="text-sm text-base/70 mb-3">
The Network Analysis section is powered by an external Core Router API and provides deep visibility into active firewall sessions, top peers, ports, and security events related to your server's IP addresses.
</p>
<table class="w-full text-sm mb-3">
<tbody class="text-base/70">
<tr class="border-b border-neutral/20">
<td class="py-2 px-4 font-semibold w-1/3">Data Source</td>
<td class="py-2 px-4">Core Router API firewall state table (list of active sessions).</td>
</tr>
<tr class="border-b border-neutral/20">
<td class="py-2 px-4 font-semibold">IP Filtering</td>
<td class="py-2 px-4">Only connections where the source or destination matches an IP assigned to your server are included.</td>
</tr>
<tr class="border-b border-neutral/20">
<td class="py-2 px-4 font-semibold">Sections</td>
<td class="py-2 px-4"><strong>Active Connections</strong>, <strong>Top Peers</strong>, <strong>Top Ports</strong>, and <strong>Security</strong> (threat detections).</td>
</tr>
<tr class="border-b border-neutral/20">
<td class="py-2 px-4 font-semibold">Loading Behaviour</td>
<td class="py-2 px-4">Network Analysis is loaded when the Statistics tab opens. If the Core Router API is not configured or the server has no IPs, a clear warning message is shown instead of an endless loading state.</td>
</tr>
<tr>
<td class="py-2 px-4 font-semibold">Error Handling</td>
<td class="py-2 px-4">HTTP 502 errors from the Core Router API trigger automatic, limited retries with exponential backoff before a final error is presented.</td>
</tr>
</tbody>
</table>
</div>
<div class="bg-background border border-neutral rounded-lg p-5 mb-4">
<p class="text-sm font-semibold mb-2 flex items-center gap-2">
<x-ri-table-line class="size-4 text-secondary" />
Active Connections Table & Traffic Sorting
</p>
<ul class="list-disc list-inside text-sm text-base/70 space-y-1 ml-4">
<li>The <strong>Active Connections</strong> table supports searching, filtering, and clicking any header to sort by that column.</li>
<li>The <strong>Traffic</strong> column sorts by the underlying total bytes for each connection (not the formatted text), so high-traffic sessions rise to the top or bottom depending on the sort direction.</li>
<li>Clicking the Traffic header toggles between descending (largest traffic first) and ascending order.</li>
<li>Very low or empty traffic values still participate in the sort; connections with no traffic are treated as zero.</li>
</ul>
</div>
<div class="bg-background border border-neutral rounded-lg p-5 mb-4">
<p class="text-sm font-semibold mb-2 flex items-center gap-2">
<x-ri-timer-2-line class="size-4 text-secondary" />
Loading & Performance Optimizations
</p>
<ul class="list-disc list-inside text-sm text-base/70 space-y-1 ml-4">
<li>When you first open a server page, the Statistics tab is preloaded in the background so that navigating to it later is faster.</li>
<li>Live Telemetry responses from the Proxmox RRD API are cached per graph type, time range, and aggregation to reduce redundant upstream calls.</li>
<li>Network Analysis results are cached per server for a short period to avoid repeatedly scanning the full firewall state table when you revisit the Statistics tab.</li>
<li>All graphs limit the number of rendered points to keep the UI responsive, even on busy servers with long time ranges selected.</li>
</ul>
</div>
</div>
<!-- System Section -->
<div x-show="activeSection === 'system'" x-transition style="display: none;" data-section-id="system">
<div class="flex items-center gap-3 mb-4">