A self-hosted, GDPR-compliant server-side analytics package for Laravel with multi-tenancy support. Track page views, events, conversions, and performance metrics without relying on third-party services.
- Server-side tracking - No client-side JavaScript required
- GDPR compliant - IP anonymization, no cookies, full data control
- Multi-tenancy support - Built-in support for multi-tenant applications
- Performance monitoring - Track response times, memory usage, and query counts
- Queue support - Async processing with Redis/Horizon
- Data aggregation - Hourly, daily, weekly, and monthly summaries
- RESTful API - Headless API for custom dashboards
- Automatic tracking - Middleware for hands-free analytics
- Privacy-focused - No external dependencies or data sharing
- PHP 8.1 or higher
- Laravel 10.x or 11.x
- MySQL 5.7+ or 8.0+
- Redis (optional, recommended for queue processing)
Install the package via Composer:
composer require orimyth/laravel-analyticsPublish the configuration file:
php artisan vendor:publish --tag=insight-configRun the migrations:
php artisan migrateThe configuration file is published to config/insight.php. Key options include:
return [
// Enable/disable tracking
'enabled' => env('INSIGHT_ENABLED', true),
// Automatic request tracking
'auto_track_requests' => env('INSIGHT_AUTO_TRACK_REQUESTS', true),
// Performance tracking
'auto_track_performance' => env('INSIGHT_AUTO_TRACK_PERFORMANCE', false),
// Queue configuration
'queue_connection' => env('INSIGHT_QUEUE_CONNECTION', 'redis'),
'queue_name' => env('INSIGHT_QUEUE_NAME', 'insight'),
// GDPR compliance
'anonymize_ip' => env('INSIGHT_ANONYMIZE_IP', true),
'track_user' => env('INSIGHT_TRACK_USER', true),
'track_anonymous' => env('INSIGHT_TRACK_ANONYMOUS', true),
// Multi-tenancy
'multi_tenancy' => [
'enabled' => env('INSIGHT_MULTI_TENANCY', false),
'tenant_resolver' => function () {
return tenant('id'); // Compatible with stancl/tenancy
},
],
// Data retention
'retention_days' => env('INSIGHT_RETENTION_DAYS', 90),
// Exclude routes, IPs, and user agents
'excluded_routes' => ['horizon*', 'telescope*'],
'excluded_ips' => [],
'excluded_user_agents' => ['*bot*', '*crawler*'],
];By default, Laravel Analytics automatically tracks all web requests. No additional code is required.
Track custom events using the Insight facade:
use Orimyth\LaravelAnalytics\Facades\Analytics;
// Track a page view
Analytics::pageView('/custom-page', ['metadata' => 'value']);
// Track a conversion
Analytics::conversion('signup', 100, ['plan' => 'premium']);
// Track a click
Analytics::click('cta-button', ['campaign' => 'summer-sale']);
// Track an API request
Analytics::apiRequest('/api/users');
// Track a custom event
Analytics::track('video_play', [
'video_id' => 123,
'duration' => 45,
]);You can manually apply middleware to specific routes:
// Track page views only
Route::get('/dashboard', [DashboardController::class, 'index'])
->middleware('insight.pageview');
// Track performance metrics
Route::get('/reports', [ReportController::class, 'index'])
->middleware('insight.performance');
// Track both
Route::middleware(['insight.pageview', 'insight.performance'])
->group(function () {
Route::get('/analytics', [AnalyticsController::class, 'index']);
});Laravel Analytics provides a RESTful API for querying analytics data:
GET /api/insight/eventsQuery parameters:
start_date- Filter by start date (YYYY-MM-DD)end_date- Filter by end date (YYYY-MM-DD)event_type- Filter by event type (page_view, click, conversion, etc.)tenant_id- Filter by tenant IDuser_id- Filter by user IDpath- Filter by path (supports wildcards)per_page- Results per page (max 100)sort_by- Sort field (default: created_at)sort_order- Sort order (asc/desc)
GET /api/insight/summary?start_date=2024-01-01&end_date=2024-01-31Returns:
{
"total_events": 1234,
"unique_sessions": 456,
"unique_users": 123,
"page_views": 890,
"conversions": 45,
"clicks": 234,
"api_requests": 567,
"performance": {
"avg_response_time_ms": 123.45,
"max_response_time_ms": 567.89,
"avg_memory_mb": 45.67,
"avg_query_count": 12.34
}
}GET /api/insight/metricsSame query parameters as events endpoint.
GET /api/insight/trends?dimension=event_type&aggregate_type=dailyQuery parameters:
dimension- Dimension to group by (event_type, path, browser, platform, device_type)aggregate_type- Aggregation level (hourly, daily, weekly, monthly)start_date- Start dateend_date- End datetenant_id- Filter by tenant
GET /api/insight/top-pages?limit=10GET /api/insight/top-referrers?limit=10GET /api/insight/browsers
GET /api/insight/platforms
GET /api/insight/devicesAggregate raw events into summary statistics:
# Daily aggregation (default)
php artisan insight:aggregate
# Hourly aggregation
php artisan insight:aggregate --type=hourly
# Specific date
php artisan insight:aggregate --date=2024-01-15
# Specific tenant
php artisan insight:aggregate --tenant=tenant-123Schedule aggregations in app/Console/Kernel.php:
$schedule->command('insight:aggregate --type=hourly')->hourly();
$schedule->command('insight:aggregate --type=daily')->daily();Remove old analytics data based on retention policy:
# Clean up based on config retention_days
php artisan insight:cleanup
# Custom retention period
php artisan insight:cleanup --days=30
# Preview without deleting
php artisan insight:cleanup --dry-runSchedule cleanup:
$schedule->command('insight:cleanup')->weekly();Optimize database tables for better performance:
php artisan insight:optimizeLaravel Analytics is compatible with stancl/tenancy:
// config/insight.php
'multi_tenancy' => [
'enabled' => true,
'tenant_resolver' => function () {
return tenant('id');
},
],All events and metrics will automatically include the tenant context.
For optimal performance, configure Redis as your queue connection:
INSIGHT_QUEUE_CONNECTION=redis
INSIGHT_QUEUE_NAME=insightProcess the queue with Laravel Horizon or a queue worker:
php artisan queue:work redis --queue=insightLaravel Analytics is designed with privacy in mind:
- IP Anonymization: Last octet of IPv4 and last 80 bits of IPv6 are removed by default
- No Cookies: Server-side tracking doesn't require cookies
- Data Ownership: All data is stored in your own database
- User Control: Users can be excluded from tracking
- Data Retention: Automatic cleanup of old data
To exclude specific users from tracking:
// In a middleware or service provider
if (auth()->user()?->opted_out_of_analytics) {
config(['insight.enabled' => false]);
}- Enable queue processing for production environments
- Run aggregations regularly to improve query performance
- Use the aggregates table for dashboard queries
- Consider partitioning tables for large datasets
- Run
insight:optimizeperiodically
composer testIf you discover any security-related issues, please email security@orimyth.com instead of using the issue tracker.
The MIT License (MIT). Please see License File for more information.
Future features under consideration:
- Real-time tracking via WebSocket
- AI-based anomaly detection
- Custom dashboard UI (Filament/Livewire)
- Export functionality (CSV, JSON)
- Integration with Laravel Pulse
- Geographic visualization
- A/B testing support
- Funnel analysis
- User journey tracking
For support, please open an issue on GitHub.