PHPackages                             kiora/health-check-bundle - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Logging &amp; Monitoring](/categories/logging)
4. /
5. kiora/health-check-bundle

ActiveSymfony-bundle[Logging &amp; Monitoring](/categories/logging)

kiora/health-check-bundle
=========================

Production-ready Symfony bundle for comprehensive application health checks with database, Redis, S3, and HTTP endpoint monitoring. Security-first design with auto-tagging support.

v2.0.0(4mo ago)01.2k↓41.3%[8 issues](https://github.com/kiora-tech/health_check_bundle/issues)MITPHPPHP &gt;=8.3CI passing

Since Nov 6Pushed 4mo agoCompare

[ Source](https://github.com/kiora-tech/health_check_bundle)[ Packagist](https://packagist.org/packages/kiora/health-check-bundle)[ Docs](https://github.com/kiora-tech/health_check_bundle)[ RSS](/packages/kiora-health-check-bundle/feed)WikiDiscussions main Synced 1mo ago

READMEChangelog (1)Dependencies (13)Versions (12)Used By (0)

Health Check Bundle
===================

[](#health-check-bundle)

A Symfony bundle providing comprehensive health check functionality for monitoring application dependencies and services.

[![CI](https://github.com/kiora-tech/health_check_bundle/actions/workflows/ci.yml/badge.svg)](https://github.com/kiora-tech/health_check_bundle/actions/workflows/ci.yml)[![codecov](https://camo.githubusercontent.com/49394158469f0d8424ced98b8fb6b08ccfd4e8c61294c6e7f32366dfbe616fbd/68747470733a2f2f636f6465636f762e696f2f67682f6b696f72612d746563682f6865616c74685f636865636b5f62756e646c652f6272616e63682f6d61696e2f67726170682f62616467652e737667)](https://codecov.io/gh/kiora-tech/health_check_bundle)[![PHPStan Level 9](https://camo.githubusercontent.com/83dd3d35cebed0eab9ee97ff1a5849c1344cda6a8ee9cac2cda20f5aa55b67bd/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f5048505374616e2d6c6576656c253230392d627269676874677265656e2e7376673f7374796c653d666c6174)](https://phpstan.org/)

[![Latest Stable Version](https://camo.githubusercontent.com/9a209dfd473a603431788d0251a96a24c266c7edc27e7aa7de5f44b19e8638da/68747470733a2f2f706f7365722e707567782e6f72672f6b696f72612f6865616c74682d636865636b2d62756e646c652f762f737461626c65)](https://packagist.org/packages/kiora/health-check-bundle)[![Total Downloads](https://camo.githubusercontent.com/b349069543f888b4a0a806488786f3701f2b5dba85333e0fdca81097951f95ff/68747470733a2f2f706f7365722e707567782e6f72672f6b696f72612f6865616c74682d636865636b2d62756e646c652f646f776e6c6f616473)](https://packagist.org/packages/kiora/health-check-bundle)[![License](https://camo.githubusercontent.com/cf7a7aa1925aaa216c7f6853644d27a6c9d818d90873c33ee7738b8af4ec67c7/68747470733a2f2f706f7365722e707567782e6f72672f6b696f72612f6865616c74682d636865636b2d62756e646c652f6c6963656e7365)](https://packagist.org/packages/kiora/health-check-bundle)

[![PHP Version](https://camo.githubusercontent.com/172ac9047cbc6f9516837d5ec072712f127ad52e879cad5cf89efae27886c97d/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f7068702d382e33253230253743253230382e342d3737374242342e7376673f6c6f676f3d706870266c6f676f436f6c6f723d7768697465)](https://www.php.net/)[![Symfony Version](https://camo.githubusercontent.com/ed3484788aadeeaa24f44f284ba4b9a6ff48633d80b74c56fccd9e87409dd4fc/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f73796d666f6e792d362e34253230253743253230372e30253230253743253230372e312d677265656e2e7376673f6c6f676f3d73796d666f6e79266c6f676f436f6c6f723d7768697465)](https://symfony.com/)

Why use this bundle?
--------------------

[](#why-use-this-bundle)

### Production-Ready &amp; Battle-Tested

[](#production-ready--battle-tested)

- Comprehensive test coverage with 37 tests and 104 assertions
- PHPStan level 9 static analysis - strictest type safety (maximum level)
- CI/CD pipeline testing across PHP 8.3/8.4 and Symfony 6.4/7.0/7.1
- Security-first design with no sensitive information exposure

### Enterprise-Grade Features

[](#enterprise-grade-features)

- Multiple database connections support (read/write replicas, analytics, logs)
- Context-aware health checks with group filtering (web, worker, console)
- Kubernetes-ready with dedicated liveness (`/ping`) and readiness (`/ready`) probes
- Performance monitoring with execution statistics and slow check detection

### Developer-Friendly

[](#developer-friendly)

- Modern auto-configuration with Symfony's `#[AutoconfigureTag]`
- No manual service tagging required
- Docker development environment included
- Follows Symfony best practices and coding standards

Features
--------

[](#features)

- 🔍 **Multiple Health Checks**: Database, Redis, S3/MinIO, HTTP endpoints
- 🗂️ **Multiple Connections**: Support for multiple database connections (read/write replicas, analytics, logs)
- 🏷️ **Check Groups**: Filter health checks by context (web, worker, console) via `?group=` parameter
- 🔒 **Security First**: No sensitive information exposed (versions, paths, credentials)
- ⚡ **Performance**: Configurable timeouts, non-blocking checks
- 🎯 **Flexible**: Critical vs non-critical checks, enable/disable per check
- 🛡️ **Production Ready**: Rate limiting, security headers, generic error messages
- 📊 **Standard Format**: JSON response with status, duration, and individual check results
- 📈 **Performance Statistics**: Monitor slow checks, average execution time, and identify performance bottlenecks

Development with Docker
-----------------------

[](#development-with-docker)

The project includes a complete Docker environment for development and testing.

### Quick Start

[](#quick-start)

```
# Start all services (MySQL, PostgreSQL, Redis, MinIO)
make up

# Install dependencies
make install

# Run tests
make test

# Run PHPStan analysis
make phpstan

# Check code style
make cs-check

# Fix code style
make cs-fix

# Run all quality checks
make check

# Open a shell in PHP container
make shell

# Stop all services
make down
```

### Available Services

[](#available-services)

- **PHP 8.4** with all required extensions
- **MySQL 8.0** on port 3306
- **PostgreSQL 16** on port 5432
- **Redis 7** on port 6379
- **MinIO (S3-compatible)** on ports 9000 (API) and 9002 (Console)

### Manual Commands

[](#manual-commands)

If you prefer not to use Make:

```
# Start services
docker compose up -d

# Run tests
docker compose exec php composer test

# Run PHPStan
docker compose exec php composer phpstan

# Open shell
docker compose exec php sh

# Stop services
docker compose down
```

Installation
------------

[](#installation)

### 1. Install the bundle

[](#1-install-the-bundle)

```
composer require kiora/health-check-bundle
```

### 2. Enable the bundle

[](#2-enable-the-bundle)

If Symfony Flex is not installed, manually add the bundle to `config/bundles.php`:

```
return [
    // ...
    Kiora\HealthCheckBundle\HealthCheckBundle::class => ['all' => true],
];
```

### 3. Import routes

[](#3-import-routes)

Create `config/routes/health_check.yaml`:

```
health_check_bundle:
    resource: '@HealthCheckBundle/config/routes.php'
    type: php
```

### 4. Configure security access

[](#4-configure-security-access)

Add public access to the health check endpoint in `config/packages/security.yaml`:

```
access_control:
    - { path: ^/health, roles: PUBLIC_ACCESS }
    # ... your other rules
```

### 5. (Optional) Configure rate limiting

[](#5-optional-configure-rate-limiting)

Create `config/packages/rate_limiter.yaml`:

```
framework:
    rate_limiter:
        health_check:
            policy: 'sliding_window'
            limit: 60
            interval: '1 minute'
```

Install required packages:

```
composer require symfony/rate-limiter symfony/lock
```

Configuration
-------------

[](#configuration)

### Basic Configuration

[](#basic-configuration)

Create `config/packages/health_check.yaml`:

```
health_check:
    enabled: true
    checks:
        database:
            enabled: true  # Default: true (auto-registered)
        redis:
            enabled: false  # Default: false (enable only if Redis is available)
```

### Built-in Checks

[](#built-in-checks)

#### 1. Database Check (Auto-registered)

[](#1-database-check-auto-registered)

✅ **Automatically enabled** - Verifies database connectivity using Doctrine DBAL.

```
health_check:
    checks:
        database:
            enabled: true  # Default: true
```

No additional configuration needed. Works out of the box with your existing Doctrine configuration.

##### Multiple Database Connections

[](#multiple-database-connections)

If your application uses multiple database connections (e.g., read/write replicas, analytics database, logs database), you can configure separate health checks for each connection:

```
services:
    # Default connection (automatically registered)
    # Already available as 'database' check

    # Analytics database (read-only replica)
    app.health_check.database_analytics:
        class: Kiora\HealthCheckBundle\HealthCheck\Checks\DatabaseHealthCheck
        autoconfigure: true
        arguments:
            $connection: '@doctrine.dbal.analytics_connection'
            $name: 'analytics'
            $critical: false  # Non-critical: analytics can be down without affecting main app
            $groups: ['worker', 'cron']  # Only check in worker/cron contexts

    # Logs database
    app.health_check.database_logs:
        class: Kiora\HealthCheckBundle\HealthCheck\Checks\DatabaseHealthCheck
        autoconfigure: true
        arguments:
            $connection: '@doctrine.dbal.logs_connection'
            $name: 'logs'
            $critical: false  # Non-critical: logging can fail without affecting main app
            $groups: ['web', 'worker']  # Check in both web and worker contexts
```

**Naming Convention:**

- Default connection: Returns `database`
- Named connections: Returns `database_{name}` (e.g., `database_analytics`, `database_logs`)

**Configuration Options:**

- `$name`: Connection identifier (default: `'default'`)
- `$critical`: Whether failure should return HTTP 503 (default: `true`)
- `$groups`: Contexts where this check runs (default: `[]` = all contexts)

#### 2. Redis Check (Manual setup)

[](#2-redis-check-manual-setup)

⚙️ **Disabled by default** - Only configure if your project uses Redis.

**Step 1:** Enable in configuration

```
health_check:
    checks:
        redis:
            enabled: true  # Explicitly enable Redis check
```

**Step 2:** Configure the service

Create or update `config/packages/health_check.yaml`:

```
services:
    Kiora\HealthCheckBundle\HealthCheck\Checks\RedisHealthCheck:
        autoconfigure: true  # Enables auto-tagging via interface
        arguments:
            $host: '%env(REDIS_HOST)%'
            $port: '%env(int:REDIS_PORT)%'
            $critical: false  # Set to true if Redis failure should return 503
```

**Step 3:** Add environment variables

```
REDIS_HOST=redis
REDIS_PORT=6379
```

#### 3. S3/MinIO Storage Check (Manual setup)

[](#3-s3minio-storage-check-manual-setup)

⚙️ **Requires manual configuration** - Only configure if your project uses S3/MinIO storage.

```
services:
    app.health_check.s3_storage:
        class: Kiora\HealthCheckBundle\HealthCheck\Checks\S3HealthCheck
        autoconfigure: true  # Enables auto-tagging via interface
        arguments:
            $filesystem: '@your.flysystem.storage'  # Your Flysystem service ID
            $name: 's3_storage'
            $critical: false
```

**Example for multiple buckets:**

```
services:
    # Documents storage
    app.health_check.s3_documents:
        class: Kiora\HealthCheckBundle\HealthCheck\Checks\S3HealthCheck
        autoconfigure: true  # Enables auto-tagging via interface
        arguments:
            $filesystem: '@documents.storage'
            $name: 's3_documents'
            $critical: false

    # Templates storage
    app.health_check.s3_templates:
        class: Kiora\HealthCheckBundle\HealthCheck\Checks\S3HealthCheck
        autoconfigure: true  # Enables auto-tagging via interface
        arguments:
            $filesystem: '@templates.storage'
            $name: 's3_templates'
            $critical: false
```

#### 4. HTTP Endpoint Check (Manual setup)

[](#4-http-endpoint-check-manual-setup)

⚙️ **For monitoring external dependencies** - Configure for each external API you depend on.

```
services:
    app.health_check.external_api:
        class: Kiora\HealthCheckBundle\HealthCheck\Checks\HttpHealthCheck
        autoconfigure: true  # Enables auto-tagging via interface
        arguments:
            $url: 'https://api.example.com/health'
            $name: 'external_api'
            $timeout: 5
            $critical: false
            $expectedStatusCodes: [200, 401]  # 401 = API accessible but auth required
```

#### Example: Microsoft Graph API

[](#example-microsoft-graph-api)

```
services:
    app.health_check.microsoft_graph:
        class: Kiora\HealthCheckBundle\HealthCheck\Checks\HttpHealthCheck
        autoconfigure: true  # Enables auto-tagging via interface
        arguments:
            $url: 'https://graph.microsoft.com/v1.0/me'
            $name: 'microsoft_graph'
            $timeout: 5
            $critical: false
            $expectedStatusCodes: [401]  # 401 = API accessible, auth required (expected)
```

Usage
-----

[](#usage)

### Available Endpoints

[](#available-endpoints)

The bundle provides three distinct endpoints for different monitoring purposes:

#### 1. `/ping` - Liveness Probe (Lightweight)

[](#1-ping---liveness-probe-lightweight)

A simple endpoint that verifies the application is running without checking any external dependencies.

```
curl http://localhost/ping
```

**Response:**

```
{
  "status": "up",
  "timestamp": "2024-01-01T12:00:00+00:00"
}
```

**Use case:** Kubernetes liveness probes, load balancer health checks

**Characteristics:**

- Always returns HTTP 200 (unless the app is completely down)
- No database or external service checks
- Extremely fast response time
- Minimal resource usage

#### 2. `/ready` - Readiness Probe (Critical Dependencies)

[](#2-ready---readiness-probe-critical-dependencies)

Checks if the application is ready to serve traffic by verifying critical dependencies in the "readiness" group.

```
curl http://localhost/ready
```

**Response:**

```
{
  "status": "healthy",
  "timestamp": "2024-01-01T12:00:00+00:00",
  "duration": 0.015,
  "checks": [
    {
      "name": "database",
      "status": "healthy",
      "message": "Database operational",
      "duration": 0.012,
      "metadata": []
    }
  ],
  "statistics": {
    "total_checks": 1,
    "slow_checks": 0,
    "average_duration": 0.012,
    "slowest_check": {
      "name": "database",
      "duration": 0.012
    }
  }
}
```

**Use case:** Kubernetes readiness probes, determining when pods should receive traffic

**Characteristics:**

- Returns HTTP 200 if all critical dependencies are healthy
- Returns HTTP 503 if any critical dependency is unhealthy
- Only checks services in the "readiness" group
- Prevents traffic routing to pods with unhealthy dependencies

#### 3. `/health` - Comprehensive Health Check

[](#3-health---comprehensive-health-check)

Provides complete health status of all configured health checks, optionally filtered by group.

```
# Check all health checks
curl http://localhost/health

# Check specific group
curl http://localhost/health?group=web
```

**Use case:** Monitoring dashboards, alerting systems, comprehensive health status

**Characteristics:**

- Returns HTTP 200 if all critical checks pass
- Returns HTTP 503 if any critical check fails
- Supports filtering by group via `?group=` parameter
- Includes performance statistics

### Endpoint Comparison

[](#endpoint-comparison)

Feature`/ping``/ready``/health`PurposeIs app running?Can serve traffic?Overall healthDependencies CheckedNoneReadiness group onlyAll or filtered by groupResponse TimeInstantFastDepends on checksKubernetes UseLiveness probeReadiness probeMonitoringHTTP 503 on FailureNeverYesYesGroup FilteringNoFixed (readiness)Yes (`?group=`)### Configuring Health Checks for Readiness

[](#configuring-health-checks-for-readiness)

To mark health checks as critical for readiness probes, assign them to the "readiness" group:

```
services:
    # Database - critical for readiness
    app.health_check.database:
        class: Kiora\HealthCheckBundle\HealthCheck\Checks\DatabaseHealthCheck
        autoconfigure: true
        arguments:
            $connection: '@doctrine.dbal.default_connection'
            $groups: ['readiness']  # Mark as critical for readiness
            $critical: true

    # Redis - critical for readiness
    app.health_check.redis:
        class: Kiora\HealthCheckBundle\HealthCheck\Checks\RedisHealthCheck
        autoconfigure: true
        arguments:
            $host: '%env(REDIS_HOST)%'
            $port: '%env(int:REDIS_PORT)%'
            $groups: ['readiness']  # Mark as critical for readiness
            $critical: true

    # External API - non-critical, not for readiness
    app.health_check.external_api:
        class: Kiora\HealthCheckBundle\HealthCheck\Checks\HttpHealthCheck
        autoconfigure: true
        arguments:
            $url: 'https://api.example.com/health'
            $name: 'external_api'
            $groups: ['web']  # Only in web group, not readiness
            $critical: false
```

### Response Format

[](#response-format)

```
{
  "status": "healthy",
  "timestamp": "2025-11-05T18:02:20+01:00",
  "duration": 0.015,
  "checks": [
    {
      "name": "database",
      "status": "healthy",
      "message": "Database operational",
      "duration": 0.002,
      "metadata": []
    },
    {
      "name": "redis",
      "status": "healthy",
      "message": "Redis operational",
      "duration": 0.001,
      "metadata": []
    }
  ],
  "statistics": {
    "total_checks": 2,
    "slow_checks": 0,
    "average_duration": 0.002,
    "slowest_check": {
      "name": "database",
      "duration": 0.002
    }
  }
}
```

#### Statistics Breakdown

[](#statistics-breakdown)

The `statistics` section provides performance insights:

- **total\_checks**: Total number of health checks executed
- **slow\_checks**: Number of checks that took longer than 1 second to execute
- **average\_duration**: Average execution time across all checks (in seconds)
- **slowest\_check**: Details of the slowest health check
    - `name`: Name of the slowest check
    - `duration`: Execution time in seconds
    - Will be `null` if no checks were executed

### Status Codes

[](#status-codes)

- **200 OK**: All critical checks passed
- **503 Service Unavailable**: One or more critical checks failed

### Check Status Values

[](#check-status-values)

- `healthy`: Check passed successfully
- `unhealthy`: Check failed
- `degraded`: Check passed with warnings (reserved for future use)

### Filtering Checks by Group

[](#filtering-checks-by-group)

Health checks can be organized into groups/contexts (e.g., `web`, `worker`, `console`) to enable granular monitoring based on the application context.

#### Using the Group Query Parameter

[](#using-the-group-query-parameter)

Filter health checks by group using the `?group=` query parameter:

```
# Check only web-related services
curl http://localhost/health?group=web

# Check only worker/background job services
curl http://localhost/health?group=worker

# Check only console/CLI services
curl http://localhost/health?group=console
```

#### Configuring Groups

[](#configuring-groups)

Assign groups to health checks in your service configuration:

```
services:
    # Database check - runs in all contexts (no groups specified)
    Kiora\HealthCheckBundle\HealthCheck\Checks\DatabaseHealthCheck:
        autoconfigure: true
        arguments:
            $connection: '@doctrine.dbal.default_connection'
            $name: 'default'
            $critical: true
            $groups: []  # Empty = belongs to all groups

    # Redis check - only for web and worker contexts
    Kiora\HealthCheckBundle\HealthCheck\Checks\RedisHealthCheck:
        autoconfigure: true
        arguments:
            $host: '%env(REDIS_HOST)%'
            $port: '%env(int:REDIS_PORT)%'
            $critical: false
            $groups: ['web', 'worker']  # Only runs when ?group=web or ?group=worker

    # External API check - only for web context
    app.health_check.external_api:
        class: Kiora\HealthCheckBundle\HealthCheck\Checks\HttpHealthCheck
        autoconfigure: true
        arguments:
            $url: 'https://api.example.com/health'
            $name: 'external_api'
            $timeout: 5
            $critical: false
            $expectedStatusCodes: [200]
            $groups: ['web']  # Only runs when ?group=web
```

#### Group Filtering Behavior

[](#group-filtering-behavior)

- **Empty groups** (`$groups: []`): Check runs in **all contexts** (no filtering)
- **Specified groups** (`$groups: ['web', 'worker']`): Check runs only when requested group matches
- **No group parameter**: All checks run (default behavior)

#### Use Cases

[](#use-cases)

**Kubernetes Probes:**

```
# Web pod - check only web-related services
livenessProbe:
  httpGet:
    path: /health?group=web
    port: 80

# Worker pod - check only worker-related services
livenessProbe:
  httpGet:
    path: /health?group=worker
    port: 80
```

**Console Commands:**

```
# Check services needed for console commands
php bin/console app:health-check --group=console
```

**Monitoring Different Environments:**

```
# Production web servers - check critical web services
curl https://prod.example.com/health?group=web

# Background workers - check queue and batch processing services
curl https://worker.example.com/health?group=worker
```

Creating Custom Health Checks
-----------------------------

[](#creating-custom-health-checks)

### 1. Create your check class

[](#1-create-your-check-class)

Simply implement `HealthCheckInterface` or extend `AbstractHealthCheck`. **No manual tagging required!**

```
