Skip to content

Health Monitoring

Health monitoring using Spatie Health package with Laravel Telescope for debugging and performance analysis.

The health monitoring system provides:

  • Health check endpoints for load balancers and monitoring
  • Dashboard UI for manual inspection
  • Email notifications for failures (throttled)
  • Historical data stored in database
Terminal window
# Via Artisan
./vendor/bin/sail artisan health:check
# Via HTTP
curl http://localhost/health

Navigate to /health-dashboard (requires authentication).

CheckPurposeThreshold
DatabasePostgreSQL connectivity-
CacheRedis connectivity-
Disk SpaceAvailable storageWarn: 70%, Fail: 90%
Optimized AppLaravel optimization statusProduction only
Debug ModeAPP_DEBUG is falseProduction only
EnvironmentAPP_ENV matches expectedProduction only

Each check returns one of:

  • ok - Check passed
  • warning - Check passed with concerns
  • failed - Check failed
GET /health
Response (200 OK):
{
"finishedAt": "2025-11-14T17:30:00Z",
"checkResults": [
{"name": "Database", "status": "ok"},
{"name": "Cache", "status": "ok"},
{"name": "UsedDiskSpace", "status": "ok", "meta": {"used": "45%"}}
]
}
Response (503 Service Unavailable):
{
"finishedAt": "2025-11-14T17:30:00Z",
"checkResults": [
{"name": "Database", "status": "failed", "message": "Connection refused"}
]
}
GET /health-dashboard

Visual dashboard showing:

  • All check statuses
  • Historical trends
  • Failure details

File: config/health.php

return [
'result_stores' => [
DatabaseHealthResultStore::class => [
'keep_history_for_days' => 5,
],
],
'notifications' => [
'enabled' => true,
'notifiable' => HealthNotifiable::class,
'channels' => ['mail'],
'throttle_notifications_for_minutes' => 60,
],
];
Terminal window
# Notification email
HEALTH_NOTIFICATION_EMAIL=ops@example.com
# Database connection for health checks
HEALTH_DB_CONNECTION=pgsql

Telescope provides debugging and monitoring for:

  • Requests
  • Commands
  • Jobs
  • Exceptions
  • Logs
  • Database queries
  • Cache operations
  • Mail
  • Notifications
GET /telescope

Requires authentication in production.

File: config/telescope.php

'enabled' => env('TELESCOPE_ENABLED', true),
'ignore_commands' => [
'schedule:work',
'queue:work',
],
'ignore_paths' => [
'nova-api*',
'pulse*',
],

Telescope data is pruned daily:

  • Keeps last 14 days
  • Preserves exception entries
  • Runs via scheduler
app/Console/Kernel.php
$schedule->command('telescope:prune --hours=336')->daily();
# Load balancer health check
HealthCheck:
Path: /health
Interval: 30
Timeout: 5
HealthyThreshold: 2
UnhealthyThreshold: 2
# DataDog agent check
- name: volare_health
url: https://api.volare.com/health
check_interval: 30
alert_on_failure: true
# Prometheus scrape config
- job_name: 'volare'
metrics_path: '/health'
static_configs:
- targets: ['api.volare.com']
use Spatie\Health\Checks\Check;
use Spatie\Health\Checks\Result;
class AerTicketApiCheck extends Check
{
public function run(): Result
{
try {
$service = app(AerticketCabinetService::class);
$service->testConnection();
return Result::make()->ok('AerTicket API is accessible');
} catch (\Exception $e) {
return Result::make()
->failed("AerTicket API unreachable: {$e->getMessage()}");
}
}
}
app/Providers/HealthServiceProvider.php
use Spatie\Health\Facades\Health;
Health::checks([
// ... existing checks
AerTicketApiCheck::new(),
]);
// Notifications sent when checks fail
// Throttled to 1 per hour per check
class HealthNotifiable extends Notifiable
{
public function routeNotificationForMail(): string
{
return config('health.notification_email');
}
}
// Add Slack channel
'channels' => ['mail', 'slack'],
// Configure webhook
HEALTH_SLACK_WEBHOOK_URL=https://hooks.slack.com/...
  1. Run check manually:
Terminal window
./vendor/bin/sail artisan health:check
  1. Check specific service:
Terminal window
# Database
./vendor/bin/sail artisan tinker
>>> DB::connection()->getPdo();
# Cache
>>> Cache::get('test');
  1. Check authentication
  2. Verify route registration
  3. Check middleware configuration
  1. Check TELESCOPE_ENABLED=true
  2. Verify storage permissions
  3. Check database migration ran