aboleon / laravel-analytics
Fork of the Laravel Visitor Tracker of antonioribeiro/tracker, updated for Laravel 11+
Requires
- php: ^8.3
- illuminate/cache: ^11.0|^12.0|^13.0
- illuminate/config: ^11.0|^12.0|^13.0
- illuminate/console: ^11.0|^12.0|^13.0
- illuminate/contracts: ^11.0|^12.0|^13.0
- illuminate/cookie: ^11.0|^12.0|^13.0
- illuminate/database: ^11.0|^12.0|^13.0
- illuminate/events: ^11.0|^12.0|^13.0
- illuminate/filesystem: ^11.0|^12.0|^13.0
- illuminate/http: ^11.0|^12.0|^13.0
- illuminate/log: ^11.0|^12.0|^13.0
- illuminate/routing: ^11.0|^12.0|^13.0
- illuminate/session: ^11.0|^12.0|^13.0
- illuminate/support: ^11.0|^12.0|^13.0
- illuminate/translation: ^11.0|^12.0|^13.0
- illuminate/view: ^11.0|^12.0|^13.0
- jaybizzle/crawler-detect: ^1.3
- jenssegers/agent: ^2.6
- psr/log: ^1.1|^2.0|^3.0
- ramsey/uuid: ^3 || ^4
- ua-parser/uap-php: ^3.10
- yajra/laravel-datatables-oracle: ^11.0|^12.0|^13.0
Requires (Dev)
- laravel/pint: ^1.14
- mockery/mockery: ^1.6
- orchestra/testbench: ^9.0|^10.0|^11.0
- phpunit/phpunit: ^11.0|^12.0
Suggests
- geoip/geoip: ~1.14
- geoip2/geoip2: ^2.0|^3.0
This package is auto-updated.
Last update: 2026-05-18 14:53:31 UTC
README
This package is an updated fork of antonioribeiro/tracker, maintained as aboleon/laravel-analytics for current Laravel applications.
Laravel Analytics records request, session, route, user, device, referer, exception, event, and SQL query metadata in normalized tracker_* database tables. Tracking is disabled by default so applications can opt in to only the data they need.
Requirements
- PHP 8.3 or newer
- Laravel or Illuminate components 11, 12, or 13
- A configured Laravel database connection
- Optional:
geoip2/geoip2plus a local MaxMind-compatible MMDB database when GeoIP logging is enabled
Installation
Install the package with Composer:
composer require aboleon/laravel-analytics
The service provider and Tracker facade are registered through Laravel package discovery. If package discovery is disabled, register the provider manually:
Aboleon\Analytics\Vendor\Laravel\ServiceProvider::class,
Publish the configuration file:
php artisan vendor:publish --tag=tracker-config
The package loads its migrations automatically. Publish them only when you need to customize the migration files:
php artisan vendor:publish --tag=tracker-migrations
Run the migrations after confirming your application database connection:
php artisan migrate
Configuration
The published configuration file is config/tracker.php.
Enable the package and request logging:
'enabled' => true, 'log_enabled' => true,
By default, the package stores analytics tables on Laravel's default database connection:
'connection' => null,
Set tracker.connection only when the analytics tables should use a specific named connection.
Dedicated connection for SQL query logging
Most applications do not need a dedicated analytics connection. One is useful when SQL query logging is enabled and you want to log queries from the default application connection without also logging the package's own writes.
Add a second connection to config/database.php that points to the same database as your application connection, but uses a different name. For example, copy your mysql connection settings to a new tracker connection, then configure the package like this:
'connection' => 'tracker', 'log_sql_queries' => true, 'do_not_log_sql_queries_connections' => [ 'tracker', ],
The separate connection name is what matters. It lets Laravel Analytics write to the same database while excluding only the package's own SQL writes. If you keep connection as null and add your default connection name, such as mysql, to do_not_log_sql_queries_connections, SQL query logging for that application connection will also be skipped.
Enable only the data categories your application needs:
'log_user_agents' => true, 'log_users' => true, 'log_devices' => true, 'log_languages' => true, 'log_referers' => true, 'log_paths' => true, 'log_queries' => true, 'log_routes' => true, 'log_exceptions' => true, 'log_events' => false, 'log_geoip' => false,
Crawler and bot user agents are excluded by default through jaybizzle/crawler-detect:
'do_not_track_robots' => true,
Set this to false only when you intentionally want crawler sessions in the tracker tables.
Tracking can be limited by environment, route name, path, IP range, and robot detection:
'do_not_track_environments' => ['local', 'testing'], 'do_not_track_routes' => ['tracker.stats.*'], 'do_not_track_paths' => ['api/*'], 'do_not_track_ips' => ['127.0.0.0/24'], 'do_not_track_robots' => true,
Middleware
By default, the package boots through middleware on the web group so Laravel's PHP session is available before tracking runs. This keeps one visitor session row and accumulates page views on that row:
'use_middleware' => true,
With this setting, the package automatically pushes its tracking middleware to the web group. If you disable middleware mode, tracking boots during the service provider lifecycle; that mode is only useful when you do not need Laravel session-based visitor grouping.
User Tracking
Set tracker.user_model to the Eloquent model that represents users in your application:
'user_model' => App\Models\User::class,
For applications with multiple guards or authentication bindings, configure the authentication options:
'authentication_ioc_binding' => ['auth'], 'authentication_guards' => ['web', 'admin'], 'authenticated_check_method' => 'check', 'authenticated_user_method' => 'user', 'authenticated_user_id_column' => 'id', 'authenticated_user_username_column' => 'email',
GeoIP
GeoIP logging is optional. Install the official MaxMind reader package when you need it:
composer require geoip2/geoip2
The package reads MaxMind binary databases in MMDB format. Store the database under storage/app/geoip, not under config/, because the database is runtime data and can be large:
'geoip_database_path' => storage_path('app/geoip'), 'log_geoip' => true,
Automatic GeoIP database downloads are not bundled. The tracker:updategeoip command reports the configured path so deployments can manage the database file explicitly.
Create the directory during deployment and place one of these files in it:
storage/app/geoip/GeoLite2-City.mmdb
storage/app/geoip/GeoIP2-City.mmdb
storage/app/geoip/GeoLite2-Country.mmdb
storage/app/geoip/GeoIP2-Country.mmdb
City databases are preferred and provide country, region/subdivision, city, postal code, latitude, longitude, metro code, and continent data when MaxMind has those values. Country databases only provide country and continent data; city, region, postal code, and coordinates will remain empty.
The actual .mmdb file should normally stay out of git.
Stats Panel
The package includes optional stats routes and views. Enable them with:
'stats_panel_enabled' => true, 'stats_routes_middleware' => ['web', 'auth'], 'stats_base_uri' => 'stats', 'stats_layout' => 'aboleon/analytics::layout',
The routes are registered under tracker.stats.* and are excluded from tracking by default.
The stats controller requires an authenticated admin user. Set tracker.user_model to your application user model, then expose one of these boolean attributes or methods on the authenticated user:
adminrootis_adminis_rootisAdmin()isRoot()
Use the same user model class that your Laravel auth provider uses. In current Laravel applications this is usually App\Models\User::class; in older applications it may be App\User::class.
For a typical current Laravel app:
'user_model' => App\Models\User::class, 'authenticated_user_id_column' => 'id', 'authenticated_user_username_column' => 'email',
For an older app whose config/auth.php provider uses App\User::class, configure the tracker the same way:
'user_model' => App\User::class,
Then add an admin flag or method to that authenticated user model:
class User extends Authenticatable { public function isAdmin(): bool { return (bool) $this->is_admin; } }
If the stats page displays tracker::tracker.miss_admin_prop or "User model misses admin property", the current authenticated user does not expose any of the supported admin attributes or methods above. If it displays "You are not Admin", the attribute or method exists but returns a falsy value.
The bundled views are registered under the aboleon/analytics view namespace. The default stats panel loads Bootstrap 5, Bootstrap Icons, DataTables, jQuery, and Chart.js from public CDNs, so there is no required local stats asset directory to publish.
Customizing stats views
Publish the stats views when you need to customize the panel markup:
php artisan vendor:publish --tag=tracker-views
This copies the package views to:
resources/views/vendor/aboleon/analytics
Laravel automatically loads those project views before the package defaults, so no extra configuration is needed after publishing. Edit the copied Blade files directly.
If you already published the old fork's views under resources/views/vendor/pragmarx/tracker, move your customizations to resources/views/vendor/aboleon/analytics; the pragmarx/tracker namespace is no longer used.
The legacy tracker.stats_template_path option is retained only for older customized views that still reference $stats_template_path. The bundled package views no longer use it.
To refresh the published views from the package, run the publish command with --force, but only after backing up your custom changes:
php artisan vendor:publish --tag=tracker-views --force
Runtime API
Use the facade or resolve the service from the container:
$current = Tracker::currentSession(); $sessions = Tracker::sessions(60 * 24); $online = Tracker::onlineUsers(); $users = Tracker::users(60 * 24); $devices = Tracker::userDevices(60 * 24, $userId); $events = Tracker::events(60 * 24); $errors = Tracker::errors(60 * 24); $pageViews = Tracker::pageViews(60 * 24 * 30); $pageViewsByCountry = Tracker::pageViewsByCountry(60 * 24);
Track custom events:
Tracker::trackEvent([ 'event' => 'cart.add', 'object' => App\Events\CartItemAdded::class, ]);
Track a custom route or virtual visit:
Tracker::trackVisit( [ 'name' => 'reports.export', 'action' => App\Http\Controllers\ReportExportController::class.'@store', ], [ 'path' => 'reports/export', ] );
Query visits for a route:
$count = Tracker::logByRouteName('orders.show') ->where('parameter', 'id') ->where('value', $order->getKey()) ->count();
Stored Data
Depending on configuration, the package can store:
- sessions and page views
- authenticated user identifiers
- devices, user agents, operating systems, and robot detection
- request paths, query strings, route names, route parameters, and HTTP metadata
- referers and parsed referer search terms
- language preferences
- GeoIP location data
- exceptions and errors
- application events
- SQL statements, timings, bindings, and connection names
- optional visitor cookies for device continuity
All package tables use the tracker_ prefix.
Testing
Run the package checks with:
composer validate --strict vendor/bin/phpunit
Changelog
See changelog.md.
License
Laravel Analytics is open-sourced software licensed under the MIT license.