diff --git a/app/Livewire/Fleet/Metrics.php b/app/Livewire/Fleet/Metrics.php index 0d44d1d470..679fdf5593 100644 --- a/app/Livewire/Fleet/Metrics.php +++ b/app/Livewire/Fleet/Metrics.php @@ -35,12 +35,17 @@ class Metrics extends Component #[Url(as: 'cmetric')] public string $containerMetric = 'cpu'; + public bool $live = false; + /** @var array */ public array $kpis = []; /** @var array> */ public array $serverRows = []; + /** @var array> All fetched containers, kept so the metric toggle re-ranks without re-fetching. */ + public array $containersRaw = []; + /** @var array> */ public array $topContainers = []; @@ -78,7 +83,8 @@ class Metrics extends Component public function updatedContainerMetric(): void { - $this->loadData(); + // Re-rank the already-fetched containers; no need to re-hit Sentinel. + $this->topContainers = FleetMetricsAggregator::rankContainers($this->containersRaw, $this->containerMetric); } public function setRange(string $range): void @@ -87,6 +93,11 @@ class Metrics extends Component $this->loadData(); } + public function isLivePollable(): bool + { + return $this->live && $this->range === '24h'; + } + /** * @return Collection */ @@ -147,6 +158,7 @@ class Metrics extends Component $this->serverRows = $rows; $this->kpis = FleetMetricsAggregator::fleetKpis($rows); + $this->containersRaw = $containers; $this->topContainers = FleetMetricsAggregator::rankContainers($containers, $this->containerMetric); $this->chartData = $this->buildChartPayload($series); diff --git a/app/Services/SentinelMetricsClient.php b/app/Services/SentinelMetricsClient.php index 5f27f1e564..820fd9c0f8 100644 --- a/app/Services/SentinelMetricsClient.php +++ b/app/Services/SentinelMetricsClient.php @@ -9,6 +9,9 @@ class SentinelMetricsClient { private string $base = 'http://localhost:8888/api'; + /** Cap on points per trend series after downsampling raw Sentinel samples. */ + private const MAX_SERIES_POINTS = 300; + public function __construct(protected Server $server) {} public static function rangeFrom(string $range): string @@ -126,10 +129,18 @@ class SentinelMetricsClient return []; } - return array_values(array_map( + $series = array_values(array_map( fn ($r) => [(int) ($r['time'] ?? 0), (float) ($r[$field] ?? 0)], $rows )); + + // Sentinel returns raw samples (thousands of points over 24h). Cap the series so + // the chart payload stays small enough to embed and morph cheaply. + if (count($series) > self::MAX_SERIES_POINTS) { + $series = downsampleLTTB($series, self::MAX_SERIES_POINTS); + } + + return $series; } /** diff --git a/resources/views/livewire/fleet/metrics.blade.php b/resources/views/livewire/fleet/metrics.blade.php index db28a47285..07bd0d9e0d 100644 --- a/resources/views/livewire/fleet/metrics.blade.php +++ b/resources/views/livewire/fleet/metrics.blade.php @@ -30,6 +30,28 @@ $serverListboxOptions = array_merge(
+ @if ($range === '24h') +
+ +
+ @endif
@foreach (['24h' => '24 hours', '7d' => '7 days', '30d' => '30 days'] as $value => $label)