spatie/laravel-health
Monitor your Laravel app’s health by registering checks (disk space, queues, cache, etc.). Set warning/fail thresholds and get notified via mail or Slack when something goes wrong, so you can catch issues early and keep services running smoothly.
Installation:
composer require spatie/laravel-health
Publish the config file:
php artisan vendor:publish --provider="Spatie\Health\HealthServiceProvider"
Register Checks:
In a service provider (e.g., AppServiceProvider):
use Spatie\Health\Facades\Health;
use Spatie\Health\Checks\Checks\DatabaseConnectionCheck;
Health::checks([
DatabaseConnectionCheck::new(),
]);
Run Checks:
php artisan health:check
Or trigger via HTTP:
php artisan health:check --http
Configure Notifications:
Update .env for Slack/Mail:
HEALTH_NOTIFICATIONS_SLACK_WEBHOOK_URL=your_webhook_url
HEALTH_NOTIFICATIONS_MAIL_FROM_ADDRESS=health@example.com
Monitor critical infrastructure (e.g., database, queues, disk space) during deployment or cron jobs:
Health::checks([
DatabaseConnectionCheck::new()->ignoreFailuresForConnections(['mysql']),
QueueCheck::new()->failAfterMinutes(10),
]);
Check Registration:
Database, Queue, ExternalServices).UsedDiskSpaceCheck::new()
->warnWhenUsedSpaceIsAbovePercentage(75)
->failWhenUsedSpaceIsAbovePercentage(90);
Scheduling:
app/Console/Kernel.php):
$schedule->command('health:check')->everyFiveMinutes();
Notification Integration:
config/health.php:
'notifications' => [
'mail' => true,
'slack' => [
'enabled' => true,
'webhook_url' => env('HEALTH_NOTIFICATIONS_SLACK_WEBHOOK_URL'),
],
],
only_on_failure for targeted alerts:
Health::checks([
PingCheck::new('https://api.example.com')
->failAfterMinutes(1)
->notifyOnlyOnFailure(),
]);
HTTP Endpoint:
/health endpoint with middleware:
Route::get('/health', function () {
return Health::check();
})->middleware(['auth:sanctum']);
Custom Checks:
Extend Spatie\Health\Checks\Check:
namespace App\HealthChecks;
use Spatie\Health\Checks\Check;
class CustomCheck extends Check {
public function run(): array {
return [
'status' => 'ok',
'message' => 'Custom check passed',
];
}
}
Register via:
Health::checks([new CustomCheck()]);
Dynamic Checks: Load checks conditionally (e.g., based on environment):
if (app()->environment('production')) {
Health::checks([new DatabaseConnectionCheck()]);
}
History Tracking: Enable via config:
'store_results_in_database' => true,
Query results:
$results = \Spatie\Health\Models\HealthCheckResult::latest()->take(10)->get();
Middleware Collision:
Avoid naming custom middleware health (removed in v1.39.2). Use unique names:
Route::middleware(['health:custom'])->group(...);
Time Drift: Skipped checks due to time drift? Fix with:
'ignore_time_drift' => true, // in config/health.php
Queue Check Quirks:
failAfterMinutes uses Carbon-compatible values (avoid floats in older Laravel).HorizonCheck instead of QueueCheck.Notification Delays:
sync flag for immediate alerts:
Health::checks([...])->notifySync();
Database Connection Issues:
DatabaseConnectionCheck::new()->ignoreFailuresForConnections(['mysql_replica']);
Verbose Output:
php artisan health:check --verbose
Check Isolation: Test checks individually:
Health::checks([new DatabaseConnectionCheck()])->check();
Log Results:
Enable logging in config/health.php:
'log_results' => true,
Custom Notifiers:
Implement Spatie\Health\Notifications\HealthNotification:
namespace App\Notifications;
use Spatie\Health\Notifications\HealthNotification;
class CustomNotifier extends HealthNotification {
public function via($notifiable) {
return ['custom'];
}
}
Register in config/health.php:
'notifications' => [
'custom' => App\Notifications\CustomNotifier::class,
],
Check Dependencies: Chain checks for complex workflows:
Health::checks([
new DatabaseConnectionCheck(),
new function () {
if (!DB::connection()->getPdo()) {
return ['status' => 'failed', 'message' => 'DB connection failed'];
}
return ['status' => 'ok'];
},
]);
Environment-Specific Checks:
Use app()->environment() to toggle checks:
if (app()->environment('staging')) {
Health::checks([new PingCheck('https://staging.example.com')]);
}
Slack Webhook: Ensure the webhook URL is HTTPS and properly formatted. Test with:
curl -X POST -H 'Content-type: application/json' --data '{"text":"Test"}' YOUR_WEBHOOK_URL
Mail Configuration:
Verify HEALTH_NOTIFICATIONS_MAIL_FROM_ADDRESS is a valid sender in your mail driver (e.g., Mailgun, SES).
Timezones:
Override globally in config/health.php:
'timezone' => 'America/New_York',
Or per check:
PingCheck::new()->timezone('UTC');
How can I help you explore Laravel packages today?