Installation:
composer require eliseekn/laravel-metrics
Publish the config (if needed):
php artisan vendor:publish --provider="Eliseekn\LaravelMetrics\LaravelMetricsServiceProvider"
First Use Case:
Generate a simple trend for a model (e.g., Product):
use Eliseekn\LaravelMetrics\LaravelMetrics;
$trends = LaravelMetrics::query(Product::query())
->count()
->byMonth()
->trends();
This returns an array of monthly counts for the current year.
Where to Look First:
config/metrics.php for default settings (e.g., date formatting, timezones).LaravelMetrics methods in src/Facades/LaravelMetrics.php.Query Chaining: Use the fluent interface to build metrics:
LaravelMetrics::query(User::query())
->where('active', true)
->sum('purchases')
->byMonth(3) // Last 3 months
->metrics(); // Returns raw metrics
Date Granularity:
byDay(7) → Last 7 days.byMonth(6) → Last 6 months.byYear() → All years in the table.byCustom($startDate, $endDate) with Carbon instances.Aggregations:
count(): Row count.sum('column'): Sum of a column (e.g., sum('revenue')).avg('column'): Average value.min('column')/max('column'): Extremes.Output Modes:
metrics(): Raw aggregated data (e.g., ['2024-01' => 150, '2024-02' => 200]).trends(): Pre-formatted for charts (includes dates and values).Custom Columns:
For non-standard aggregations, use selectRaw():
LaravelMetrics::query(Order::query())
->selectRaw('SUM(amount) as total_amount')
->byMonth()
->metrics();
$metrics = Cache::remember('user_metrics_monthly', now()->addHours(1), function () {
return LaravelMetrics::query(User::query())->count()->byMonth()->metrics();
});
return response()->json(LaravelMetrics::query(Product::query())->count()->byMonth()->trends());
LaravelMetrics::shouldReceive('query')->andReturnSelf()
->shouldReceive('count')->andReturnSelf()
->shouldReceive('byMonth')->andReturnSelf()
->shouldReceive('trends')->andReturn(['2024-01' => 100]);
Date Handling:
config/app.php) matches your database’s timezone. Metrics use Carbon under the hood.byCustom() expects Carbon instances or strings parsable by Carbon. Invalid dates may throw exceptions.
Fix: Validate inputs:
$start = Carbon::parse($request->start_date);
$end = Carbon::parse($request->end_date);
Query Complexity:
LaravelMetrics::query(Product::with('category')->query())
->count()
->byMonth();
groupBy(), metrics may override it. Use selectRaw() for custom groupings.Performance:
created_at).sum() on large decimal columns) can hit PHP’s memory limit.
Fix: Increase memory_limit or chunk queries:
LaravelMetrics::query(Order::query()->take(1000))->sum('amount')->byMonth();
SQLite Quirks:
DATE_FORMAT). Use Carbon’s accessors instead:
->selectRaw('strftime("%Y-%m", created_at) as month')
Verbose Queries: Enable query logging to inspect generated SQL:
LaravelMetrics::setDebug(true);
Or use Laravel’s built-in logging:
DB::enableQueryLog();
$metrics = LaravelMetrics::query(...);
dd(DB::getQueryLog());
Common Errors:
selectRaw().byCustom() or byMonth().->get() to debug).Custom Aggregations: Extend the package by creating a custom metric class:
namespace App\Metrics;
use Eliseekn\LaravelMetrics\Contracts\Metric;
class CustomMetric implements Metric {
public function apply($query) {
return $query->selectRaw('AVG(price) as avg_price');
}
}
Register it in config/metrics.php under custom_metrics.
Date Translations: Override default date formatting in the config:
'date_formats' => [
'day' => 'Y-m-d H:i',
'month' => 'Y-m',
'year' => 'Y',
],
Database-Specific Optimizations: Add database-specific query tweaks via service provider booting:
public function boot() {
if (app()->database->getDriverName() === 'pgsql') {
LaravelMetrics::extend(function ($metrics) {
$metrics->query->addSelect(DB::raw('DATE_TRUNC(\'month\', created_at) as month'));
});
}
}
Testing:
Use the MetricsTestCase trait (if provided) or mock the facade:
use Eliseekn\LaravelMetrics\Testing\MetricsTestCase;
class MyTest extends TestCase {
use MetricsTestCase;
}
How can I help you explore Laravel packages today?