diff --git a/resources/views/livewire/slow-requests.blade.php b/resources/views/livewire/slow-requests.blade.php
index 5daeb89a..c8be509a 100644
--- a/resources/views/livewire/slow-requests.blade.php
+++ b/resources/views/livewire/slow-requests.blade.php
@@ -8,6 +8,19 @@
+ @php
+ $message = <<
+
+
+
@@ -31,12 +46,14 @@
+
Method
Route
Count
+ Average
Slowest
@@ -66,9 +83,12 @@
@if ($config['sample_rate'] < 1)
~{{ number_format($slowRequest->count * (1 / $config['sample_rate'])) }}
@else
- {{ number_format($slowRequest->count) }}
+ {{ number_format($slowRequest->count) }} / {{ number_format($slowRequest->total) }}
@endif
+
+ {{ number_format($slowRequest->avg) }} ms
+
@if ($slowRequest->slowest === null)
Unknown
diff --git a/src/Livewire/SlowRequests.php b/src/Livewire/SlowRequests.php
index 9521f9c2..7c165b58 100644
--- a/src/Livewire/SlowRequests.php
+++ b/src/Livewire/SlowRequests.php
@@ -21,7 +21,7 @@ class SlowRequests extends Card
/**
* Ordering.
*
- * @var 'slowest'|'count'
+ * @var 'slowest'|'count'|'average'|'total'
*/
#[Url(as: 'slow-requests')]
public string $orderBy = 'slowest';
@@ -34,12 +34,15 @@ public function render(): Renderable
[$slowRequests, $time, $runAt] = $this->remember(
fn () => $this->aggregate(
'slow_request',
- ['max', 'count'],
+ ['max', 'count', 'avg'],
match ($this->orderBy) {
'count' => 'count',
+ 'average' => 'avg',
+ 'total' => 'avg_count',
default => 'max',
},
- )->map(function ($row) {
+ )
+ ->map(function ($row) {
[$method, $uri, $action] = json_decode($row->key, flags: JSON_THROW_ON_ERROR);
return (object) [
@@ -48,6 +51,8 @@ public function render(): Renderable
'action' => $action,
'count' => $row->count,
'slowest' => $row->max,
+ 'avg' => $row->avg,
+ 'total' => $row->avg_count,
'threshold' => $this->threshold($uri, SlowRequestsRecorder::class),
];
}),
diff --git a/src/Recorders/SlowRequests.php b/src/Recorders/SlowRequests.php
index d7038261..04e59142 100644
--- a/src/Recorders/SlowRequests.php
+++ b/src/Recorders/SlowRequests.php
@@ -54,19 +54,26 @@ public function record(Carbon $startedAt, Request $request, Response $response):
[$path, $via] = $this->resolveRoutePath($request);
- if (
- $this->shouldIgnore($path) ||
- $this->underThreshold($duration = ((int) $startedAt->diffInMilliseconds()), $path)
- ) {
+ if ($this->shouldIgnore($path)) {
return;
}
- $this->pulse->record(
+ $duration = ((int) $startedAt->diffInMilliseconds());
+
+ // Record average and max duration for all requests.
+ $entry = $this->pulse->record(
type: 'slow_request',
key: json_encode([$request->method(), $path, $via], flags: JSON_THROW_ON_ERROR),
value: $duration,
timestamp: $startedAt,
- )->max()->count();
+ )->avg()->max();
+
+ if ($this->underThreshold($duration, $path)) {
+ return;
+ }
+
+ // Record count of slow requests
+ $entry->count();
if ($userId = $this->pulse->resolveAuthenticatedUserId()) {
$this->pulse->record(
diff --git a/src/Storage/DatabaseStorage.php b/src/Storage/DatabaseStorage.php
index 09b75812..56d3b2f3 100644
--- a/src/Storage/DatabaseStorage.php
+++ b/src/Storage/DatabaseStorage.php
@@ -540,6 +540,10 @@ public function aggregate(
$orderBy ??= $aggregates[0];
+ if (in_array('avg', $aggregates)) {
+ $aggregates[] = 'avg_count';
+ }
+
/** @phpstan-ignore return.type */
return $this->connection()
->query()
@@ -561,6 +565,7 @@ public function aggregate(
'max' => "max({$this->wrap('max')})",
'sum' => "sum({$this->wrap('sum')})",
'avg' => "avg({$this->wrap('avg')})",
+ 'avg_count' => "sum({$this->wrap('avg_count')})",
}." as {$this->wrap($aggregate)}");
}
@@ -581,6 +586,7 @@ public function aggregate(
'max' => "max({$this->wrap('value')})",
'sum' => "sum({$this->wrap('value')})",
'avg' => "avg({$this->wrap('value')})",
+ 'avg_count' => 'count(*)',
}." as {$this->wrap($aggregate)}");
}
@@ -593,6 +599,10 @@ public function aggregate(
// Buckets
foreach ($aggregates as $currentAggregate) {
+ if ($currentAggregate === 'avg_count') {
+ continue;
+ }
+
$query->unionAll(function (Builder $query) use ($type, $aggregates, $currentAggregate, $period, $oldestBucket) {
$query->select('key_hash');
@@ -605,6 +615,8 @@ public function aggregate(
'sum' => "sum({$this->wrap('value')})",
'avg' => "avg({$this->wrap('value')})",
}." as {$this->wrap($aggregate)}");
+ } elseif ($aggregate === 'avg_count' && $currentAggregate === 'avg') {
+ $query->selectRaw("sum({$this->wrap('count')}) as {$this->wrap('avg_count')}");
} else {
$query->selectRaw("null as {$this->wrap($aggregate)}");
}
diff --git a/tests/Feature/Livewire/CacheTest.php b/tests/Feature/Livewire/CacheTest.php
index 80ddbbd2..087bcdf1 100644
--- a/tests/Feature/Livewire/CacheTest.php
+++ b/tests/Feature/Livewire/CacheTest.php
@@ -58,8 +58,8 @@
Pulse::ingest();
Livewire::test(Cache::class, ['lazy' => false])
- ->assertDontSeeHtml("100.00%\n")
- ->assertSeeHtml("99.99%\n");
+ ->assertDontSeeHtml("100.00%" . PHP_EOL)
+ ->assertSeeHtml("99.99%" . PHP_EOL);
});
it('does not show decimals for round numbers', function () {
@@ -68,6 +68,6 @@
Pulse::ingest();
Livewire::test(Cache::class, ['lazy' => false])
- ->assertDontSeeHtml("50.00%\n")
- ->assertSeeHtml("50%\n");
+ ->assertDontSeeHtml("50.00%" . PHP_EOL)
+ ->assertSeeHtml("50%" . PHP_EOL);
});
diff --git a/tests/Feature/Livewire/SlowRequestsTest.php b/tests/Feature/Livewire/SlowRequestsTest.php
index ee303286..55cc42d7 100644
--- a/tests/Feature/Livewire/SlowRequestsTest.php
+++ b/tests/Feature/Livewire/SlowRequestsTest.php
@@ -17,26 +17,26 @@
// Add entries outside of the window.
Carbon::setTestNow('2000-01-01 12:00:00');
- Pulse::record('slow_request', $request1, 1)->max()->count();
- Pulse::record('slow_request', $request2, 1)->max()->count();
+ Pulse::record('slow_request', $request1, 1)->avg()->max()->count();
+ Pulse::record('slow_request', $request2, 1)->avg()->max()->count();
// Add entries to the "tail".
Carbon::setTestNow('2000-01-01 12:00:01');
- Pulse::record('slow_request', $request1, 1234)->max()->count();
- Pulse::record('slow_request', $request1, 2468)->max()->count();
- Pulse::record('slow_request', $request2, 1234)->max()->count();
+ Pulse::record('slow_request', $request1, 1234)->avg()->max()->count();
+ Pulse::record('slow_request', $request1, 2468)->avg()->max()->count();
+ Pulse::record('slow_request', $request2, 1234)->avg()->max()->count();
// Add entries to the current buckets.
Carbon::setTestNow('2000-01-01 13:00:00');
- Pulse::record('slow_request', $request1, 1000)->max()->count();
- Pulse::record('slow_request', $request1, 1000)->max()->count();
- Pulse::record('slow_request', $request2, 1000)->max()->count();
+ Pulse::record('slow_request', $request1, 1000)->avg()->max()->count();
+ Pulse::record('slow_request', $request1, 1000)->avg()->max()->count();
+ Pulse::record('slow_request', $request2, 1000)->avg()->max()->count();
Pulse::ingest();
Livewire::test(SlowRequests::class, ['lazy' => false])
->assertViewHas('slowRequests', collect([
- (object) ['method' => 'GET', 'uri' => '/users', 'action' => 'FooController@index', 'count' => 4, 'slowest' => 2468, 'threshold' => 1_000],
- (object) ['method' => 'GET', 'uri' => '/users/{user}', 'action' => 'Closure', 'count' => 2, 'slowest' => 1234, 'threshold' => 1_000],
+ (object) ['method' => 'GET', 'uri' => '/users', 'action' => 'FooController@index', 'count' => 4, 'slowest' => 2468, 'threshold' => 1_000, 'avg' => 1425.5, 'total' => 4],
+ (object) ['method' => 'GET', 'uri' => '/users/{user}', 'action' => 'Closure', 'count' => 2, 'slowest' => 1234, 'threshold' => 1_000, 'avg' => 1117, 'total' => 2],
]));
});
diff --git a/tests/Feature/Recorders/SlowRequestsTest.php b/tests/Feature/Recorders/SlowRequestsTest.php
index b02afd68..d1e50e8d 100644
--- a/tests/Feature/Recorders/SlowRequestsTest.php
+++ b/tests/Feature/Recorders/SlowRequestsTest.php
@@ -33,69 +33,107 @@
expect($entries[0]->value)->toBe(4000);
$aggregates = Pulse::ignore(fn () => DB::table('pulse_aggregates')->orderBy('type')->orderBy('period')->orderBy('aggregate')->get());
- expect($aggregates)->toHaveCount(8);
+ expect($aggregates)->toHaveCount(12);
expect($aggregates[0]->bucket)->toBe(946782240);
expect($aggregates[0]->period)->toBe(60);
expect($aggregates[0]->type)->toBe('slow_request');
- expect($aggregates[0]->aggregate)->toBe('count');
+ expect($aggregates[0]->aggregate)->toBe('avg');
expect($aggregates[0]->key)->toBe(json_encode(['GET', '/test-route', 'Closure']));
expect($aggregates[0]->key_hash)->toBe(keyHash(json_encode(['GET', '/test-route', 'Closure'])));
- expect($aggregates[0]->value)->toEqual(1);
+ expect($aggregates[0]->value)->toEqual(4000);
+ expect($aggregates[0]->count)->toEqual(1);
expect($aggregates[1]->bucket)->toBe(946782240);
expect($aggregates[1]->period)->toBe(60);
expect($aggregates[1]->type)->toBe('slow_request');
- expect($aggregates[1]->aggregate)->toBe('max');
+ expect($aggregates[1]->aggregate)->toBe('count');
expect($aggregates[1]->key)->toBe(json_encode(['GET', '/test-route', 'Closure']));
expect($aggregates[1]->key_hash)->toBe(keyHash(json_encode(['GET', '/test-route', 'Closure'])));
- expect($aggregates[1]->value)->toEqual(4000);
+ expect($aggregates[1]->value)->toEqual(1);
- expect($aggregates[2]->bucket)->toBe(946782000);
- expect($aggregates[2]->period)->toBe(360);
+ expect($aggregates[2]->bucket)->toBe(946782240);
+ expect($aggregates[2]->period)->toBe(60);
expect($aggregates[2]->type)->toBe('slow_request');
- expect($aggregates[2]->aggregate)->toBe('count');
+ expect($aggregates[2]->aggregate)->toBe('max');
expect($aggregates[2]->key)->toBe(json_encode(['GET', '/test-route', 'Closure']));
expect($aggregates[2]->key_hash)->toBe(keyHash(json_encode(['GET', '/test-route', 'Closure'])));
- expect($aggregates[2]->value)->toEqual(1);
+ expect($aggregates[2]->value)->toEqual(4000);
expect($aggregates[3]->bucket)->toBe(946782000);
expect($aggregates[3]->period)->toBe(360);
expect($aggregates[3]->type)->toBe('slow_request');
- expect($aggregates[3]->aggregate)->toBe('max');
+ expect($aggregates[3]->aggregate)->toBe('avg');
expect($aggregates[3]->key)->toBe(json_encode(['GET', '/test-route', 'Closure']));
expect($aggregates[3]->key_hash)->toBe(keyHash(json_encode(['GET', '/test-route', 'Closure'])));
expect($aggregates[3]->value)->toEqual(4000);
+ expect($aggregates[3]->count)->toEqual(1);
- expect($aggregates[4]->bucket)->toBe(946781280);
- expect($aggregates[4]->period)->toBe(1440);
+ expect($aggregates[4]->bucket)->toBe(946782000);
+ expect($aggregates[4]->period)->toBe(360);
expect($aggregates[4]->type)->toBe('slow_request');
expect($aggregates[4]->aggregate)->toBe('count');
expect($aggregates[4]->key)->toBe(json_encode(['GET', '/test-route', 'Closure']));
expect($aggregates[4]->key_hash)->toBe(keyHash(json_encode(['GET', '/test-route', 'Closure'])));
expect($aggregates[4]->value)->toEqual(1);
- expect($aggregates[5]->bucket)->toBe(946781280);
- expect($aggregates[5]->period)->toBe(1440);
+ expect($aggregates[5]->bucket)->toBe(946782000);
+ expect($aggregates[5]->period)->toBe(360);
expect($aggregates[5]->type)->toBe('slow_request');
expect($aggregates[5]->aggregate)->toBe('max');
expect($aggregates[5]->key)->toBe(json_encode(['GET', '/test-route', 'Closure']));
expect($aggregates[5]->key_hash)->toBe(keyHash(json_encode(['GET', '/test-route', 'Closure'])));
expect($aggregates[5]->value)->toEqual(4000);
- expect($aggregates[6]->period)->toBe(10080);
+ expect($aggregates[6]->bucket)->toBe(946781280);
+ expect($aggregates[6]->period)->toBe(1440);
expect($aggregates[6]->type)->toBe('slow_request');
- expect($aggregates[6]->aggregate)->toBe('count');
+ expect($aggregates[6]->aggregate)->toBe('avg');
expect($aggregates[6]->key)->toBe(json_encode(['GET', '/test-route', 'Closure']));
expect($aggregates[6]->key_hash)->toBe(keyHash(json_encode(['GET', '/test-route', 'Closure'])));
- expect($aggregates[6]->value)->toEqual(1);
+ expect($aggregates[6]->value)->toEqual(4000);
+ expect($aggregates[6]->count)->toEqual(1);
- expect($aggregates[7]->period)->toBe(10080);
+ expect($aggregates[7]->bucket)->toBe(946781280);
+ expect($aggregates[7]->period)->toBe(1440);
expect($aggregates[7]->type)->toBe('slow_request');
- expect($aggregates[7]->aggregate)->toBe('max');
+ expect($aggregates[7]->aggregate)->toBe('count');
expect($aggregates[7]->key)->toBe(json_encode(['GET', '/test-route', 'Closure']));
expect($aggregates[7]->key_hash)->toBe(keyHash(json_encode(['GET', '/test-route', 'Closure'])));
- expect($aggregates[7]->value)->toEqual(4000);
+ expect($aggregates[7]->value)->toEqual(1);
+
+ expect($aggregates[8]->bucket)->toBe(946781280);
+ expect($aggregates[8]->period)->toBe(1440);
+ expect($aggregates[8]->type)->toBe('slow_request');
+ expect($aggregates[8]->aggregate)->toBe('max');
+ expect($aggregates[8]->key)->toBe(json_encode(['GET', '/test-route', 'Closure']));
+ expect($aggregates[8]->key_hash)->toBe(keyHash(json_encode(['GET', '/test-route', 'Closure'])));
+ expect($aggregates[8]->value)->toEqual(4000);
+
+ expect($aggregates[9]->bucket)->toBe(946774080);
+ expect($aggregates[9]->period)->toBe(10080);
+ expect($aggregates[9]->type)->toBe('slow_request');
+ expect($aggregates[9]->aggregate)->toBe('avg');
+ expect($aggregates[9]->key)->toBe(json_encode(['GET', '/test-route', 'Closure']));
+ expect($aggregates[9]->key_hash)->toBe(keyHash(json_encode(['GET', '/test-route', 'Closure'])));
+ expect($aggregates[9]->value)->toEqual(4000);
+ expect($aggregates[9]->count)->toEqual(1);
+
+ expect($aggregates[10]->bucket)->toBe(946774080);
+ expect($aggregates[10]->period)->toBe(10080);
+ expect($aggregates[10]->type)->toBe('slow_request');
+ expect($aggregates[10]->aggregate)->toBe('count');
+ expect($aggregates[10]->key)->toBe(json_encode(['GET', '/test-route', 'Closure']));
+ expect($aggregates[10]->key_hash)->toBe(keyHash(json_encode(['GET', '/test-route', 'Closure'])));
+ expect($aggregates[10]->value)->toEqual(1);
+
+ expect($aggregates[11]->bucket)->toBe(946774080);
+ expect($aggregates[11]->period)->toBe(10080);
+ expect($aggregates[11]->type)->toBe('slow_request');
+ expect($aggregates[11]->aggregate)->toBe('max');
+ expect($aggregates[11]->key)->toBe(json_encode(['GET', '/test-route', 'Closure']));
+ expect($aggregates[11]->key_hash)->toBe(keyHash(json_encode(['GET', '/test-route', 'Closure'])));
+ expect($aggregates[11]->value)->toEqual(4000);
Pulse::ignore(fn () => expect(DB::table('pulse_values')->count())->toBe(0));
});
@@ -122,12 +160,23 @@
get('default-threshold')->assertOk();
$entries = Pulse::ignore(fn () => DB::table('pulse_entries')->get());
- expect($entries)->toHaveCount(1);
+ expect($entries)->toHaveCount(3);
+
expect($entries[0]->type)->toBe('slow_request');
expect($entries[0]->key)->toBe(json_encode(['GET', '/one-second-threshold', 'Closure']));
expect($entries[0]->key_hash)->toBe(keyHash(json_encode(['GET', '/one-second-threshold', 'Closure'])));
expect($entries[0]->value)->toBe(1000);
+ expect($entries[1]->type)->toBe('slow_request');
+ expect($entries[1]->key)->toBe(json_encode(['GET', '/two-second-threshold', 'Closure']));
+ expect($entries[1]->key_hash)->toBe(keyHash(json_encode(['GET', '/two-second-threshold', 'Closure'])));
+ expect($entries[1]->value)->toBe(1000);
+
+ expect($entries[2]->type)->toBe('slow_request');
+ expect($entries[2]->key)->toBe(json_encode(['GET', '/default-threshold', 'Closure']));
+ expect($entries[2]->key_hash)->toBe(keyHash(json_encode(['GET', '/default-threshold', 'Closure'])));
+ expect($entries[2]->value)->toBe(0);
+
DB::table('pulse_entries')->delete();
$sleepSeconds = 2;
@@ -136,15 +185,21 @@
get('default-threshold')->assertOk();
$entries = Pulse::ignore(fn () => DB::table('pulse_entries')->orderBy('key')->get());
- expect($entries)->toHaveCount(2);
+ expect($entries)->toHaveCount(3);
expect($entries[0]->type)->toBe('slow_request');
- expect($entries[0]->key)->toBe(json_encode(['GET', '/one-second-threshold', 'Closure']));
- expect($entries[0]->key_hash)->toBe(keyHash(json_encode(['GET', '/one-second-threshold', 'Closure'])));
- expect($entries[0]->value)->toBe(2000);
+ expect($entries[0]->key)->toBe(json_encode(['GET', '/default-threshold', 'Closure']));
+ expect($entries[0]->key_hash)->toBe(keyHash(json_encode(['GET', '/default-threshold', 'Closure'])));
+ expect($entries[0]->value)->toBe(0);
+
expect($entries[1]->type)->toBe('slow_request');
- expect($entries[1]->key)->toBe(json_encode(['GET', '/two-second-threshold', 'Closure']));
- expect($entries[1]->key_hash)->toBe(keyHash(json_encode(['GET', '/two-second-threshold', 'Closure'])));
+ expect($entries[1]->key)->toBe(json_encode(['GET', '/one-second-threshold', 'Closure']));
+ expect($entries[1]->key_hash)->toBe(keyHash(json_encode(['GET', '/one-second-threshold', 'Closure'])));
expect($entries[1]->value)->toBe(2000);
+
+ expect($entries[2]->type)->toBe('slow_request');
+ expect($entries[2]->key)->toBe(json_encode(['GET', '/two-second-threshold', 'Closure']));
+ expect($entries[2]->key_hash)->toBe(keyHash(json_encode(['GET', '/two-second-threshold', 'Closure'])));
+ expect($entries[2]->value)->toBe(2000);
});
it('captures slow requests per user', function () {
@@ -212,7 +267,7 @@
get('test-route');
Pulse::ignore(fn () => expect(DB::table('pulse_entries')->get())->toHaveCount(1));
- Pulse::ignore(fn () => expect(DB::table('pulse_aggregates')->get())->toHaveCount(8));
+ Pulse::ignore(fn () => expect(DB::table('pulse_aggregates')->get())->toHaveCount(12));
Pulse::ignore(fn () => expect(DB::table('pulse_values')->count())->toBe(0));
});
@@ -225,8 +280,8 @@
get('test-route');
- Pulse::ignore(fn () => expect(DB::table('pulse_entries')->count())->toBe(0));
- Pulse::ignore(fn () => expect(DB::table('pulse_aggregates')->count())->toBe(0));
+ Pulse::ignore(fn () => expect(DB::table('pulse_entries')->count())->toBe(1));
+ Pulse::ignore(fn () => expect(DB::table('pulse_aggregates')->count())->toBe(8));
Pulse::ignore(fn () => expect(DB::table('pulse_values')->count())->toBe(0));
});
@@ -320,71 +375,107 @@
expect($entries[0]->value)->toBe(4000);
$aggregates = Pulse::ignore(fn () => DB::table('pulse_aggregates')->orderBy('type')->orderBy('period')->orderBy('aggregate')->get());
- expect($aggregates)->toHaveCount(8);
+ expect($aggregates)->toHaveCount(12);
expect($aggregates[0]->bucket)->toBe(946782240);
expect($aggregates[0]->period)->toBe(60);
expect($aggregates[0]->type)->toBe('slow_request');
- expect($aggregates[0]->aggregate)->toBe('count');
+ expect($aggregates[0]->aggregate)->toBe('avg');
expect($aggregates[0]->key)->toBe(json_encode(['POST', '/test-route', 'via /livewire/update']));
expect($aggregates[0]->key_hash)->toBe(keyHash(json_encode(['POST', '/test-route', 'via /livewire/update'])));
- expect($aggregates[0]->value)->toEqual(1);
+ expect($aggregates[0]->value)->toEqual(4000);
+ expect($aggregates[0]->count)->toEqual(1);
expect($aggregates[1]->bucket)->toBe(946782240);
expect($aggregates[1]->period)->toBe(60);
expect($aggregates[1]->type)->toBe('slow_request');
- expect($aggregates[1]->aggregate)->toBe('max');
+ expect($aggregates[1]->aggregate)->toBe('count');
expect($aggregates[1]->key)->toBe(json_encode(['POST', '/test-route', 'via /livewire/update']));
expect($aggregates[1]->key_hash)->toBe(keyHash(json_encode(['POST', '/test-route', 'via /livewire/update'])));
- expect($aggregates[1]->value)->toEqual(4000);
+ expect($aggregates[1]->value)->toEqual(1);
- expect($aggregates[2]->bucket)->toBe(946782000);
- expect($aggregates[2]->period)->toBe(360);
+ expect($aggregates[2]->bucket)->toBe(946782240);
+ expect($aggregates[2]->period)->toBe(60);
expect($aggregates[2]->type)->toBe('slow_request');
- expect($aggregates[2]->aggregate)->toBe('count');
+ expect($aggregates[2]->aggregate)->toBe('max');
expect($aggregates[2]->key)->toBe(json_encode(['POST', '/test-route', 'via /livewire/update']));
expect($aggregates[2]->key_hash)->toBe(keyHash(json_encode(['POST', '/test-route', 'via /livewire/update'])));
- expect($aggregates[2]->value)->toEqual(1);
+ expect($aggregates[2]->value)->toEqual(4000);
expect($aggregates[3]->bucket)->toBe(946782000);
expect($aggregates[3]->period)->toBe(360);
expect($aggregates[3]->type)->toBe('slow_request');
- expect($aggregates[3]->aggregate)->toBe('max');
+ expect($aggregates[3]->aggregate)->toBe('avg');
expect($aggregates[3]->key)->toBe(json_encode(['POST', '/test-route', 'via /livewire/update']));
expect($aggregates[3]->key_hash)->toBe(keyHash(json_encode(['POST', '/test-route', 'via /livewire/update'])));
expect($aggregates[3]->value)->toEqual(4000);
+ expect($aggregates[3]->count)->toEqual(1);
- expect($aggregates[4]->bucket)->toBe(946781280);
- expect($aggregates[4]->period)->toBe(1440);
+ expect($aggregates[4]->bucket)->toBe(946782000);
+ expect($aggregates[4]->period)->toBe(360);
expect($aggregates[4]->type)->toBe('slow_request');
expect($aggregates[4]->aggregate)->toBe('count');
expect($aggregates[4]->key)->toBe(json_encode(['POST', '/test-route', 'via /livewire/update']));
expect($aggregates[4]->key_hash)->toBe(keyHash(json_encode(['POST', '/test-route', 'via /livewire/update'])));
expect($aggregates[4]->value)->toEqual(1);
- expect($aggregates[5]->bucket)->toBe(946781280);
- expect($aggregates[5]->period)->toBe(1440);
+ expect($aggregates[5]->bucket)->toBe(946782000);
+ expect($aggregates[5]->period)->toBe(360);
expect($aggregates[5]->type)->toBe('slow_request');
expect($aggregates[5]->aggregate)->toBe('max');
expect($aggregates[5]->key)->toBe(json_encode(['POST', '/test-route', 'via /livewire/update']));
expect($aggregates[5]->key_hash)->toBe(keyHash(json_encode(['POST', '/test-route', 'via /livewire/update'])));
expect($aggregates[5]->value)->toEqual(4000);
- expect($aggregates[6]->bucket)->toBe(946774080);
- expect($aggregates[6]->period)->toBe(10080);
+ expect($aggregates[6]->bucket)->toBe(946781280);
+ expect($aggregates[6]->period)->toBe(1440);
expect($aggregates[6]->type)->toBe('slow_request');
- expect($aggregates[6]->aggregate)->toBe('count');
+ expect($aggregates[6]->aggregate)->toBe('avg');
expect($aggregates[6]->key)->toBe(json_encode(['POST', '/test-route', 'via /livewire/update']));
expect($aggregates[6]->key_hash)->toBe(keyHash(json_encode(['POST', '/test-route', 'via /livewire/update'])));
- expect($aggregates[6]->value)->toEqual(1);
+ expect($aggregates[6]->value)->toEqual(4000);
+ expect($aggregates[6]->count)->toEqual(1);
- expect($aggregates[7]->bucket)->toBe(946774080);
- expect($aggregates[7]->period)->toBe(10080);
+ expect($aggregates[7]->bucket)->toBe(946781280);
+ expect($aggregates[7]->period)->toBe(1440);
expect($aggregates[7]->type)->toBe('slow_request');
- expect($aggregates[7]->aggregate)->toBe('max');
+ expect($aggregates[7]->aggregate)->toBe('count');
expect($aggregates[7]->key)->toBe(json_encode(['POST', '/test-route', 'via /livewire/update']));
expect($aggregates[7]->key_hash)->toBe(keyHash(json_encode(['POST', '/test-route', 'via /livewire/update'])));
- expect($aggregates[7]->value)->toEqual(4000);
+ expect($aggregates[7]->value)->toEqual(1);
+
+ expect($aggregates[8]->bucket)->toBe(946781280);
+ expect($aggregates[8]->period)->toBe(1440);
+ expect($aggregates[8]->type)->toBe('slow_request');
+ expect($aggregates[8]->aggregate)->toBe('max');
+ expect($aggregates[8]->key)->toBe(json_encode(['POST', '/test-route', 'via /livewire/update']));
+ expect($aggregates[8]->key_hash)->toBe(keyHash(json_encode(['POST', '/test-route', 'via /livewire/update'])));
+ expect($aggregates[8]->value)->toEqual(4000);
+
+ expect($aggregates[9]->bucket)->toBe(946774080);
+ expect($aggregates[9]->period)->toBe(10080);
+ expect($aggregates[9]->type)->toBe('slow_request');
+ expect($aggregates[9]->aggregate)->toBe('avg');
+ expect($aggregates[9]->key)->toBe(json_encode(['POST', '/test-route', 'via /livewire/update']));
+ expect($aggregates[9]->key_hash)->toBe(keyHash(json_encode(['POST', '/test-route', 'via /livewire/update'])));
+ expect($aggregates[9]->value)->toEqual(4000);
+ expect($aggregates[9]->count)->toEqual(1);
+
+ expect($aggregates[10]->bucket)->toBe(946774080);
+ expect($aggregates[10]->period)->toBe(10080);
+ expect($aggregates[10]->type)->toBe('slow_request');
+ expect($aggregates[10]->aggregate)->toBe('count');
+ expect($aggregates[10]->key)->toBe(json_encode(['POST', '/test-route', 'via /livewire/update']));
+ expect($aggregates[10]->key_hash)->toBe(keyHash(json_encode(['POST', '/test-route', 'via /livewire/update'])));
+ expect($aggregates[10]->value)->toEqual(1);
+
+ expect($aggregates[11]->bucket)->toBe(946774080);
+ expect($aggregates[11]->period)->toBe(10080);
+ expect($aggregates[11]->type)->toBe('slow_request');
+ expect($aggregates[11]->aggregate)->toBe('max');
+ expect($aggregates[11]->key)->toBe(json_encode(['POST', '/test-route', 'via /livewire/update']));
+ expect($aggregates[11]->key_hash)->toBe(keyHash(json_encode(['POST', '/test-route', 'via /livewire/update'])));
+ expect($aggregates[11]->value)->toEqual(4000);
Pulse::ignore(fn () => expect(DB::table('pulse_values')->count())->toBe(0));
});
@@ -414,7 +505,7 @@
expect($entries[0]->key)->toBe(json_encode(['GET', '{account}.example.com/users', 'Closure']));
expect($entries[1]->key)->toBe(json_encode(['GET', '/users', 'Closure']));
- Pulse::ignore(fn () => expect(DB::table('pulse_aggregates')->count())->toBe(16));
+ Pulse::ignore(fn () => expect(DB::table('pulse_aggregates')->count())->toBe(24));
Pulse::ignore(fn () => expect(DB::table('pulse_values')->count())->toBe(0));
});
@@ -484,7 +575,7 @@
get('test-route');
Pulse::ignore(fn () => expect(DB::table('pulse_entries')->count())->toBe(10));
- Pulse::ignore(fn () => expect(DB::table('pulse_aggregates')->count())->toBe(8));
+ Pulse::ignore(fn () => expect(DB::table('pulse_aggregates')->count())->toBe(12));
Pulse::ignore(fn () => expect(DB::table('pulse_values')->count())->toBe(0));
});
diff --git a/tests/Feature/Recorders/UserRequestsTest.php b/tests/Feature/Recorders/UserRequestsTest.php
index 3e4a70e7..1f0febfc 100644
--- a/tests/Feature/Recorders/UserRequestsTest.php
+++ b/tests/Feature/Recorders/UserRequestsTest.php
@@ -21,7 +21,7 @@
actingAs(User::make(['id' => '567']))->get('users');
- $entries = Pulse::ignore(fn () => DB::table('pulse_entries')->get());
+ $entries = Pulse::ignore(fn () => DB::table('pulse_entries')->where('type', 'user_request')->get());
expect($entries)->toHaveCount(1);
expect($entries[0])->toHaveProperties([
'timestamp' => 946782245,
@@ -29,7 +29,7 @@
'key' => '567',
'value' => null,
]);
- $aggregates = Pulse::ignore(fn () => DB::table('pulse_aggregates')->orderBy('period')->get());
+ $aggregates = Pulse::ignore(fn () => DB::table('pulse_aggregates')->where('type', 'user_request')->orderBy('period')->get());
expect($aggregates)->toHaveCount(4);
expect($aggregates)->toContainAggregateForAllPeriods(
type: 'user_request',
@@ -44,7 +44,7 @@
get('users');
- $entries = Pulse::ignore(fn () => DB::table('pulse_entries')->get());
+ $entries = Pulse::ignore(fn () => DB::table('pulse_entries')->where('type', 'user_request')->get());
expect($entries)->toHaveCount(0);
});
@@ -53,7 +53,7 @@
post('login');
- $entries = Pulse::ignore(fn () => DB::table('pulse_entries')->get());
+ $entries = Pulse::ignore(fn () => DB::table('pulse_entries')->where('type', 'user_request')->get());
expect($entries)->toHaveCount(1);
expect($entries[0]->key)->toBe('567');
});
@@ -63,7 +63,7 @@
actingAs(User::make(['id' => '567']))->post('logout');
- $entries = Pulse::ignore(fn () => DB::table('pulse_entries')->get());
+ $entries = Pulse::ignore(fn () => DB::table('pulse_entries')->where('type', 'user_request')->get());
expect($entries)->toHaveCount(1);
expect($entries[0]->key)->toBe('567');
});
@@ -94,7 +94,7 @@ public function user()
get('users');
- $entries = Pulse::ignore(fn () => DB::table('pulse_entries')->get());
+ $entries = Pulse::ignore(fn () => DB::table('pulse_entries')->where('type', 'user_request')->get());
expect($entries)->toHaveCount(0);
});
@@ -106,7 +106,7 @@ public function user()
actingAs(User::make(['id' => '567']))->get('users');
- expect(Pulse::ignore(fn () => DB::table('pulse_entries')->count()))->toBe(0);
+ expect(Pulse::ignore(fn () => DB::table('pulse_entries')->where('type', 'user_request')->count()))->toBe(0);
});
it('ignores livewire update requests from an ignored path', function () {
@@ -129,7 +129,7 @@ public function user()
],
]);
- expect(Pulse::ignore(fn () => DB::table('pulse_entries')->count()))->toBe(0);
+ expect(Pulse::ignore(fn () => DB::table('pulse_entries')->where('type', 'user_request')->count()))->toBe(0);
});
it('can sample', function () {
@@ -148,7 +148,7 @@ public function user()
get('users');
get('users');
- expect(Pulse::ignore(fn () => DB::table('pulse_entries')->count()))->toEqualWithDelta(1, 4);
+ expect(Pulse::ignore(fn () => DB::table('pulse_entries')->where('type', 'user_request')->count()))->toEqualWithDelta(1, 4);
});
it('can sample at zero', function () {
@@ -167,7 +167,7 @@ public function user()
get('users');
get('users');
- expect(Pulse::ignore(fn () => DB::table('pulse_entries')->count()))->toBe(0);
+ expect(Pulse::ignore(fn () => DB::table('pulse_entries')->where('type', 'user_request')->count()))->toBe(0);
});
it('can sample at one', function () {
@@ -186,5 +186,5 @@ public function user()
get('users');
get('users');
- expect(Pulse::ignore(fn () => DB::table('pulse_entries')->count()))->toBe(10);
+ expect(Pulse::ignore(fn () => DB::table('pulse_entries')->where('type', 'user_request')->count()))->toBe(10);
});
diff --git a/tests/Feature/Storage/DatabaseStorageTest.php b/tests/Feature/Storage/DatabaseStorageTest.php
index 99644930..05942e7a 100644
--- a/tests/Feature/Storage/DatabaseStorageTest.php
+++ b/tests/Feature/Storage/DatabaseStorageTest.php
@@ -328,8 +328,8 @@
$results = Pulse::aggregate('slow_request', ['min', 'max', 'sum', 'avg', 'count'], CarbonInterval::hour());
expect($results->all())->toEqual([
- (object) ['key' => 'GET /bar', 'min' => 200, 'max' => 600, 'sum' => 2400, 'avg' => 400, 'count' => 6],
- (object) ['key' => 'GET /foo', 'min' => 100, 'max' => 400, 'sum' => 2000, 'avg' => 250, 'count' => 8],
+ (object) ['key' => 'GET /bar', 'min' => 200, 'max' => 600, 'sum' => 2400, 'avg' => 400, 'count' => 6, 'avg_count' => 6],
+ (object) ['key' => 'GET /foo', 'min' => 100, 'max' => 400, 'sum' => 2000, 'avg' => 250, 'count' => 8, 'avg_count' => 8],
]);
});