Installation:
composer require benjdiasaad/laravel-db-monitor
php artisan vendor:publish --tag=db-monitor-config
php artisan vendor:publish --tag=db-monitor-migrations
php artisan migrate
config/db-monitor.php is published and configured (e.g., slow_query_threshold, n_plus_one_threshold).Enable Middleware:
Add Benjdiasaad\LaravelDbMonitor\Middleware\MonitorQueries::class to your app/Http/Kernel.php under $middleware (for global monitoring) or $middlewareGroups (e.g., web).
First Use Case:
Trigger a slow query or N+1 issue in your app (e.g., manually loop through a collection with ->each() or force a slow query with DB::select('SELECT SLEEP(2)')). Check the dashboard at /db-monitor or run:
php artisan db:report
Middleware Integration:
MonitorQueries middleware globally or selectively (e.g., only for API routes).app/Http/Kernel.php:
protected $middleware = [
// ...
\Benjdiasaad\LaravelDbMonitor\Middleware\MonitorQueries::class,
];
$except in the middleware.Query Tagging:
Tag queries for better organization (e.g., by feature or module). Use the tag() method in queries:
DB::select('SELECT * FROM users', ['tag' => 'auth']);
php artisan db:report or check the dashboard. N+1 issues appear under the "N+1 Queries" section with details like:
Query: SELECT * FROM posts WHERE user_id = ?
Parent Query: SELECT * FROM users
Occurrences: 5
->each() with ->with() or ->load().
// Before (N+1)
$users = User::all();
foreach ($users as $user) {
$user->posts; // Triggers N+1 queries
}
// After (Fixed)
$users = User::with('posts')->get();
cursor() for Large Datasets:
User::cursor()->each(function ($user) {
// Avoids loading all users into memory
});
slow_query_threshold in config/db-monitor.php (default: 100ms). Adjust based on your app’s needs.
'slow_query_threshold' => 200, // Log queries slower than 200ms
email column").db:generate-index Artisan command:
php artisan db:generate-index --query="SELECT * FROM users WHERE email = ?"
config/db-monitor.php:
'alerts' => [
'email' => true,
'slack' => [
'enabled' => true,
'webhook_url' => env('SLACK_WEBHOOK_URL'),
],
],
alert helper to notify admins:
\Benjdiasaad\LaravelDbMonitor\Facades\DbMonitor::alert(
'High query load detected!',
'Slow queries exceeded threshold.'
);
php artisan db:report --days=7 # Report for last 7 days
php artisan db:report --format=json # Export as JSON
0 3 * * * cd /path-to-project && php artisan db:report --days=1 >> /var/log/db_monitor.log
barryvdh/laravel-debugbar, add this to config/db-monitor.php:
'debugbar' => true,
MonitorQueries middleware adds minimal overhead (~1-2ms per request), but avoid using it in high-frequency loops (e.g., cron jobs or queue workers).
if (!app()->runningUnitTests()) {
$middleware = [MonitorQueries::class];
}
enabled to false in config/db-monitor.php during high-traffic periods:
'enabled' => env('DB_MONITOR_ENABLED', true),
EXPLAIN in the dashboard for query optimization tips.pg_stat_statements is enabled for accurate metrics.
-- Enable in PostgreSQL
CREATE EXTENSION pg_stat_statements;
EXPLAIN ANALYZE). Use the package for basic query logging.tag => request()->ip). Use static tags for consistency:
DB::select('SELECT * FROM users', ['tag' => 'user-list']);
<untagged>. Ensure critical queries are tagged for better organization.rm database/migrations/xxxx_create_index_on_users_email.php
db:generate-index command may not always suggest composite indexes. Manually review EXPLAIN output for complex queries.->with()). Exclude such queries by tagging them:
DB::select('SELECT * FROM posts', ['tag' => 'pagination-safe']);
pagination-safe to ignored_tags in config/db-monitor.php:
'ignored_tags' => ['pagination-safe'],
cursor() or lazy(). Ensure you’re testing with eager-loaded collections.Prunable trait to auto-delete old logs. Adjust prune_after_days in config/db-monitor.php:
'prune_after_days' => 30, // Delete logs older than 30 days
mysql or pgsql for the db_monitor table (avoid SQLite for production).enabled: false in config/db-monitor.php to debug issues without logging queries.db_monitor_queries table directly for missing or corrupted entries:
SELECT * FROM db_monitor_queries ORDER BY created_at DESC LIMIT 10;
php artisan config:clear
php artisan cache:clear
How can I help you explore Laravel packages today?