From a6655fe9922ce98e937db3da9271a1c6d083296b Mon Sep 17 00:00:00 2001 From: Andras Bacsai <5845193+andrasbacsai@users.noreply.github.com> Date: Wed, 7 Oct 2026 13:40:02 +0200 Subject: [PATCH] fix(traffic): merge overflow paths and distinguish rows by domain Combine Sentinel overflow rows into one unlinked "Other paths" row. Show domains beside paths and include them in Livewire row keys. Add regression coverage for overflow aggregation across app keys. --- app/Services/TrafficAnalyticsAggregator.php | 5 ++-- .../livewire/traffic/_paths-list.blade.php | 27 ++++++++++++++----- .../ResourceTrafficKeysTest.php | 12 +++++++++ 3 files changed, 35 insertions(+), 9 deletions(-) diff --git a/app/Services/TrafficAnalyticsAggregator.php b/app/Services/TrafficAnalyticsAggregator.php index fd2c6cf34c..e58a78bc3b 100644 --- a/app/Services/TrafficAnalyticsAggregator.php +++ b/app/Services/TrafficAnalyticsAggregator.php @@ -122,7 +122,8 @@ class TrafficAnalyticsAggregator /** * Merge path rows keyed by (app, path), so the same path under two apps stays two - * rows, each with the domain of the row's Sentinel `app` key. + * rows, each with the domain of the row's Sentinel `app` key. Sentinel's `__other__` + * overflow rows (the long tail past its top-N cap) fold into one row without a domain. * * @param iterable $paths * @param callable(string): ?string $domainForKey @@ -132,7 +133,7 @@ class TrafficAnalyticsAggregator foreach ($paths as $path) { $data = $path->toArray(); $pathStr = (string) ($data['path'] ?? ''); - $appId = (string) ($data['app'] ?? ''); + $appId = $pathStr === '__other__' ? '' : (string) ($data['app'] ?? ''); $key = $appId."\n".$pathStr; $this->paths[$key] ??= [ diff --git a/resources/views/livewire/traffic/_paths-list.blade.php b/resources/views/livewire/traffic/_paths-list.blade.php index ad5e28f46f..2882b0e69b 100644 --- a/resources/views/livewire/traffic/_paths-list.blade.php +++ b/resources/views/livewire/traffic/_paths-list.blade.php @@ -2,7 +2,9 @@ Paginated "top paths" list. Each row shows the request path, a proportional request-volume bar, and right-aligned compact metrics (requests / bytes / p95). The path links to its live URL when the owning domain is known (new tab, - rel="noopener noreferrer nofollow"). Expects `$paths` in scope; optional + rel="noopener noreferrer nofollow"); the domain shows next to the path so the + same path of two apps stays apart. Sentinel's `__other__` overflow row reads + as "Other paths". Expects `$paths` in scope; optional `$keyPrefix` to namespace wire:keys. @param iterable $paths path rows: ['path', 'domain'?, 'requests', 'bytesOut', 'p95'] @@ -32,21 +34,32 @@ @php $domain = $path['domain'] ?? null; $pathStr = (string) ($path['path'] ?? ''); - $href = $domain ? 'https://'.$domain.$pathStr : null; + $isOther = $pathStr === '__other__'; + $href = $domain && ! $isOther ? 'https://'.$domain.$pathStr : null; $requests = (int) ($path['requests'] ?? 0); $s4xx = (int) ($path['s4xx'] ?? 0); $s5xx = (int) ($path['s5xx'] ?? 0); $errorRate = $requests > 0 ? round((($s4xx + $s5xx) / $requests) * 100, 1) : 0; $width = min(100, round(($requests / $maxRequests) * 100, 1)); @endphp -
- @if ($href) - {{ $pathStr }} + @if ($isOther) + Other paths @else - {{ $pathStr }} + + @if ($href) + {{ $pathStr }} + @else + {{ $pathStr }} + @endif + @if ($domain) + {{ $domain }} + @endif + @endif