Weave 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

Monitoring Bundle Laravel Package

ongr/monitoring-bundle

A Symfony bundle that adds health-check endpoints to your application, letting external monitoring tools query the status of services and dependencies. Useful for wiring up availability checks and exposing readiness information to uptime systems and dashboards.

View on GitHub
Deep Wiki
Context7

Getting Started

Read this first: it is a Symfony bundle, not a Laravel package. There is no ServiceProvider, no config/monitoring.php, no facades, no artisan command. The bundle registers a Bundle subclass into the Symfony kernel, ships a controller plus a route, and aggregates a set of "check" services into a single HTTP health/status response. With 1 star, 0 dependents, and a score of ~1.75, treat it as a reference implementation to read, not a dependency to composer require into a Laravel app — its PHP 7 / Symfony 2–4 constraints will collide with a modern Laravel dependency graph.

If you are evaluating it inside its native habitat (an ONGR/Symfony app), the minimal path is:

  1. composer require ongr/monitoring-bundle (pin the version; expect old Symfony constraints).
  2. Register the bundle:
    • Symfony 3: new Ongr\Bundle\MonitoringBundle\OngrMonitoringBundle() in AppKernel.php
    • Symfony 4+: Ongr\Bundle\MonitoringBundle\OngrMonitoringBundle::class => ['all' => true] in config/bundles.php
  3. Import the shipped routing under a private prefix:
    # config/routes/ongr_monitoring.yaml
    ongr_monitoring:
        resource: "@OngrMonitoringBundle/Resources/config/routing.yml"
        prefix: /_monitor
    
  4. Hit /_monitor — expect 200 when all registered checks are healthy, non-200 otherwise.

Where to look first. The package is small; read vendor/ongr/monitoring-bundle/ end to end in an hour. Three files carry the whole contract: the check/monitor interface (whatever it is named in your version), the aggregator service that collects tagged checks, and the controller that renders the aggregate. Everything else is DI plumbing.

First use case. A single liveness/readiness URL for a load balancer or uptime pinger, replacing GET / with GET /_monitor. That is the entire day-to-day value: one cheap endpoint that fans out to dependency checks (DB, Elasticsearch cluster health, cache, queue depth) and collapses them into a status code.

If you are on Laravel — which is where this assessment applies — skip steps 1–2 entirely. The equivalent first move is php artisan pulse:check / a /up route backed by Illuminate\Foundation\Configuration\Application::configure()->withRouting(health: '/up'), and read this bundle's aggregator + check interface purely as a design sketch before writing your own ~100-line version.

Implementation Patterns

The check interface is the real product. Whether you install it or port it, the pattern you take away is: one small interface, one method, a structured result (status + message), and a tag so the container collects implementations automatically. Reproduce that shape and the rest is trivial.

// Sketch of a check, regardless of framework
class ElasticsearchCheck
{
    public function __construct(private Client $client) {}

    public function check(): array
    {
        try {
            $health = $this->client->cluster()->health();
            return [
                'status'  => $health['status'] === 'red' ? 1 : 0,
                'message' => $health['status'],
            ];
        } catch (\Throwable $e) {
            return ['status' => 1, 'message' => $e->getMessage()];
        }
    }
}

Wiring pattern (Symfony). Register each check as a service and apply the bundle's tag (or the !tagged / !tagged_iterator argument in services.yaml for newer Symfony). The aggregator injects the tagged iterable and runs every check; the controller maps aggregate → HTTP status.

Wiring pattern (Laravel port). If you decide the check set is worth keeping, re-express it natively rather than importing the bundle:

// app/Providers/MonitoringServiceProvider.php
public function register(): void
{
    $this->app->singleton(HealthAggregator::class, function ($app) {
        return new HealthAggregator([
            new Checks\DatabaseCheck(),
            new Checks\CacheCheck(),
            new Checks\QueueCheck(),
            new Checks\ElasticsearchCheck($app->make(Client::class)),
        ]);
    });
}
// routes/web.php
Route::get('/_monitor', function (HealthAggregator $agg) {
    $results = $agg->run();                    // never throws
    $healthy = collect($results)->every(fn ($r) => $r['status'] === 0);
    return response()->json($results, $healthy ? 200 : 503);
})->middleware('throttle:60,1');

