kianisanaullah / laravel-traffic-sentinel
Traffic Sentinel for Laravel: tracks visitors + bots, online presence, and traffic stats.
Installs: 39
Dependents: 0
Suggesters: 0
Security: 0
Stars: 0
Watchers: 0
Forks: 0
Open Issues: 0
pkg:composer/kianisanaullah/laravel-traffic-sentinel
Requires
- php: ^8.2
- illuminate/database: ^12.0
- illuminate/http: ^12.0
- illuminate/support: ^12.0
README
Traffic Sentinel
π¦ Self-hosted Laravel traffic analytics for humans vs bots, online users, pageviews, referrers, and crawler detection β no Google Analytics, no cookies, no third-party tracking.
π€ Why Traffic Sentinel?
Most Laravel apps either:
- rely on Google Analytics (privacy issues, blocked by ad-blockers), or
- use heavy analytics tools that are hard to self-host.
Traffic Sentinel is different:
- β 100% self-hosted (your DB, your rules)
- π Privacy-first (hashed IPs, optional raw IP, no cookies by default)
- π€ Built to separate real humans vs crawlers
- β‘ Lightweight β no JS frameworks, no trackers, no beacons
- π§© Designed for developers, not marketers
If you want operational visibility instead of marketing analytics, Traffic Sentinel fits perfectly.
π How it compares
| Feature | Traffic Sentinel | Google Analytics | Laravel Telescope |
|---|---|---|---|
| Self-hosted | β Yes | β No | β Yes |
| Privacy-friendly | β Yes | β No | β Yes |
| Bot detection | β Built-in | β οΈ Limited | β No |
| Online users | β Yes | β No | β No |
| Pageviews | β Yes | β Yes | β No |
| Production-safe | β Yes | β Yes | β No |
| External scripts | β None | β Required | β None |
Traffic Sentinel focuses on traffic intelligence, not debugging or marketing.
β¨ Features
- π Privacy-first analytics (hashed IPs, optional raw IP, no cookies by default)
- β Human vs Bot detection (UA keywords + heuristics)
- π Online users (last N minutes)
- π Pageviews (humans / all)
- π Top pages, bots & referrers
- π« Exclude internal paths, hosts, IPs & UAs
- π§ Runtime IP β Country / ASN lookup (no external APIs)
- π§Ή Prune old data (
traffic:prune) - π₯οΈ Modern dashboard (Bootstrap 5)
- β‘ No JS framework dependency
- π Optional runtime IP lookup (Country + Flag + ASN) using offline datasets
- β¬οΈ One-command dataset installer (
traffic-sentinel:ipdata:install) - π§© Click any IP in the dashboard to open a modern IP details modal (optional)
π IP Privacy Modes (Important)
Traffic Sentinel can store IPs in multiple ways:
- Hashed IP (
ip.store = hashed) β privacy-friendly, recommended - Full IP (
ip.store = full) β store readable IP intraffic_sessions.ip - Raw IP (optional) (
privacy.store_raw_ip = true) β stores the real client IP intraffic_sessions.ip_raw
Tip: Many apps keep
ip.store = hashedbut still want runtime geolocation. We support runtime lookup without storing location in DB.
Traffic Sentinel never sends IPs to external services β all lookups are local.
π¦ Installation
composer require kianisanaullah/laravel-traffic-sentinel
Publish config & migrations:
php artisan vendor:publish --tag=traffic-sentinel-config php artisan vendor:publish --tag=traffic-sentinel-migrations php artisan migrate
π§© Middleware
Option A β Auto register (recommended for most apps)
In config/traffic-sentinel.php:
'middleware' => [ 'auto_register' => true, ],
Option B β Manually register
Add to your web middleware group: Laravel 11
\Kianisanaullah\TrafficSentinel\Http\Middleware\TrackTraffic::class,
Laravel 12 and above add in bootstrap/app.php
$middleware->append(\Kianisanaullah\TrafficSentinel\Http\Middleware\TrackTraffic::class);
π Dashboard
/admin/traffic-sentinel
πΌοΈ Dashboard Preview
Clean, readable, production-ready dashboard.
π Protect Dashboard
Protect it in config: 'dashboard' => [ 'middleware' => ['web', 'auth'], ],
π« Excluding URLs
'exclude' => [ 'paths' => [ 'admin', 'admin/traffic-sentinel', 'api', ], 'hosts' => [ 'localhost', '127.0.0.1', ], 'ips' => [ '127.0.0.1', '::1', ], 'user_agents' => [ 'UptimeRobot', 'Pingdom', ], // NOTE: route_names works only if your middleware supports it. // If you added Str::is() route exclude logic in TrackTraffic::shouldExclude(), // then you can use wildcards like 'admin.*' 'route_names' => [ // 'traffic-sentinel.*', // 'admin.*', ], ],
π Runtime IP Lookup (Country / ASN) β Offline (No APIs)
Traffic Sentinel can optionally resolve:
- Country code + country name + flag
- ASN + ASN org name
at runtime using offline datasets (no external API calls).
This is useful when:
- you want privacy-first tracking (hashed IPs), but
- still want country + ASN in the dashboard at view-time.
β Datasets are stored in
storage/(not insidevendor/) so Composer updates wonβt delete them.
β¬οΈ Install IP datasets
- Publish config (if not already):
php artisan vendor:publish --tag=traffic-sentinel-config
- Install datasets:
php artisan traffic-sentinel:ipdata:install
Force re-download (fresh install):
php artisan traffic-sentinel:ipdata:install --force
π IP Modal + Flags (UI)
Traffic Sentinel includes an optional UI helper: β’ Click an IP in any table β opens a modal with details (country, flag, ASN, CIDR match) β’ Optional: auto-hydrate small flags in tables
Enable in config:
'ui' => [ 'ip_modal' => [ 'enabled' => true, 'endpoint' => '/admin/traffic-sentinel/ip/lookup?ip=__IP__', 'hydrate_flags' => true, ], ],
What you need in tables
Render IPs like this:
<a href="#" class="ts-ip-link" data-ts-ip="{{ $ip }}" title="Click to view IP details"> <span class="me-1" data-ts-flag="{{ $ip }}">π</span> <code class="small">{{ $ip }}</code> </a>
The data-ts-flag attribute will be replaced with a small flag icon if the IP is found in the dataset.
The data-ts-ip attribute is used to trigger the IP detail modal.
The data-ts-ip attribute is required for the modal to work.
The data-ts-flag attribute is optional.
The data-ts-ip attribute can be used in any table cell.
β Notes / Best Practices
If config('traffic-sentinel.privacy.store_raw_ip') is null, you likely havenβt published config or config is cached:
php artisan config:clear php artisan cache:clear
When publishing config and file already exists:
php artisan vendor:publish --tag=traffic-sentinel-config --force
π§Ή Prune Old Data
php artisan traffic:prune --days=30
ποΈ Database Configuration (Optional)
By default, Traffic Sentinel uses your applicationβs default database connection (mysql).
You can override this and store all traffic tables in a separate connection (recommended for analytics-heavy apps).
βοΈ Step 1 β Configure Connection
In config/traffic-sentinel.php:
'database' => [ 'connection' => env('TRAFFIC_SENTINEL_DB_CONNECTION', 'mysql'), ],
βοΈ Step 2 β Set in .env (Optional)
TRAFFIC_SENTINEL_DB_CONNECTION=analytics
Now all Traffic Sentinel queries will use the analytics connection instead of the default one.
π€ Who is this for?
Traffic Sentinel is ideal for:
- Laravel SaaS & dashboards
- Admin panels & internal tools
- News / content websites
- APIs with crawler traffic
- Any app where you want visibility without surveillance
Not ideal if:
- You need ad conversion tracking
- You want marketing funnels / heatmaps
π§© Common Use Cases
- Detect SEO crawlers vs real readers
- Monitor traffic spikes & bot floods
- See which pages are actually visited by humans
- Track uptime bots & monitoring tools
- Audit referrers and external traffic sources
- Lightweight alternative to GA for internal dashboards
π£οΈ Roadmap
Planned improvements:
- IPv6 country zones expansion
- Per-route analytics
- Rate-limit & bot flood alerts
- Export to CSV / JSON
- Live updates (optional)
Suggestions & PRs are welcome.
β‘ Performance & Safety
- Single lightweight insert per request
- Uses indexed tables (safe for production)
- No event listeners or observers
- No cookies unless you enable them
- No outbound HTTP calls
- Designed for high-traffic Laravel apps
