directorytree/metrics
Record and query metrics in Laravel with a simple, elegant API. Track page views, API calls, signups, and other events with optional values, categories, dates, hourly buckets, model-scoped metrics, and custom attributes. Supports Redis and extensible drivers.
Installation:
composer require directorytree/metrics
php artisan vendor:publish --tag="metrics-migrations"
php artisan migrate
Publish config (optional):
php artisan vendor:publish --tag="metrics-config"
First Use Case: Track a simple event (e.g., page views):
use DirectoryTree\Metrics\Facades\Metrics;
Metrics::record(new \DirectoryTree\Metrics\MetricData('page_views'));
Or use the helper:
metric('page_views')->record();
Where to Look First:
Metrics facade or metric() helper for recording.Metric model for querying (e.g., Metric::today()->sum('value')).config/metrics.php for driver/queue settings.Event Tracking:
// app/Http/Middleware/TrackPageViews.php
public function handle(Request $request, Closure $next) {
metric('page_views')->record();
return $next($request);
}
Model-Based Metrics:
class User extends Model {
use \DirectoryTree\Metrics\HasMetrics;
}
// Record:
metric('user_logins')->measurable($user)->record();
// Query:
$user->metrics()->where('name', 'user_logins')->sum('value');
Batch Processing:
capture()/commit() for bulk operations (e.g., imports):
Metrics::capture();
foreach ($data as $item) {
metric('imported_items')->record();
}
Metrics::commit(); // Single DB write
Hourly Granularity:
metric('api_calls')->hourly()->record();
// Query:
Metric::thisHour()->where('name', 'api_calls')->sum('value');
Custom Attributes:
metric('signups')->with(['source' => 'campaign_a'])->record();
// Query:
Metric::where('name', 'signups')->where('source', 'campaign_a')->sum('value');
Redis Driver: For high-traffic apps, use Redis to batch-commit metrics:
// config/metrics.php
'driver' => 'redis',
'auto_commit' => false,
Schedule the commit command:
// app/Console/Kernel.php
$schedule->command('metrics:commit')->hourly();
Observers: Auto-record metrics on model events:
class UserObserver {
public function created(User $user) {
metric('user_creations')->record();
}
}
Laravel Events: Dispatch events and listen for metrics:
event(new UserRegistered($user));
// In listener:
metric('user_registrations')->record();
Hourly Metrics Overuse:
Custom Attributes Uniqueness:
name + attributes are merged. Oversight can lead to incorrect aggregations.metric('views')->with(['source' => 'google'])->record();
Redis TTL Misconfiguration:
metrics:commit fails, metrics may be lost.'redis_ttl' => 86400, // 1 day in seconds
Model Metrics Performance:
User::all()->metrics()) triggers N+1 queries.$users = User::withMetrics()->get();
Auto-Commit Conflicts:
auto_commit and Redis driver may cause duplicate entries.auto_commit when using Redis:
'auto_commit' => env('METRICS_DRIVER') === 'redis' ? false : true,
Missing Metrics:
capture() is active (metrics won’t persist without it).config/metrics.php.Query Issues:
Metric::toSql() to debug complex queries:
$query = Metric::thisMonth()->where('name', 'signups');
dd($query->toSql(), $query->getBindings());
Redis Stuck Metrics:
php artisan metrics:commit --force
Custom Metric Models:
Metric model to add scopes or accessors:
class CustomMetric extends \DirectoryTree\Metrics\Metric {
public function scopeActive($query) {
return $query->where('value', '>', 0);
}
}
Metric Repository:
// config/metrics.php
'repository' => \App\Repositories\CustomMetricRepository::class,
Metric Manager:
// config/metrics.php
'manager' => \App\Services\CustomMetricManager::class,
Attribute Validation:
Metrics::extend(function ($manager) {
$manager->validating(function ($data) {
if ($data->has('country')) {
$data->set('country', strtoupper($data->get('country')));
}
});
});
capture()/commit() for bulk operations (e.g., imports).Schema::table('metrics', function (Blueprint $table) {
$table->index(['name', 'category', 'year', 'month', 'day']);
});
How can I help you explore Laravel packages today?