ez-php / health
Lightweight health-check endpoint for the ez-php framework — DB, Redis, and Queue probes with a JSON /health response
Requires
- php: ^8.5
- ez-php/contracts: ^2.0
- ez-php/http: ^2.0
Requires (Dev)
- ez-php/docker: ^2.0
- ez-php/framework: ^2.0
- friendsofphp/php-cs-fixer: ^3.94
- phpstan/phpstan: ^2.1
- phpstan/phpstan-deprecation-rules: ^2.0
- phpstan/phpstan-strict-rules: ^2.0
- phpunit/phpunit: ^13.0
Suggests
- ext-redis: Needed for Probe\RedisProbe and Probe\RedisQueueProbe
Provides
None
Conflicts
None
Replaces
None
- dev-main
- 2.5.6
- 2.5.5
- 2.5.4
- 2.5.3
- 2.5.2
- 2.5.1
- 2.5.0
- 2.4.11
- 2.4.10
- 2.4.9
- 2.4.8
- 2.4.7
- 2.4.6
- 2.4.5
- 2.4.4
- 2.4.3
- 2.4.2
- 2.4.1
- 2.4.0
- 2.3.9
- 2.3.8
- 2.3.7
- 2.3.6
- 2.3.5
- 2.3.4
- 2.3.3
- 2.3.2
- 2.3.1
- 2.3.0
- 2.2.1
- 2.2.0
- 2.1.1
- 2.1.0
- 2.0.1
- 2.0.0
- 1.14.0
- 1.13.1
- 1.13.0
- 1.12.2
- 1.12.1
- 1.12.0
- 1.11.2
- 1.11.1
- 1.11.0
- 1.10.0
- 1.9.2
- 1.9.1
- 1.9.0
- 1.8.0
- 1.7.1
- 1.7.0
- 1.6.1
- 1.6.0
- 1.5.1
- 1.5.0
- 1.4.2
- 1.4.1
- 1.4.0
- 1.3.0
- 1.2.0
- 1.1.1
- 1.1.0
- 1.0.1
This package is auto-updated.
Last update: 2026-09-30 19:50:23 UTC
README
Lightweight health-check endpoint for the ez-php framework.
Registers a GET /health route that runs configurable probes (database, Redis, queue) and returns a JSON report. Independently registrable via HealthServiceProvider — no additional route configuration required.
Installation
composer require ez-php/health
Add the provider to provider/modules.php:
\EzPhp\Health\HealthServiceProvider::class,
The /health endpoint is now live.
Response format
HTTP 200 — all probes healthy:
{
"status": "ok",
"probes": {
"database": { "status": "ok", "message": "connected", "latency_ms": 1.23 },
"redis": { "status": "ok", "message": "connected", "latency_ms": 0.45 },
"queue": { "status": "ok", "message": "3 pending job(s)", "latency_ms": 0.89 }
}
}
HTTP 503 — one or more probes degraded or unhealthy:
{
"status": "degraded",
"probes": {
"database": { "status": "ok", "message": "connected", "latency_ms": 1.10 },
"redis": { "status": "degraded", "message": "slow response", "latency_ms": 310.00 },
"queue": { "status": "ok", "message": "0 pending job(s)", "latency_ms": 0.70 }
}
}
Status levels
| Status | Meaning | HTTP |
|---|---|---|
ok |
All probes passed | 200 |
degraded |
At least one probe is impaired but not critical | 503 |
unhealthy |
At least one probe failed completely | 503 |
Built-in probes
| Probe | Trigger condition | What it checks |
|---|---|---|
DatabaseProbe |
DatabaseInterface bound in container |
SELECT 1 on the configured PDO |
RedisProbe |
health.redis.host config key present |
PING on the Redis server |
QueueProbe |
queue.driver config is not 'redis' (the default) |
SELECT COUNT(*) FROM jobs |
RedisQueueProbe |
queue.driver config is 'redis' |
ready + due delayed jobs (same as RedisDriver::size()); not-yet-due delayed jobs reported as , N delayed |
OpcacheProbe |
health.opcache.enabled config is true (opt-in) |
opcache_get_status() memory usage + hit rate |
Probes that cannot be set up (missing binding, missing extension) are silently skipped — the endpoint still works with whatever probes are available.
Configuration
Add to config/health.php (only needed for the Redis and OPcache probes):
<?php return [ 'redis' => [ 'host' => getenv('REDIS_HOST') ?: '127.0.0.1', 'port' => (int) (getenv('REDIS_PORT') ?: 6379), ], 'opcache' => [ 'enabled' => filter_var(getenv('HEALTH_OPCACHE_ENABLED'), FILTER_VALIDATE_BOOLEAN), ], ];
The queue probe needs no config/health.php entry — it reads the queue module's own
queue.driver/queue.redis.* config keys to pick QueueProbe (database) or
RedisQueueProbe (Redis) automatically.
Custom probes
Implement ProbeInterface and register a custom HealthRegistry in a service provider:
use EzPhp\Health\HealthRegistry; use EzPhp\Health\HealthResult; use EzPhp\Health\ProbeInterface; final class StorageProbe implements ProbeInterface { public function name(): string { return 'storage'; } public function check(): HealthResult { $start = microtime(true); $ok = is_writable('/var/www/html/storage'); $latency = (microtime(true) - $start) * 1000; return $ok ? HealthResult::ok($this->name(), 'writable', $latency) : HealthResult::unhealthy($this->name(), 'not writable', $latency); } } // In your ServiceProvider::register(): $this->app->bind(HealthRegistry::class, fn() => new HealthRegistry([ new DatabaseProbe($pdo), new StorageProbe(), ]));
Rebinding HealthRegistry replaces the whole registry, including the built-in probes. To add
a probe alongside whatever HealthServiceProvider already wires up (database, Redis, queue,
opt-in OPcache), tag it instead — HealthServiceProvider::register() collects every
ProbeInterface registered under the 'health.probe' tag:
use EzPhp\Contracts\TaggedContainerInterface; // In your ServiceProvider::register(), before HealthServiceProvider has registered // (provider order in provider/modules.php controls this): $container = $this->app->make(TaggedContainerInterface::class); $container->tag(StorageProbe::class, 'health.probe');
StorageProbe is resolved through the container like any other tagged service — give it a
constructor if it needs dependencies, the container will autowire it.
Static facade
use EzPhp\Health\Health; $results = Health::check(); // array<string, HealthResult> $status = Health::status(); // HealthStatus::OK | DEGRADED | UNHEALTHY
License
MIT