Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Health Check Results Laravel Package

ohdearapp/health-check-results

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Install the package:

    composer require ohdearapp/health-check-results
    
  2. Create a health check endpoint (e.g., routes/web.php):

    use OhDearApp\HealthCheckResults\CheckResults;
    use OhDearApp\HealthCheckResults\CheckResult;
    
    Route::get('/health-check', function () {
        $checkResults = new CheckResults(now());
    
        $checkResults->addCheckResult(new CheckResult(
            name: 'DatabaseConnection',
            label: 'Database Connection',
            notificationMessage: 'Database is unreachable',
            shortSummary: 'Failed',
            status: CheckResult::STATUS_FAILED,
            meta: ['error' => 'Connection timeout']
        ));
    
        return response()->json($checkResults->toArray());
    });
    
  3. Configure Oh Dear to poll this endpoint (e.g., https://your-app.test/health-check).

First Use Case: Basic Health Checks

Start with critical checks like:

  • Database connectivity
  • Disk space
  • Queue processing
  • API dependencies (e.g., Stripe, Mailgun)

Example:

$checkResults = new CheckResults(now());

// Database check
$checkResults->addCheckResult(new CheckResult(
    name: 'Database',
    label: 'Database Status',
    notificationMessage: 'Database connection failed',
    shortSummary: 'Failed',
    status: CheckResult::STATUS_FAILED,
    meta: ['query' => 'SELECT 1']
));

// Disk space check
$checkResults->addCheckResult(new CheckResult(
    name: 'DiskSpace',
    label: 'Disk Space',
    notificationMessage: 'Disk usage exceeds 90%',
    shortSummary: '92%',
    status: CheckResult::STATUS_WARNING,
    meta: ['usage_percentage' => 92]
));

Implementation Patterns

1. Structured Health Checks

Organize checks into logical groups (e.g., Infrastructure, Application, ThirdParty):

$checkResults = new CheckResults(now());

// Infrastructure checks
$checkResults->addCheckResult(new CheckResult(
    name: 'Storage',
    label: 'Storage Health',
    status: CheckResult::STATUS_OK,
    shortSummary: 'OK',
    meta: ['free_space_gb' => 50]
));

// Application checks
$checkResults->addCheckResult(new CheckResult(
    name: 'Cache',
    label: 'Redis Cache',
    status: CheckResult::STATUS_FAILED,
    notificationMessage: 'Redis connection lost',
    meta: ['last_ping' => '2023-01-01T00:00:00Z']
));

2. Dynamic Checks with Closures

Use closures for checks that require runtime logic (e.g., API calls):

$checkResults = new CheckResults(now());

$checkResults->addCheckResult(new CheckResult(
    name: 'StripeAPI',
    label: 'Stripe API',
    status: fn() => (new StripeService())->ping() ? CheckResult::STATUS_OK : CheckResult::STATUS_FAILED,
    notificationMessage: 'Stripe API is unavailable',
    shortSummary: fn() => (new StripeService())->ping() ? 'OK' : 'Failed',
    meta: ['last_ping' => now()->toIso8601String()]
));

3. Integration with Laravel Events

Trigger health checks on critical events (e.g., job.failed):

use Illuminate\Support\Facades\Event;

Event::listen('job.failed', function ($event) {
    $checkResults = new CheckResults(now());
    $checkResults->addCheckResult(new CheckResult(
        name: 'QueueWorker',
        label: 'Queue Worker',
        status: CheckResult::STATUS_FAILED,
        notificationMessage: 'Job failed: ' . $event->job->payload['command'],
        meta: ['job_id' => $event->job->id]
    ));

    // Store or return results (e.g., via API)
});

4. Scheduled Checks with Laravel Tasks

Use Laravel’s task scheduling (app/Console/Kernel.php) to run periodic checks:

protected function schedule(Schedule $schedule)
{
    $schedule->call(function () {
        $checkResults = new CheckResults(now());

        // Add checks here (e.g., database backups, cache warming)
        $checkResults->addCheckResult(new CheckResult(
            name: 'Backup',
            label: 'Database Backup',
            status: Storage::disk('backups')->exists('latest.sql') ? CheckResult::STATUS_OK : CheckResult::STATUS_FAILED,
            notificationMessage: 'Backup failed',
            meta: ['last_backup' => Storage::disk('backups')->lastModified('latest.sql')]
        ));

        // Log or return results
    })->hourly();
}

5. Reusable Check Factories

Create factories for common checks (e.g., app/Services/HealthChecks.php):

namespace App\Services;

use OhDearApp\HealthCheckResults\CheckResult;

class HealthChecks
{
    public static function databaseCheck(): CheckResult
    {
        return new CheckResult(
            name: 'Database',
            label: 'Database Connection',
            status: self::isDatabaseReachable() ? CheckResult::STATUS_OK : CheckResult::STATUS_FAILED,
            notificationMessage: 'Database is unreachable',
            shortSummary: self::isDatabaseReachable() ? 'OK' : 'Failed',
            meta: ['last_query' => now()->toIso8601String()]
        );
    }

    private static function isDatabaseReachable(): bool
    {
        // Logic to check DB connection
        return true;
    }
}

Usage:

$checkResults->addCheckResult(HealthChecks::databaseCheck());

Gotchas and Tips

Pitfalls

  1. Status Naming:

    • Use CheckResult::STATUS_OK, STATUS_WARNING, or STATUS_FAILED (not strings like "ok").
    • Example: $status = CheckResult::STATUS_FAILED; (not "failed").
  2. Meta Data Types:

    • The meta field must be an array (not an object or string).
    • Example: meta: ['key' => 'value'] (not meta: new stdClass()).
  3. Timestamp Precision:

    • finishedAt expects a Unix timestamp (integer). Use now()->timestamp or strtotime($date).
    • Avoid passing DateTime objects directly; convert to timestamp first.
  4. Notification Messages:

    • Keep messages actionable and concise (Oh Dear truncates long messages).
    • Example: ❌ "The database is not working" → ✅ "Database connection failed: Timeout".
  5. Performance:

    • Avoid blocking checks (e.g., long-running API calls). Use timeouts or async processing.
    • Cache results if checks are expensive (e.g., Cache::remember()).

Debugging Tips

  1. Validate JSON Output: Use Oh Dear’s test endpoint to validate your JSON:

    curl -X POST https://ohdear.app/api/v1/health-checks/test \
         -H "Content-Type: application/json" \
         -d @path/to/your/health-check.json
    
  2. Log Raw Results: Log the raw CheckResults object before returning JSON to debug:

    \Log::debug('Health check results:', $checkResults->toArray());
    
  3. Check for Deprecations:

    • The package supports PHP 8.4+. If using older versions, update or patch deprecated methods (e.g., CheckResult::meta type hints).

Extension Points

  1. Custom Statuses: Extend the package by adding a CheckResult subclass for custom statuses:

    class CustomCheckResult extends CheckResult
    {
        public const STATUS_MAINTENANCE = 'maintenance';
    
        public static function maintenanceCheck(): self
        {
            return new self(
                name: 'Maintenance',
                label: 'System Maintenance',
                status: self::STATUS_MAINTENANCE,
                shortSummary: 'In Maintenance',
                meta: ['scheduled_until' => now()->addHours(2)]
            );
        }
    }
    
  2. Batch Processing: Process checks in batches to avoid timeouts:

    $checkResults = new CheckResults(now());
    $batch = collect([...])->chunk(10);
    
    foreach ($batch as $items) {
        foreach ($items as $item) {
            $checkResults->addCheckResult($this->createCheckFor($item));
        }
    }
    
  3. Integration with Laravel Horizon: Use Horizon’s FailedJob events to auto-generate health checks:

    Horizon::failed(function ($job, $exception) {
        $checkResults = new CheckResults(now());
        $checkResults->addCheckResult(new CheckResult(
            name: 'QueueJob',
            label: 'Failed Job',
            status: CheckResult::STATUS_FAILED,
            notificationMessage: "Job {$job->payload['command']} failed",
            meta: ['
    
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
directorytree/privacy-filter-classifier
directorytree/privacy-filter
datacore/hub-sdk
develia/commons
cuci/prototurk-sdk
cuci/prototurk-sdk-symfony
develia/geo-bundle
dreamzy/livewire-charts
touchestate-sdk/php-sdk
22h/doctrine-garbage-collection-bundle
agtp/agtp-php
agtp/mod-php
splash/sonata-admin
splash/metadata
splash/openapi
splash/scopes
splash/toolkit
testo/output-teamcity
testo/bridge-symfony
spatie/flare-daemon-runtime