To achieve multiple aggregations from a single recorder in Laravel Pulse, you can record the data once and then use different groupings to aggregate the data as needed. This approach will help you avoid recording redundant data and keep your implementation efficient.
Here's a solution that demonstrates how to record the data once and then perform different aggregations:
- Single Recorder Implementation: Record the data once with all necessary information.
// UnifiedRecorder.php
$this->pulse->record(
type: 'request',
key: json_encode([
'method' => $request->method(),
'domain' => $domain,
'path' => $domainAndPath,
'api_path' => $apiPath,
'via' => $via
], flags: JSON_THROW_ON_ERROR),
value: $duration,
timestamp: $startedAt,
)->count();
- Aggregation Logic: Use different groupings to aggregate the data based on your requirements.
use Illuminate\Support\Facades\DB;
// Most requested paths
$mostRequestedPaths = DB::table('pulse_records')
->select(DB::raw('JSON_UNQUOTE(JSON_EXTRACT(key, "$.path")) as path'), DB::raw('count(*) as count'))
->groupBy('path')
->orderBy('count', 'desc')
->get();
// Most requested domains
$mostRequestedDomains = DB::table('pulse_records')
->select(DB::raw('JSON_UNQUOTE(JSON_EXTRACT(key, "$.domain")) as domain'), DB::raw('count(*) as count'))
->groupBy('domain')
->orderBy('count', 'desc')
->get();
// Most requested API endpoints
$mostRequestedApiPaths = DB::table('pulse_records')
->select(DB::raw('JSON_UNQUOTE(JSON_EXTRACT(key, "$.api_path")) as api_path'), DB::raw('count(*) as count'))
->groupBy('api_path')
->orderBy('count', 'desc')
->get();
- Presentation: Display the aggregated data on separate cards for maximum visibility.
// In your Blade template or frontend code
@foreach ($mostRequestedPaths as $path)
<div class="card">
<h3>Path: {{ $path->path }}</h3>
<p>Requests: {{ $path->count }}</p>
</div>
@endforeach
@foreach ($mostRequestedDomains as $domain)
<div class="card">
<h3>Domain: {{ $domain->domain }}</h3>
<p>Requests: {{ $domain->count }}</p>
</div>
@endforeach
@foreach ($mostRequestedApiPaths as $apiPath)
<div class="card">
<h3>API Path: {{ $apiPath->api_path }}</h3>
<p>Requests: {{ $apiPath->count }}</p>
</div>
@endforeach
By recording the data once and then using different groupings for aggregation, you can efficiently achieve the desired results without duplicating the recorded data. This approach also makes it easier to add more slices in the future without significantly increasing the amount of recorded data per request.