plusforta / health-bundle
Symfony health check bundle inspired by Spatie's laravel-health
Package info
gitlab.com/plusforta/public/healthbundle
Type:symfony-bundle
pkg:composer/plusforta/health-bundle
Requires
- php: ^8.2
- ohdearapp/health-check-results: ^1.0
- symfony/console: ^6.4|^7.0
- symfony/framework-bundle: ^6.4|^7.0
Requires (Dev)
- doctrine/dbal: ^3.0|^4.0
- phpstan/phpstan: ^1.0|^2.0
- phpunit/phpunit: ^10.0|^11.0
- symfony/cache: ^6.4|^7.0
- symfony/http-client: ^6.4|^7.0
- symfony/mailer: ^6.4|^7.0
- symfony/messenger: ^6.4|^7.0
- symfony/notifier: ^6.4|^7.0
- symfony/process: ^6.4|^7.0
- symfony/test-pack: ^1.0
Suggests
- doctrine/dbal: Required for database health checks
- symfony/cache: Required for CacheCheck, CacheResultStore, and throttling
- symfony/http-client: Required for PingCheck and MeilisearchCheck
- symfony/mailer: Required for email notifications
- symfony/messenger: Required for MessengerCheck
- symfony/notifier: Required for Slack notifications
- symfony/process: Required for UsedDiskSpaceCheck
This package is not auto-updated.
Last update: 2026-03-25 14:02:15 UTC
README
A Symfony bundle for monitoring the health of your application. It provides a set of built-in health checks, an HTTP endpoint compatible with Oh Dear application health monitoring, and a simple API for creating your own custom checks.
This package was entirely inspired by the excellent spatie/laravel-health package.
Installation
composer require plusforta/health-bundle
Requirements: PHP 8.2+, Symfony 6.4 or 7.0
Configuration
Create config/packages/health.yaml:
health:
endpoint:
enabled: true
path: /health-check-results
secret: '%env(HEALTH_CHECK_SECRET)%'
always_send_fresh_results: true
failure_status_code: 200
result_stores:
json_file:
enabled: true
path: '%kernel.project_dir%/var/health-check-results.json'
cache:
enabled: true
pool: cache.app
doctrine:
enabled: true
connection: ~
keep_history_for_days: 5
notifications:
enabled: false
throttle_minutes: 60
only_on_failure: true
email:
to: admin@example.com
from: health@example.com
slack:
dsn: 'slack://token@default/channel'
checks:
database:
class: Plusforta\Health\Check\Checks\DatabaseCheck
label: Database Connection
disk_space:
class: Plusforta\Health\Check\Checks\UsedDiskSpaceCheck
options:
warning_threshold: 70
error_threshold: 90
Oh Dear Integration
This bundle is designed to work with Oh Dear's application health monitoring out of the box. The JSON endpoint uses the ohdearapp/health-check-results package to produce output in the exact format Oh Dear expects:
{
"finishedAt": 1234567890,
"checkResults": [
{
"name": "Database",
"label": "Database Connection",
"notificationMessage": "",
"shortSummary": "Ok",
"status": "ok",
"meta": {
"connection_name": "default"
}
}
]
}
Simply point Oh Dear at your /health-check-results endpoint (with the secret token if configured) and it will start monitoring your checks.
You can also protect the endpoint with a secret token, passed via the X-Secret-Token header or ?secret= query parameter.
While built for Oh Dear, the JSON output is straightforward and can be consumed by any monitoring system.
Built-in Checks
| Check | Description | Requires |
|---|---|---|
DatabaseCheck | Verifies database connectivity via SELECT 1 | doctrine/dbal |
DatabaseConnectionCountCheck | Monitors active database connections | doctrine/dbal |
DatabaseSizeCheck | Checks total database size in GB | doctrine/dbal |
DatabaseTableSizeCheck | Checks individual table size | doctrine/dbal |
CacheCheck | Tests cache read/write/delete operations | symfony/cache |
RedisCheck | Verifies Redis connectivity via PING | Redis extension or Predis |
RedisMemoryUsageCheck | Monitors Redis memory consumption | Redis extension or Predis |
PingCheck | Makes HTTP requests to verify external services | symfony/http-client |
MeilisearchCheck | Verifies Meilisearch health endpoint | symfony/http-client |
UsedDiskSpaceCheck | Monitors disk usage with configurable thresholds | symfony/process |
EnvironmentCheck | Asserts the application environment (prod, dev, etc.) | - |
DebugModeCheck | Asserts the kernel debug mode state | - |
ProfilerCheck | Detects if the WebProfilerBundle is active | - |
MessengerCheck | Heartbeat mechanism to detect stuck message consumers | symfony/messenger |
Creating Custom Checks
Creating a custom health check is straightforward. Extend the abstract Check class and implement the run() method:
<?php
declare(strict_types=1);
namespace App\Health\Checks;
use Plusforta\Health\Check\Check;
use Plusforta\Health\Result\Result;
class QueueDepthCheck extends Check
{
public function __construct(
private readonly int $warningThreshold = 100,
private readonly int $errorThreshold = 500,
) {
}
public function run(): Result
{
$depth = $this->getQueueDepth();
if ($depth >= $this->errorThreshold) {
return Result::make("Queue depth is {$depth}")
->failed()
->shortSummary("{$depth} jobs")
->meta(['depth' => $depth]);
}
if ($depth >= $this->warningThreshold) {
return Result::make("Queue depth is {$depth}")
->warning()
->shortSummary("{$depth} jobs")
->meta(['depth' => $depth]);
}
return Result::make()
->ok()
->shortSummary("{$depth} jobs")
->meta(['depth' => $depth]);
}
private function getQueueDepth(): int
{
// Your logic here
}
}
The Result Object
The Result class uses a fluent builder pattern. Available methods:
Result::make(string $message = '')- Create a new result->ok(),->warning(),->failed(),->crashed(),->skipped()- Set the status->shortSummary(string)- A brief status string (shown in Oh Dear dashboard)->notificationMessage(string)- Message used in notifications->meta(array)- Arbitrary metadata (included in JSON output)
Registering Custom Checks
Register your check in your bundle configuration:
health:
checks:
queue_depth:
class: App\Health\Checks\QueueDepthCheck
label: Message Queue
options:
warning_threshold: 100
error_threshold: 500
Or tag it as a service directly:
services:
App\Health\Checks\QueueDepthCheck:
tags: ['health.check']
Naming and Labels
Check names and labels are derived automatically from the class name. QueueDepthCheck becomes:
- Name:
QueueDepth - Label:
Queue Depth
You can override both:
QueueDepthCheck::new()
->name('queue')
->label('RabbitMQ Queue Depth');
CLI Commands
# Run all health checks and display results
php bin/console health:check
# Run checks but don't store results or send notifications
php bin/console health:check --no-store --no-notification
# Exit with non-zero code if any check fails
php bin/console health:check --fail-on-error
# List all registered checks
php bin/console health:list
# Pause health checks (e.g. during deployments)
php bin/console health:pause
# Resume health checks
php bin/console health:resume
Events
The bundle dispatches events before and after each check runs:
CheckStartingEvent- Dispatched before a check runsCheckEndedEvent- Dispatched after a check completes, includes the result
Use these to add logging, metrics, or custom side effects.
Result Stores
Results can be persisted to multiple stores simultaneously:
| Store | Description |
|---|---|
InMemoryResultStore | Static in-memory storage (useful for testing) |
JsonFileResultStore | Persists results to a JSON file |
CacheResultStore | Uses Symfony's cache component |
DoctrineResultStore | Database storage with automatic history tracking and pruning |
License
MIT