nafiur / laravel-web-analytics
High-performance Web Traffic & Visitor Analytics Dashboard for Laravel with real-time SSE live streaming
Requires
- php: ^8.1 || ^8.2 || ^8.3 || ^8.4
- illuminate/database: ^9.0 || ^10.0 || ^11.0 || ^12.0 || ^13.0
- illuminate/http: ^9.0 || ^10.0 || ^11.0 || ^12.0 || ^13.0
- illuminate/routing: ^9.0 || ^10.0 || ^11.0 || ^12.0 || ^13.0
- illuminate/support: ^9.0 || ^10.0 || ^11.0 || ^12.0 || ^13.0
Requires (Dev)
None
Suggests
None
Provides
None
Conflicts
None
Replaces
None
README
A modern, fast, and self-hosted Web Traffic & Visitor Analytics Dashboard for Laravel with real-time Server-Sent Events (SSE) live streaming and Tailwind CSS styling.
โก Highlights & Key Features
- ๐ Real-Time Live Stream (SSE): Live active visitor count and instant real-time traffic feed without WebSockets, Node.js, or Pusher.
- ๐จ Tailwind CSS UI with Dark Mode: Modern, responsive dashboard powered by Tailwind CSS Play CDN (zero build step / zero npm dependencies). Includes a 1-click persistent Dark/Light mode toggle.
- ๐ Comprehensive Metrics: Total Requests, Unique Visitors, Bandwidth (Data Transferred), Avg Response Time, Error Rate.
- ๐ GeoIP & Location Provider: Automatic country/city resolution with fallback support for Cloudflare headers and
ip-api. - ๐จ Instant Error Alerts: Automatic Telegram, Slack, or Discord webhook alerts when 5xx server errors or traffic spikes occur.
- ๐ฅ Export to CSV: Download filtered analytics logs into structured CSV format via high-performance chunked streams.
- ๐งน Automatic Log Pruning: Includes an Artisan command (
php artisan lwa:prune) to maintain a clean database and prevent disk bloat. - โก Zero Latency Impact: Non-blocking telemetry tracking using Laravel's
terminate()hook, recording traffic after the HTTP response has been sent to the user. - ๐๏ธ Lightweight & Decoupled Storage: Stores telemetry in the
lwa_logstable without coupling to any specific User model, with GDPR-compliant IP anonymization options.
๐ Requirements
- PHP
^8.1 | ^8.2 | ^8.3 | ^8.4 - Laravel
^9.0 | ^10.0 | ^11.0 | ^12.0 | ^13.0
๐ฆ Installation
Install the package via Composer:
composer require nafiur/laravel-web-analytics
Publish configuration, migration, and views:
php artisan vendor:publish --provider="Nafiur\WebAnalytics\WebAnalyticsServiceProvider"
Or publish selectively:
# Publish configuration php artisan vendor:publish --tag=laravel-web-analytics-config # Publish migrations php artisan vendor:publish --tag=web-analytics-migrations # Publish views (optional, to customize dashboard UI) php artisan vendor:publish --tag=web-analytics-views
Run database migrations to create the lwa_logs table:
php artisan migrate
๐ Setup & Middleware Registration
To start capturing web traffic, register the TrackWebTraffic middleware.
For Laravel 11 and Laravel 12 (bootstrap/app.php):
use Nafiur\WebAnalytics\Http\Middleware\TrackWebTraffic; return Application::configure(basePath: dirname(__DIR__)) ->withRouting( web: __DIR__.'/../routes/web.php', commands: __DIR__.'/../routes/console.php', health: '/up', ) ->withMiddleware(function (Middleware $middleware) { $middleware->web(append: [ TrackWebTraffic::class, ]); }) ->create();
For Laravel 9 and Laravel 10 (app/Http/Kernel.php):
Add the middleware to the $middlewareGroups['web'] array:
protected $middlewareGroups = [ 'web' => [ // ... other middlewares \Nafiur\WebAnalytics\Http\Middleware\TrackWebTraffic::class, ], ];
๐ฅ๏ธ Accessing the Dashboard
Navigate to:
https://your-domain.com/web-analytics
By default, the dashboard is protected by the ['web', 'auth'] middleware stack. You can adjust the route prefix and authorization rules in config/laravel-web-analytics.php.
Route Names
The package defines routes with the lwa_ prefix to avoid conflicts with your application routes:
| Route | Name | Description |
|---|---|---|
GET /web-analytics |
lwa_dashboard |
Main analytics dashboard (alias: lwa_index) |
GET /web-analytics/data |
lwa_data |
AJAX endpoint for real-time data |
GET /web-analytics/stream |
lwa_stream |
SSE stream for live traffic |
GET /web-analytics/export |
lwa_export |
Export analytics to CSV |
Generate URLs in your Blade templates or code:
route('lwa_dashboard', ['range' => '24h']); route('lwa_data', ['range' => '24h']); route('lwa_stream'); route('lwa_export', ['range' => '24h']);
โ๏ธ Configuration (config/laravel-web-analytics.php)
return [ /* * Enable or disable traffic tracking globally */ 'enabled' => env('WEB_ANALYTICS_ENABLED', true), /* * Database table name for storing web analytics logs */ 'table_name' => env('WEB_ANALYTICS_TABLE_NAME', 'lwa_logs'), /* * Route configurations for the Analytics Dashboard */ 'route' => [ 'prefix' => env('WEB_ANALYTICS_ROUTE_PREFIX', 'web-analytics'), 'middleware' => ['web', 'auth'], ], /* * Real-time SSE polling interval in seconds */ 'stream_interval' => env('WEB_ANALYTICS_STREAM_INTERVAL', 2), /* * Active visitor calculation window in minutes */ 'active_visitor_window' => env('WEB_ANALYTICS_ACTIVE_WINDOW', 5), /* * Capture Settings (Web & API) */ 'capture' => [ 'web' => true, 'api' => env('WEB_ANALYTICS_CAPTURE_API', true), 'ajax' => true, 'bots' => env('WEB_ANALYTICS_CAPTURE_BOTS', false), ], /* * GeoIP & Location Provider */ 'geoip' => [ 'enabled' => env('WEB_ANALYTICS_GEOIP_ENABLED', true), 'provider' => env('WEB_ANALYTICS_GEOIP_PROVIDER', 'cloudflare'), // 'cloudflare', 'ip-api' 'maxmind_db_path' => env('WEB_ANALYTICS_MAXMIND_DB', storage_path('app/GeoLite2-City.mmdb')), ], /* * Alert Notifications (Spikes & 5xx Server Errors) */ 'alerts' => [ 'enabled' => env('WEB_ANALYTICS_ALERTS_ENABLED', false), 'webhook_url' => env('WEB_ANALYTICS_ALERT_WEBHOOK', null), 'channel' => env('WEB_ANALYTICS_ALERT_CHANNEL', 'telegram'), // 'telegram', 'slack', 'discord' 'telegram_bot_token' => env('WEB_ANALYTICS_TELEGRAM_BOT_TOKEN', null), 'telegram_chat_id' => env('WEB_ANALYTICS_TELEGRAM_CHAT_ID', null), 'error_rate_threshold_percentage' => env('WEB_ANALYTICS_ERROR_THRESHOLD', 10), ], /* * Exclude specific URL paths and file extensions from being tracked */ 'ignored_paths' => [ 'livewire/*', 'broadcasting/auth', 'admin/web-analytics*', '*.css', '*.js', '*.png', '*.jpg', '*.jpeg', '*.gif', '*.svg', '*.webp', '*.woff*', '*.ico', ], /* * IP Anonymization for privacy compliance (GDPR) */ 'anonymize_ip' => env('WEB_ANALYTICS_ANONYMIZE_IP', false), /* * Number of days to retain logs */ 'retention_days' => env('WEB_ANALYTICS_RETENTION_DAYS', 30), ];
๐งน Database Maintenance (Pruning)
To keep your database lean, run the included prune command:
# Prune logs older than configured retention days (default 30) php artisan lwa:prune # Or specify custom days php artisan lwa:prune --days=14
Schedule it in your routes/console.php (Laravel 11+) or app/Console/Kernel.php:
use Illuminate\Support\Facades\Schedule; Schedule::command('lwa:prune')->daily();
๐ฅ Exporting Reports
Click the Export to CSV button on the dashboard or directly access:
GET /web-analytics/export?range=24h
Supported ranges: 1h, 6h, 24h, 7d, 30d.
๐ก๏ธ Security & Authorization
To restrict dashboard access to specific user roles or permissions, update config/laravel-web-analytics.php:
'route' => [ 'prefix' => 'web-analytics', 'middleware' => ['web', 'auth', 'can:view-analytics'], ],
๐ค Contributing
Contributions, issues, and feature requests are welcome! Feel free to check the issues page.
๐ License
This project is licensed under the MIT License - see the LICENSE file for details.