Workflow patterns that actually pay off day to day:

  • Deep vs. shallow split. Keep /_monitor shallow (process is alive, config loaded) for the LB, and expose a ?deep=1 variant with the expensive dependency checks for humans and on-call dashboards. A health endpoint that queries Elasticsearch on every LB poll will page you for a slow cluster and amplify the slowdown.
  • Cache the expensive checks. Run them on a short TTL (10–30s) into the cache store so 50 LB nodes polling every 5s don't become a self-inflicted load test.
  • Tag by severity. Distinguish critical (DB unreachable → 503, pull from rotation) from degraded (queue backlog → still 200, but log/alert). Collapsing everything into one boolean is the most common reason these endpoints get ignored after the first false alarm.
  • Wire it into whatever already pages you. The aggregate status code is the point — it drops into Nagios, Pingdom, UptimeRobot, K8s readinessProbe, or a plain curl --fail in CI smoke tests, with no body parsing.

Gotchas and Tips

  • Abandonment is the headline risk. 1 star, 0 dependents, no vendor, no SLA, no security response. If you fork it, you own it permanently. Budget that as a standing line item or don't start.
  • Never let a check throw. Monitoring code must fail open: wrap every check in try/catch, return an unhealthy result rather than propagating, and put explicit timeouts on every network call inside a check. An exception inside a health check that 500s the endpoint is a self-inflicted outage.
  • Beware synchronous dependency calls on the request path. A DB or ES probe inside the health controller adds latency proportional to poll rate and can cascade the failure it's meant to detect. Timeout aggressively (100–500ms), cache the result, or both.
  • Long-running processes and buffers. If you extend the package with any event buffering, watch for unbounded in-memory arrays under queue workers / Octane — a classic leak that surfaces only under sustained load. Cap and sample.
  • Config lives in the Symfony container. Any parameter read from parameters.yml has to become config/monitoring.php + env() in a Laravel port. Nothing transfers automatically.
  • Event semantics don't line up. Modern Laravel's dispatcher implements the Symfony EventDispatcherInterface contract, so listener classes may partially work — but tagged registration, priorities, and the bundle's event names won't. Don't count on drop-in listener reuse.
  • Dependency graph landmines. Expect a composer.json pinned to PHP 7.x and Symfony 2/3/4-era constraints. If you find yourself reaching for --ignore-platform-reqs or constraint relaxation, stop — that's the signal to port instead of install.
  • Silent failure is the worst failure mode. A check that always returns healthy because it caught an error and swallowed it makes your dashboard look fine while data is missing. Add a self-metric: checks executed vs. checks reporting, and alert on the gap.
  • Extension point, if you keep it: the tagged-check interface is the right place to add anything. Resist editing the aggregator or controller — add a check, add a severity, add a cache decorator. Keeping the diff in one file makes the eventual fork-upgrade (or removal) cheap.
  • The honest recommendation: for a Laravel codebase, do not adopt. Laravel Pulse (metrics), Telescope (local inspection), Horizon (queues), OpenTelemetry (traces), and the built-in /up health route cover the same ground with zero ownership cost. Read this bundle's check/aggregator split, copy the idea in ~100 lines you can test, and move on.
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.
store-doc/laravel-storage-driver
plus-it/laravel-translation-manager
diephp/perhaps
diephp/telegraph
osmaviation/spreadsheet
microsoft/fluentui-system-icons
mmccook/php-json-canonicalization-scheme
middlewares/firewall
qubiqx/montapacking
nyoncode/laravel-package-console
pnscripts/filament-broadquill-lite
pnscripts/laravel-sentfold-lite
vleap/mx-sdk-laravel-internal
twidpay/utils
htetmyathlaing/scout-elasticsearch-driver
artisan-toolbox/front-awesome
ls/client-assistant
users-au/laravel-client
cgv/localized-resource
noith/settings