A production health dashboard for Laravel: pluggable checks, a JSON endpoint for uptime monitors and a status page.
webrek/laravel-health-ui is a Laravel package for a production health dashboard for laravel: pluggable checks, a json endpoint for uptime monitors and a status page..
It currently has 0 GitHub stars and 0 downloads on Packagist (latest version v1.2.0).
Install it with composer require webrek/laravel-health-ui.
Discover more Laravel packages by webrek
or browse all Laravel packages to compare alternatives.
Last updated
A production health dashboard for Laravel. Pluggable checks (database, cache, disk, external services), a JSON endpoint your uptime monitor can poll, and a clean status page — all from a single route.
composer require webrek/laravel-health-ui
Visit /health to see the status page, or poll it as JSON:
curl -H "Accept: application/json" https://your-app.test/health
{
"status": "ok",
"healthy": true,
"checks": [
{"name": "database", "status": "ok", "message": "Connection [sqlite] is reachable.", "meta": [], "duration_ms": 0.4},
{"name": "cache", "status": "ok", "message": "Cache read/write succeeded.", "meta": [], "duration_ms": 0.2},
{"name": "disk_space", "status": "ok", "message": "Disk is 41% full.", "meta": {"used_percent": 41}, "duration_ms": 0.1}
]
}
The endpoint returns 200 while the app is healthy and 503 the moment a check fails hard — exactly what an uptime monitor needs (Pingdom, UptimeRobot, a Kubernetes liveness probe).
/upLaravel's built-in /up route answers a single question: did the framework
boot? That tells you nothing about whether your database is reachable, whether
your cache is responding, whether the disk is filling up, or whether a
third-party API you depend on is down. This package runs real checks, aggregates
them, and shows you which one is sick — on a status page and as machine-readable
JSON.
Each check returns one of three statuses, and the overall status is the worst of them:
| Status | Meaning | HTTP |
| --- | --- | --- |
| ok (Operational) | Healthy | 200 |
| warning (Degraded) | Working but needs attention (e.g. disk at 85%, debug mode enabled) | 200 |
| failed (Down) | A hard failure | 503 |
Warnings keep the endpoint at 200 so you aren't paged for degraded-but-serving conditions — only hard failures flip it to 503.
Enable and tune them in config/health-ui.php:
'checks' => [
'database' => ['enabled' => true, 'connection' => null],
'cache' => ['enabled' => true, 'store' => null],
'disk_space' => ['enabled' => true, 'path' => null, 'warning_threshold' => 80, 'failure_threshold' => 90],
'debug_mode' => ['enabled' => true],
'http' => ['enabled' => true, 'endpoints' => [
['name' => 'Payments API', 'url' => 'https://api.example.com/health', 'timeout' => 5],
]],
],
select 1 on the connection.APP_DEBUG is enabled (a common slip in production).The schedule check reads a timestamp your scheduler keeps fresh. Add a frequent
task that stamps it:
// routes/console.php (or your schedule definition)
Schedule::call(fn () => cache()->forever('health-ui:schedule-heartbeat', now()->timestamp))
->everyMinute();
The check then fails if that heartbeat is older than max_age_minutes.
Implement the Check contract. Return a Result, or simply throw an exception —
the checker turns an exception into a failed result automatically.
use Webrek\HealthUi\Contracts\Check;
use Webrek\HealthUi\Result;
class RedisQueueDepthCheck implements Check
{
public function name(): string
{
return 'queue_depth';
}
public function run(): Result
{
$depth = Redis::llen('queues:default');
return $depth < 1000
? Result::ok($this->name(), "Queue depth is {$depth}.", ['depth' => $depth])
: Result::warning($this->name(), "Queue is backing up ({$depth}).", ['depth' => $depth]);
}
}
Register it (e.g. in a service provider):
app(\Webrek\HealthUi\HealthChecker::class)->register(new RedisQueueDepthCheck);
Run the checks from the CLI or a cron — it exits with a non-zero code when unhealthy, so it plugs straight into deployment gates and alerting:
php artisan health:check
'route' => env('HEALTH_UI_ROUTE', 'health'),
// Protect the endpoint — it can expose internal details.
'middleware' => [],
// Cache the report so frequent polls don't run every check each hit.
'cache' => ['ttl' => 0, 'store' => null, 'key' => 'health-ui.report'],
Publish the config and views to customize them:
php artisan vendor:publish --tag=health-ui-config
php artisan vendor:publish --tag=health-ui-views
The endpoint can reveal internal state. In production, put it behind
middleware(a token, a signed URL, or an internal network restriction).
| Component | Version | | --------- | ------- | | PHP | 8.2+ | | Laravel | 12.x / 13.x |
composer install
composer test
See CONTRIBUTING.md.
Please review the security policy before reporting a vulnerability.
The MIT License (MIT). See LICENSE.