1. Go to this page and download the library: Download directorytree/metrics library. Choose the download type require.
2. Extract the ZIP file and open the index.php.
3. Add this code to the index.php.
<?php
require_once('vendor/autoload.php');
/* Start to develop here. Best regards https://php-download.com/ */
// app/Console/Kernel.php
protected function schedule(Schedule $schedule): void
{
$schedule->command('metrics:commit')->hourly();
}
use DirectoryTree\Metrics\MetricData;
use DirectoryTree\Metrics\Facades\Metrics;
Metrics::record(new MetricData('signups'));
metric('signups')->record();
use DirectoryTree\Metrics\PendingMetric;
PendingMetric::make('signups')->record();
// Track multiple API calls at once
metric('api:requests')->record(10);
// Track batch job completions
metric('jobs:completed')->record(250);
metric('auth:logins')->record(); // value: 1
metric('auth:logins')->record(); // value: 1
// Database will contain one metric with value: 2
// Track API calls by endpoint
metric('api:requests')->category('users')->record();
metric('api:requests')->category('orders')->record();
// Track errors by severity
metric('app:errors')->category('critical')->record();
metric('app:errors')->category('warning')->record();
// Track purchases by payment method
metric('purchases')->category('stripe')->record();
metric('purchases')->category('paypal')->record();
use Carbon\Carbon;
// Backfill signup data from an import
metric('signups')
->date(Carbon::parse('2025-01-15'))
->record(50);
// Record yesterday's batch job completions
metric('jobs:completed')
->date(Carbon::yesterday())
->record(1250);
// Track API requests by hour
metric('api:requests')
->hourly()
->record();
use Carbon\Carbon;
// Record API requests for a specific hour
metric('api:requests')
->date(Carbon::parse('2025-10-19 14:30:00'))
->hourly()
->record();
// This will be stored with hour = 14
use DirectoryTree\Metrics\Metric;
// Get metrics for this hour
$metrics = Metric::thisHour()->get();
// Get metrics for last hour
$metrics = Metric::lastHour()->get();
// Get metrics for a specific date and hour
$metrics = Metric::onDateTime(Carbon::parse('2025-10-19 14:00:00'))->get();
// Get API requests for the current hour
$requests = Metric::thisHour()
->where('name', 'api:requests')
->sum('value');
use DirectoryTree\Metrics\HasMetrics;
use Illuminate\Database\Eloquent\Model;
class User extends Model
{
use HasMetrics;
}
// Track logins per user
metric('auth:logins')
->measurable(Auth::user())
->record();
// Track orders per customer
metric('orders')
->measurable(Customer::find(...))
->record();
// Track API calls per client
metric('api:requests')
->measurable(ApiClient::find(...))
->record();
// Get total logins for a user
$totalLogins = $user->metrics()
->where('name', 'auth:logins')
->sum('value');
// Get orders this month for a customer
$ordersThisMonth = $customer->metrics()
->where('name', 'orders')
->thisMonth()
->sum('value');
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
Schema::table('metrics', function (Blueprint $table) {
$table->string('source')->nullable()->index();
$table->string('country')->nullable()->index();
$table->string('device')->nullable();
});
// Track post views with traffic source
metric('views')
->measurable(Post::find(1))
->with(['source' => 'google'])
->record();
// Track conversions with multiple attributes
metric('conversions')
->with([
'source' => 'facebook',
'country' => 'US',
'device' => 'mobile',
])
->record();
// Track API requests for a user within a team
metric('api:requests')
->measurable(Auth::user())
->with(['team_id' => 123])
->record();
// Get page views by source
$googleViews = Metric::where('name', 'page:views')
->where('source', 'google')
->sum('value');
// Get conversions by country this month
$conversions = Metric::thisMonth()
->where('name', 'conversions')
->get()
->groupBy('country')
->map->sum('value');
// Get mobile vs desktop traffic
$mobileViews = Metric::today()
->where('name', 'page:views')
->where('device', 'mobile')
->sum('value');
use DirectoryTree\Metrics\MetricData;
use DirectoryTree\Metrics\Facades\Metrics;
Metrics::record(new MetricData(
name: 'page:views',
additional: [
'source' => 'google',
'country' => 'US',
]
));
use DirectoryTree\Metrics\Facades\Metrics;
Metrics::capture();
// Record multiple metrics...
metric('signups')->record();
metric('notifications:sent')->category('welcome')->record();
metric('signups')->record();
// Commit all captured metrics at once
Metrics::commit();
Metrics::stopCapturing();
// app/Providers/AppServiceProvider.php
use DirectoryTree\Metrics\Facades\Metrics;
class AppServiceProvider extends ServiceProvider
{
// ...
public function boot(): void
{
Metrics::capture();
}
}
use DirectoryTree\Metrics\Metric;
// Get today's metrics
$metrics = Metric::today()->get();
// Get this week's metrics
$metrics = Metric::thisWeek()->get();
// Get this month's metrics
$metrics = Metric::thisMonth()->get();
// Get this year's metrics
$metrics = Metric::thisYear()->get();
// Get yesterday's metrics
$metrics = Metric::yesterday()->get();
// Get last week's metrics
$metrics = Metric::lastWeek()->get();
// Get last month's metrics
$metrics = Metric::lastMonth()->get();
// Get last year's metrics
$metrics = Metric::lastYear()->get();
// Get metrics between specific dates
$metrics = Metric::betweenDates(
Carbon::parse('2025-01-01'),
Carbon::parse('2025-12-31')
)->get();
// Get metrics on a specific date
$metrics = Metric::onDate(Carbon::parse('2025-10-15'))->get();
// Get today's signups
$signups = Metric::today()
->where('name', 'signups')
->sum('value');
// Get this week's purchases
$purchases = Metric::thisWeek()
->where('name', 'purchases')
->sum('value');
// Get API usage by endpoint this month
$apiUsage = Metric::thisMonth()
->where('name', 'api:requests')
->get()
->groupBy('category')
->map->sum('value');
// Count unique metrics recorded today
$count = Metric::today()->count();
use DirectoryTree\Metrics\Measurable;
use DirectoryTree\Metrics\Facades\Metrics;
public function test_user_signup_records_metric()
{
Metrics::fake();
// Your code that records metrics...
$this->post('register', [
'email' => '[email protected]',
'password' => 'password',
]);
// Assert metrics were recorded
Metrics::assertRecorded('signups');
}
public function test_api_call_records_metric_with_endpoint()
{
Metrics::fake();
$this->getJson('api/users');
// Assert metrics were recorded with a closure
Metrics::assertRecorded(fn (Measurable $metric) =>
$metric->name() === 'api:requests' &&
$metric->category() === 'users'
);
}
public function test_failed_login_records_metric()
{
Metrics::fake();
$this->post('login', [
'email' => '[email protected]',
'password' => 'wrong',
]);
// Assert metrics were not recorded
Metrics::assertNotRecorded('auth:logins');
// Assert failed login was recorded
Metrics::assertRecorded('auth:attempts');
}
public function test_purchase_records_metric_for_user()
{
Metrics::fake();
$user = User::factory()->create();
$this->actingAs($user)->post('purchases', [
'product_id' => 1,
]);
// Assert metrics were recorded with model
Metrics::assertRecorded(fn ($metric) =>
$metric->name() === 'purchases' &&
$metric->measurable()?->is($user)
);
}
public function test_batch_job_records_metrics()
{
Metrics::fake();
// Run your batch job
Artisan::call('orders:process');
// Assert metrics were recorded a specific number of times
Metrics::assertRecordedTimes('orders:processed', 100);
}
Metrics::fake();
metric('api:requests')->category('users')->record();
// Get all recorded metrics
$all = Metrics::recorded();
// Get metrics by name
$apiCalls = Metrics::recorded('api:requests');
// Get metrics with a closure
$userEndpoint = Metrics::recorded(fn ($metric) =>
$metric->category() === 'users'
);
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class CustomMetric extends Model
{
protected $guarded = [];
protected function casts(): array
{
return [
'year' => 'integer',
'month' => 'integer',
'day' => 'integer',
'hour' => 'integer',
'value' => 'integer',
];
}
}
use App\Models\CustomMetric;
use DirectoryTree\Metrics\DatabaseMetricManager;
/**
* Bootstrap any application services.
*/
public function boot(): void
{
DatabaseMetricManager::useModel(CustomMetric::class);
}
use App\Models\ApiMetric;
use App\Models\UserMetric;
// Store API metrics in a separate table
metric('requests')
->model(ApiMetric::class)
->record();
// Store user metrics in another table
metric('user:logins')
->model(UserMetric::class)
->with(['user_id' => Auth::id()])
->record();
// Use the default model
metric('page:views')->record();
namespace App\Metrics;
use DirectoryTree\Metrics\Measurable;
use DirectoryTree\Metrics\MetricManager;
class CustomMetricManager implements MetricManager
{
public function record(Measurable $metric): void
{
// Your custom recording logic...
}
public function commit(): void
{
// Your custom commit logic...
}
public function capture(): void
{
// Your custom capture logic...
}
public function isCapturing(): bool
{
// Your custom capturing check...
}
public function stopCapturing(): void
{
// Your custom stop capturing logic...
}
}
use App\Metrics\CustomMetricManager;
use DirectoryTree\Metrics\MetricManager;
public function register(): void
{
$this->app->singleton(MetricManager::class, CustomMetricManager::class);
}
namespace App\Metrics;
use DirectoryTree\Metrics\Measurable;
use DirectoryTree\Metrics\MetricRepository;
class CustomMetricRepository implements MetricRepository
{
public function add(Measurable $metric): void
{
// Your custom add logic...
}
public function all(): array
{
// Your custom retrieval logic...
}
public function flush(): void
{
// Your custom flush logic...
}
}
use App\Metrics\CustomMetricRepository;
use DirectoryTree\Metrics\MetricRepository;
public function register(): void
{
$this->app->singleton(MetricRepository::class, CustomMetricRepository::class);
}