diff --git a/bootstrap/app.php b/bootstrap/app.php index e7b1eb8bb..a965bf891 100644 --- a/bootstrap/app.php +++ b/bootstrap/app.php @@ -55,4 +55,52 @@ return Application::configure(basePath: dirname(__DIR__)) throw $e; } }); + + // #region agent log + $exceptions->report(function (\Throwable $e) { + try { + $reqPath = ''; + try { + $reqPath = request()?->path() ?? ''; + } catch (\Throwable) { + } + $msg = $e->getMessage(); + $file = $e->getFile(); + $trace = $e->getTraceAsString(); + $normFile = str_replace('\\', '/', $file); + $normTrace = str_replace('\\', '/', $trace); + $relevant = str_contains(strtolower((string) $reqPath), 'statistics') + || str_contains(strtolower((string) $reqPath), 'livewire') + || str_contains(strtolower($msg), 'statistics.blade') + || str_contains(strtolower($msg), 'unable to locate a class or view for component') + || str_contains($msg, 'proxmox::') + || str_contains($normTrace, 'Servers/Proxmox/Livewire/Statistics') + || str_contains($normFile, 'Servers/Proxmox/'); + if (!$relevant) { + return; + } + $payload = [ + 'sessionId' => 'd17155', + 'runId' => 'pre-fix', + 'hypothesisId' => 'H_exc', + 'timestamp' => (int) round(microtime(true) * 1000), + 'location' => 'bootstrap/app.php:withExceptions.report', + 'message' => 'statistics_related_exception', + 'data' => [ + 'class' => $e::class, + 'msg' => $msg, + 'file' => $file, + 'line' => $e->getLine(), + 'reqPath' => $reqPath, + ], + ]; + file_put_contents( + base_path('debug-d17155.log'), + json_encode($payload, JSON_UNESCAPED_SLASHES) . "\n", + FILE_APPEND | LOCK_EX + ); + } catch (\Throwable) { + } + }); + // #endregion })->create(); diff --git a/extensions/Servers/Proxmox/Livewire/Statistics.php b/extensions/Servers/Proxmox/Livewire/Statistics.php index 6c5244a9c..acbead2d6 100644 --- a/extensions/Servers/Proxmox/Livewire/Statistics.php +++ b/extensions/Servers/Proxmox/Livewire/Statistics.php @@ -2001,8 +2001,48 @@ class Statistics extends Component public function getHistoricalComparisonExportDataProperty() { + // #region agent log + try { + file_put_contents( + base_path('debug-d17155.log'), + json_encode([ + 'sessionId' => 'd17155', + 'runId' => 'pre-fix', + 'hypothesisId' => 'H_export', + 'timestamp' => (int) round(microtime(true) * 1000), + 'location' => 'Statistics.php:getHistoricalComparisonExportDataProperty:enter', + 'message' => 'export_getter_enter', + 'data' => [], + ], JSON_UNESCAPED_SLASHES) . "\n", + FILE_APPEND | LOCK_EX + ); + } catch (\Throwable) { + } + // #endregion + try { $comparison = $this->historicalComparison; if (!$comparison || isset($comparison['error'])) { + // #region agent log + try { + file_put_contents( + base_path('debug-d17155.log'), + json_encode([ + 'sessionId' => 'd17155', + 'runId' => 'pre-fix', + 'hypothesisId' => 'H_export', + 'timestamp' => (int) round(microtime(true) * 1000), + 'location' => 'Statistics.php:getHistoricalComparisonExportDataProperty:early_empty', + 'message' => 'export_getter_empty', + 'data' => [ + 'hasComparison' => (bool) $comparison, + 'errorKey' => isset($comparison['error']) ? (string) $comparison['error'] : null, + ], + ], JSON_UNESCAPED_SLASHES) . "\n", + FILE_APPEND | LOCK_EX + ); + } catch (\Throwable) { + } + // #endregion return []; } @@ -2011,13 +2051,35 @@ class Statistics extends Component $diff = $comparison['differences'] ?? null; if (!$current || !$historical || !$diff) { + // #region agent log + try { + file_put_contents( + base_path('debug-d17155.log'), + json_encode([ + 'sessionId' => 'd17155', + 'runId' => 'pre-fix', + 'hypothesisId' => 'H_export', + 'timestamp' => (int) round(microtime(true) * 1000), + 'location' => 'Statistics.php:getHistoricalComparisonExportDataProperty:missing_slices', + 'message' => 'export_getter_empty_slices', + 'data' => [ + 'hasCurrent' => (bool) $current, + 'hasHistorical' => (bool) $historical, + 'hasDiff' => (bool) $diff, + ], + ], JSON_UNESCAPED_SLASHES) . "\n", + FILE_APPEND | LOCK_EX + ); + } catch (\Throwable) { + } + // #endregion return []; } $historicalDateTime = $historical->DateTime->format('Y-m-d H:i:s'); $currentDateTime = $current->DateTime->format('Y-m-d H:i:s'); - return [ + $out = [ [ 'metric' => 'CPU Usage', 'historical_datetime' => $historicalDateTime, @@ -2082,6 +2144,51 @@ class Statistics extends Component 'percent_change' => round($diff['disk_write']['percent_change'], 2) . '%', ], ]; + // #region agent log + try { + file_put_contents( + base_path('debug-d17155.log'), + json_encode([ + 'sessionId' => 'd17155', + 'runId' => 'pre-fix', + 'hypothesisId' => 'H_export', + 'timestamp' => (int) round(microtime(true) * 1000), + 'location' => 'Statistics.php:getHistoricalComparisonExportDataProperty:ok', + 'message' => 'export_getter_ok', + 'data' => ['rowCount' => count($out)], + ], JSON_UNESCAPED_SLASHES) . "\n", + FILE_APPEND | LOCK_EX + ); + } catch (\Throwable) { + } + // #endregion + return $out; + } catch (\Throwable $ex) { + // #region agent log + try { + file_put_contents( + base_path('debug-d17155.log'), + json_encode([ + 'sessionId' => 'd17155', + 'runId' => 'pre-fix', + 'hypothesisId' => 'H_export', + 'timestamp' => (int) round(microtime(true) * 1000), + 'location' => 'Statistics.php:getHistoricalComparisonExportDataProperty:catch', + 'message' => 'export_getter_throw', + 'data' => [ + 'class' => $ex::class, + 'msg' => $ex->getMessage(), + 'file' => $ex->getFile(), + 'line' => $ex->getLine(), + ], + ], JSON_UNESCAPED_SLASHES) . "\n", + FILE_APPEND | LOCK_EX + ); + } catch (\Throwable) { + } + // #endregion + throw $ex; + } } public function exportHistoricalComparison() @@ -3837,6 +3944,24 @@ class Statistics extends Component public function render() { + // #region agent log + try { + file_put_contents( + base_path('debug-d17155.log'), + json_encode([ + 'sessionId' => 'd17155', + 'runId' => 'pre-fix', + 'hypothesisId' => 'H_render', + 'timestamp' => (int) round(microtime(true) * 1000), + 'location' => 'Statistics.php:render:enter', + 'message' => 'statistics_render_enter', + 'data' => ['serverId' => $this->server->id ?? null], + ], JSON_UNESCAPED_SLASHES) . "\n", + FILE_APPEND | LOCK_EX + ); + } catch (\Throwable) { + } + // #endregion return view('proxmox::statistics')->layoutData([ 'sidebar' => true, ]); diff --git a/extensions/Servers/Proxmox/views/statistics.blade.php b/extensions/Servers/Proxmox/views/statistics.blade.php index 76a1bbc2f..01c016ae2 100644 --- a/extensions/Servers/Proxmox/views/statistics.blade.php +++ b/extensions/Servers/Proxmox/views/statistics.blade.php @@ -95,7 +95,7 @@ 'label' => 'CPU pulse', 'value' => $statLiveCpuPct . '%', 'hint' => $statCpuCores . ' vCPU budget', - 'icon' => 'x-ri-cpu-line', + 'icon' => 'ri-cpu-line', 'tone' => 'sky', ], [ @@ -104,21 +104,21 @@ 'hint' => $statMemMax > 0 ? \Illuminate\Support\Number::fileSize(bytes: $statMemUsed) . ' of ' . \Illuminate\Support\Number::fileSize(bytes: $statMemMax) : 'RAM cap unknown', - 'icon' => 'x-ri-database-2-line', + 'icon' => 'ri-database-2-line', 'tone' => 'emerald', ], [ 'label' => 'Stored samples', 'value' => number_format($statSnapshotCount), 'hint' => 'Hourly automation + five manual pins', - 'icon' => 'x-ri-stack-line', + 'icon' => 'ri-stack-line', 'tone' => 'violet', ], [ 'label' => 'Signals loaded', 'value' => number_format($statTaskBufferCount) . ' jobs', 'hint' => $statLifecyclePreview . ' lifecycle beats mapped', - 'icon' => 'x-ri-pulse-line', + 'icon' => 'ri-pulse-line', 'tone' => 'amber', ], ];