me-shaon/laravel-request-analytics
Privacy-first web analytics for Laravel: track real-time page views, visitors, bounce rate, sessions, and performance in a built-in dashboard. Includes bot filtering, geo/device insights, data retention controls, IP anonymization, and a REST API—no third-party sharing.
Installation:
composer require me-shaon/laravel-request-analytics
php artisan request-analytics:install
The installer handles migrations, config, and assets automatically.
First Use Case:
/analytics (or your configured path).Where to Look First:
/analytics for immediate insights.config/request-analytics.php to tweak tracking behavior (e.g., ignore paths, geolocation providers).request-analytics.access is in your web/api middleware groups for protected access.Tracking Requests:
use MeShaon\RequestAnalytics\Facades\RequestAnalytics;
RequestAnalytics::track($request, $customData = []);
Queue-Based Processing:
config/request-analytics.php:
'queue' => [
'enabled' => true,
'on_queue' => 'analytics',
],
RequestAnalytics::dispatchTrackJob($request, $customData);
Data Filtering:
ignore-paths:
'ignore-paths' => [
'admin/*',
'api/health',
],
'skip_ips' => ['192.168.1.0/24', '10.0.0.1'],
Geolocation Integration:
'geolocation' => [
'provider' => 'maxmind',
'maxmind' => [
'license_key' => env('MAXMIND_LICENSE_KEY'),
],
],
$visitors = RequestAnalytics::getVisitorsByCountry();
API Access:
// Get top pages
$topPages = RequestAnalytics::getTopPages(7);
// Get visitor metrics
$metrics = RequestAnalytics::getMetrics();
CanAccessAnalyticsDashboard interface to gate dashboard access:
class User implements CanAccessAnalyticsDashboard {
public function canAccessAnalyticsDashboard(): bool {
return $this->isAdmin();
}
}
use MeShaon\RequestAnalytics\Models\RequestAnalytics;
$reports = RequestAnalytics::query()
->where('created_at', '>=', now()->subDays(7))
->with('user') // If tracking users
->get();
RequestAnalytics::tracked(function ($request, $data) {
// Log custom events
});
Performance Overhead:
'queue.enabled' => true) and monitor queue workers:
php artisan queue:work --queue=analytics
Geolocation Rate Limits:
Middleware Conflicts:
request-analytics.access may conflict with other middleware (e.g., auth).app/Http/Kernel.php:
'web' => [
\App\Http\Middleware\EncryptCookies::class,
\Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
\Illuminate\Session\Middleware\StartSession::class,
// ... other middleware ...
\MeShaon\RequestAnalytics\Http\Middleware\AccessMiddleware::class, // Move to end
],
IP Anonymization:
anonymize_ip: true) may break geo reports.'privacy' => ['anonymize_ip' => false],
Pruning Side Effects:
pruning.days: 30) may delete needed data.php artisan model:prune --model="MeShaon\RequestAnalytics\Models\RequestAnalytics" --dry-run
request_analytics table:
php artisan tinker
>>> \MeShaon\RequestAnalytics\Models\RequestAnalytics::latest()->take(5)->get();
'middleware' => [
'web' => [\Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class],
],
php artisan queue:failed-table
php artisan queue:retry all
Custom Metrics:
RequestAnalytics model to add fields:
// app/Models/ExtendedRequestAnalytics.php
use MeShaon\RequestAnalytics\Models\RequestAnalytics as BaseModel;
class ExtendedRequestAnalytics extends BaseModel {
protected $casts = [
'custom_metric' => 'integer',
];
}
Custom Reports:
namespace App\Services;
use MeShaon\RequestAnalytics\Models\RequestAnalytics;
class CustomReport {
public function getUserJourney($userId) {
return RequestAnalytics::where('user_id', $userId)
->orderBy('created_at')
->get();
}
}
Override Views:
php artisan vendor:publish --tag="request-analytics-views"
resources/views/vendor/request-analytics/.Bot Detection:
skip_referrers list or creating a custom middleware:
namespace App\Http\Middleware;
use Closure;
use MeShaon\RequestAnalytics\Facades\RequestAnalytics;
class CustomBotFilter {
public function handle($request, Closure $next) {
if (RequestAnalytics::isBot($request)) {
return response('Blocked', 403);
}
return $next($request);
}
}
'skip_ips' => ['127.0.0.1', '::1'],
'capture' => [
'web' => env('APP_ENV') !== 'staging',
'api' => env('APP_ENV') !== 'staging',
],
cookie-consent package for GDPR compliance:
// Only track if consent is given
if (session('cookie_consent')) {
RequestAnalytics::track($request);
}
How can I help you explore Laravel packages today?