NewWe open-sourced 50+ Laravel packages
Custom AI apps, agents and automation — Roundly ConsultingRoundly
All packages
Alerts for Laravel

The Health facade

RoundlyConsulting\Alerts\Facades\Health is the recommended entry point, and its Health alias is auto-discovered. Its surface has four parts: the check registry, a handle scoped to one owner, the maintenance-window sub-accessor and the verbs that span every owner:

use RoundlyConsulting\Alerts\Checks\DatabaseCheck;
use RoundlyConsulting\Alerts\Facades\Health;

// The check registry
Health::check(DatabaseCheck::make('mysql'));
Health::checks([DiskUsageCheck::class, MemoryUsageCheck::class]);
Health::define('orders-flowing', fn () => Order::where('created_at', '>=', now()->subHour())->exists());
Health::all();                               // Collection<string, Check>
Health::find('disk_usage_check');            // ?Check

// Everything scoped to one owner
Health::for($team)->monitor(DatabaseCheck::class)->everyFiveMinutes()->save();
Health::for($team)->schedule($data);         // from a ScheduleHealthCheckData
Health::for($team)->run(DatabaseCheck::class);
Health::for($team)->run('orders-flowing');   // by key, e.g. an inline check
Health::for($team)->report(['critical']);
Health::for($team)->status();
Health::for($team)->monitors();
Health::for($team)->unmonitor(DatabaseCheck::class);

// Maintenance windows
Health::silences()->mute('db', until: now()->addHour(), for: $team, reason: 'upgrade');
Health::silences()->unmute('db', for: $team);
Health::silences()->isMuted('db');
Health::silences()->active($team);

// Across every owner
Health::report();
Health::status();
Health::runDue();                            // what alerts:perform-health-checks calls
Health::prune(14);                           // what alerts:prune-runs calls
Health::routes();                            // the opt-in JSON endpoint

Flat methods

MethodReturnsWhat it does
check(string|object $check)HealthManagerRegister one check class or instance. Anything that does not extend Check throws InvalidHealthCheck.
checks(array $checks)HealthManagerRegister several checks at once.
define(string $key, Closure $callback)PendingCheckDefine an inline closure check (see Inline closure checks).
all()Collection<string, Check>Every registered check, keyed by its key.
find(string $key)?CheckOne registered check, or null.
for(Model $owner)NotifiableHealthThe handle scoped to one owner (next table).
report(?array $tags = null)HealthReportReport across every scheduled check, optionally filtered by tags.
status(?array $tags = null)StatusThe overall() roll-up of that report.
silences()SilencesThe maintenance-window sub-accessor (table below).
runDue()intQueue the configured job for every scheduled check whose cron is due; returns how many were queued.
prune(?int $days = null)intDelete run history older than $days (default history.retention_days); returns how many runs were deleted.
routes(?string $uri = null)RouteRegister the opt-in JSON status endpoint.

Health::for($owner)

Every health operation scoped to one owner model. The handle is a security boundary: a scheduled row that belongs to another owner is refused with InvalidHealthCheck.

MethodReturnsWhat it does
run(string|Check|HealthCheck $check)CheckResultRun now with the full alert, notify and history side effects. A registered key, class or instance runs through the owner’s scheduled row, else an on-demand row that is never scheduled; a row must belong to the owner, else InvalidHealthCheck.
report(?array $tags = null)HealthReportThis owner’s report, optionally filtered by tags.
status(?array $tags = null)StatusThis owner’s roll-up.
monitor(string $check)PendingScheduledCheckFluent schedule for a Check class or registered key (an inline check’s key starts from its define() options); save() validates the cron and returns the HealthCheck row.
schedule(ScheduleHealthCheckData $data)HealthCheckSchedule from a DTO.
unmonitor(string|Check|HealthCheck $check)intSoft-delete this owner’s schedules for a check, or one own row; another owner’s row throws InvalidHealthCheck.
monitors()Collection<int, HealthCheck>This owner’s schedules, oldest first — on-demand rows are not listed.

The UsesHealthChecks trait’s monitorCheck(), monitor() and createHealthCheck() are shortcuts over Health::for($this), so they behave exactly like the facade calls — and Health::fake() records them too (see Owner models).

Health::silences()

Maintenance windows. A key is a check key, a tag or * for everything; for: scopes a silence to one owner (see Maintenance windows & muting):

MethodReturnsWhat it does
mute(string $key, ?CarbonInterface $until = null, ?Model $for = null, ?string $reason = null)AlertSilenceMute a check key, a tag or *, optionally until a moment and/or for one owner.
unmute(string $key, ?Model $for = null)intLift the global silences on the key, or only those scoped to $for; returns how many were lifted.
isMuted(string $key, ?Model $for = null)boolWhether a silence on exactly this key is in force now. Always false when silence is off in the config.
active(?Model $for = null)Collection<int, AlertSilence>Silences in force now: all of them, or the global ones plus those scoped to $for.

Builders

  • Health::for($owner)->monitor($check) returns a PendingScheduledCheck — frequency presets, throttle, thresholds, tags, routing, escalation and meta, then save() (see Scheduling checks). For an inline check’s key it starts from the options declared on define().
  • Health::define($key, $closure) returns a PendingCheck for an inline check’s name, notification and options (see Inline closure checks).

In tests, Health::fake() swaps the whole surface for a recording fake (see Testing). If you prefer an explicit dependency or single-purpose classes, see DI and actions.

Show your open-source love

This package is free and MIT-licensed. If it saves you time, a one-off donation or a Patreon membership keeps it maintained, tested and documented.

More ways to support, including crypto

By donating, you agree to our donation terms.

Want this built into your product?

We integrate our packages into custom Laravel and AI builds. Tell us what you're working on and we'll reply within 48 hours.