health-laravel maintained by waypointer-digital
Kanbino Health (Laravel)
A drop-in /health endpoint for Laravel apps that emits:
status—healthyordegradedbased on probe outcomes (HTTP 200 / 503).checks— per-probe results (database, redis, queue, plus your own).stack— auto-collected OS profile (id/version/codename), kernel, PHP version, and dpkg package versions for a configured allowlist.
Kanbino's uptime monitor consumes the stack section to match your servers against Ubuntu Security Notices and oss-security advisories.
Install
composer require waypointer-digital/health-laravel
php artisan vendor:publish --tag=kanbino-health-config
The route GET /health is registered automatically. Override the path in config/kanbino-health.php or via KANBINO_HEALTH_PATH=/internal/health.
Response shape
{
"status": "healthy",
"checks": {
"database": { "ok": true, "ms": 4 },
"redis": { "ok": true, "ms": 1 },
"queue": { "ok": true, "depth": 3 }
},
"stack": {
"os": { "id": "ubuntu", "version": "24.04", "codename": "noble", "name": "Ubuntu 24.04 LTS" },
"kernel": "6.8.0-49-generic",
"php": "8.5.1",
"packages": {
"nginx": "1.24.0-2ubuntu7.1",
"postgresql": "16.4-0ubuntu0.24.04.1",
"redis-server": "5:7.0.15-1ubuntu0.1"
}
}
}
Configuration
config/kanbino-health.php:
return [
'enabled' => env('KANBINO_HEALTH_ENABLED', true),
'path' => env('KANBINO_HEALTH_PATH', '/health'),
'middleware' => ['web'],
'token' => env('KANBINO_HEALTH_TOKEN'),
'stack' => [
'enabled' => true,
'packages' => ['nginx', 'postgresql', 'redis-server', 'php8.5-fpm', /* ... */],
'cache_seconds' => 3600,
],
'probes' => [
\Kanbino\Health\Probes\DatabaseProbe::class,
\Kanbino\Health\Probes\RedisProbe::class,
\Kanbino\Health\Probes\QueueProbe::class,
// Opt-in system probes:
// \Kanbino\Health\Probes\HorizonProbe::class, // requires laravel/horizon
// \Kanbino\Health\Probes\DiskProbe::class,
// \Kanbino\Health\Probes\MemoryProbe::class,
// \Kanbino\Health\Probes\CpuProbe::class,
],
];
Built-in probes
| Probe | What it checks | Default | Notes |
|---|---|---|---|
DatabaseProbe |
SELECT 1 on default connection |
enabled | Reports ms |
RedisProbe |
PING on default Redis connection |
enabled | Reports ms |
QueueProbe |
Reads queue size on default connection | enabled | Reports depth (the queue backend, not the workers) |
HorizonProbe |
Active Horizon master supervisors | opt-in | Requires laravel/horizon. Catches "Redis up, but Horizon dead and jobs piling up" — different signal than QueueProbe |
DiskProbe |
Disk usage on a path | opt-in | Constructor: path, failAtPercent (default /, 95%) |
MemoryProbe |
Used memory from /proc/meminfo |
opt-in | Constructor: failAtPercent (default 95%). Returns OK with note on macOS where /proc isn't available |
CpuProbe |
Load avg vs core count | opt-in | Constructor: failAtPercent (default 150%, i.e. 1.5× core saturation). Cores read from /proc/cpuinfo, no shell_exec |
To override default thresholds or paths, bind in your AppServiceProvider:
$this->app->bind(\Kanbino\Health\Probes\DiskProbe::class, fn () => new \Kanbino\Health\Probes\DiskProbe('/var/www', 90.0));
$this->app->bind(\Kanbino\Health\Probes\CpuProbe::class, fn () => new \Kanbino\Health\Probes\CpuProbe(120.0));
Auth
If KANBINO_HEALTH_TOKEN is set, requests must send Authorization: Bearer <token>. The Kanbino monitor sends the configured token automatically.
Custom probes
Implement Kanbino\Health\Probes\HealthProbe and add it to the probes config array:
namespace App\Health;
use Kanbino\Health\Probes\HealthProbe;
use Kanbino\Health\Probes\ProbeResult;
class ScalewayReachableProbe implements HealthProbe
{
public function name(): string
{
return 'scaleway';
}
public function run(): ProbeResult
{
$ok = @fsockopen('s3.nl-ams.scw.cloud', 443, $err, $errstr, 2) !== false;
return $ok ? ProbeResult::ok() : ProbeResult::fail($errstr ?: 'unreachable');
}
}
// config/kanbino-health.php
'probes' => [
\Kanbino\Health\Probes\DatabaseProbe::class,
\Kanbino\Health\Probes\RedisProbe::class,
\Kanbino\Health\Probes\QueueProbe::class,
\App\Health\ScalewayReachableProbe::class, // your project-specific check
],
A failing probe flips status to degraded and the endpoint returns HTTP 503 — Kanbino's monitor will mark the service as degraded.
Stack package detection
Stack package versions are read from /var/lib/dpkg/status (Debian/Ubuntu only, no shell exec). On non-dpkg systems (macOS, Alpine), the packages block will be empty but OS/kernel/PHP detection still works where possible.
The OS is detected from /etc/os-release — ID, VERSION_ID, VERSION_CODENAME. Codename matching (noble, jammy, …) is what Kanbino uses to filter Ubuntu Security Notices for your release.
Manual usage
If you don't want the auto-registered route, set enabled => false and use HealthResponse from your own controller:
use Kanbino\Health\HealthResponse;
Route::get('/my-health', function (HealthResponse $response) {
return response()->json($response->build());
});