spatie/laravel-stats
Lightweight Laravel package to track and summarize database stat changes over time. Create a stats class, call increase/decrease on events, then query totals and deltas over ranges grouped by day/week/month for easy reporting.
BaseStats) and leveraging Laravel’s service container. It aligns well with Laravel’s ecosystem, avoiding heavy dependencies or complex abstractions.increase/decrease/set methods are ideal for tracking business metrics (e.g., subscriptions, orders) in real-time or batch processes. The ability to backdate events (increase(1, $timestamp)) enables historical data correction.StatsQuery builder supports granular time-based aggregation (minute/year) and custom grouping, making it adaptable to analytics dashboards or reporting tools.HasMany), and attributes, enabling multi-tenant or segmented analytics (e.g., per-tenant stats).SubscriptionStats::increase() in a SubscriptionCreated event handler).created() observer for User model).TrackSubscriptionJob).set() method allows external data sources (e.g., Stripe webhooks) to update stats directly.stats table. Migration conflicts could arise if the table name is customized or conflicts with existing tables.increase/decrease calls (e.g., per-request) may impact DB performance. Mitigation: Batch writes or queue jobs.stats table on statistic, period_start, and period_end is critical.StatsQuery method renames). Test thoroughly during adoption.increase/decrease could require transactions or locks.statistic column differentiate tenants? (Options: Prefix with tenant ID, use a tenant_id column.)version column or shadow table.increase/decrease logic and integration tests for query accuracy are essential.UserCreated event → UserStats::increase()).TrackUserActivityJob).set() via Stripe webhook).stats table is indexed on:
ALTER TABLE stats ADD INDEX idx_statistic_period ON (statistic, period_start, period_end);
/stats/subscriptions?group=week).composer require spatie/laravel-stats
php artisan vendor:publish --provider="Spatie\Stats\StatsServiceProvider" --tag="stats-migrations"
php artisan migrate
BaseStats subclasses (e.g., UserStats, OrderStats) in app/Models/Stats.// Before: $user->increment('count');
// After: UserStats::increase();
// app/Listeners/TrackUserCreation.php
public function handle(UserCreated $event) {
UserStats::increase();
}
// app/Jobs/BackfillUserStats.php
public function handle() {
User::chunk(100, function ($users) {
UserStats::set($users->count());
});
}
increase/decrease logic.$stats = UserStats::query()
->start(now()->subMonth())
->groupByWeek()
->get();
config/stats.php (if needed).StatsQuery for custom date formats.stats table (e.g., metadata JSON field) via migrations.Tenant::orderStats()).UserStats).stats table growth. Consider partitioning by period_start for large datasets.stats table in regular DB backups.2.x → 2.y).increase/decrease calls (e.g., DB connection issues).try {
UserStats::increase();
} catch (\Exception $e) {
Log::error("Failed to track user stat", ['error' => $e]);
}
increase/decrease calls are triggered (add logging).groupByMinute() over large datasets).DB::enableQueryLog(); to inspect queries.php artisan tinker to test stats manually.ProductStats).How can I help you explore Laravel packages today?