$ show spatie/laravel-schedule-monitor
This is a Laravel package that monitors scheduled tasks by logging their start, finish, failure, and skip events to a database table. It provides three Artisan commands: `schedule-monitor:sync` to register tasks from the scheduler into a `monitored_scheduled_tasks` table, `schedule-monitor:list` to display their status with visual indicators for late or failed runs, and `schedule-monitor:verify` to check connectivity with the Oh Dear monitoring service. The package integrates deeply with Laravel's scheduling system through event subscribers (`ScheduledTaskEventSubscriber`, `BackgroundCommandListener`) that listen to core scheduler events and update the database accordingly. It also optionally syncs tasks with Oh Dear, pinging external endpoints on task start, finish, or failure, using a queued job (`PingOhDearJob`) with configurable retry logic and custom job support. The architecture is clean and follows Laravel package conventions: a service provider registers macros on scheduler events, configurable model bindings allow custom model classes, and a singleton (`MonitoredScheduledTasks`) stores per-task monitoring configurations (like custom names, grace times, and opt-out flags) using an in-memory array keyed by object hash. While the package is tightly coupled to Laravel's console scheduler and cannot be extracted as a standalone library, its internal patternsβsuch as the polymorphic `Task` hierarchy (CommandTask, JobTask, ClosureTask, ShellTask) and the `Payload` strategy for building Oh Dear ping dataβdemonstrate strong software design.
The LLM identified 6 files worth highlighting for reuse:
A singleton that stores per-task monitoring configuration (custom name, grace time, doNotMonitor flag, doNotMonitorAtOhDear flag, storeOutputInDb flag) in a multi-dimensional array keyed by class name and object hash. It provides setter/getter methods that are called from scheduler event macros registered by the service provider. This pattern avoids modifying the scheduler Event class and allows the package to inject custom metadata without altering core Laravel classes. It is reusable as a lightweight metadata store for any system that needs to attach ephemeral settings to objects without modifying them.
A service class that wraps the Laravel Schedule collection and provides methods to categorize tasks into monitored, ready-for-monitoring, duplicate, unnamed, and monitored-at-oh-dear groups. It filters out tasks not running in the current environment and handles task factory creation. This class is the core reporting engine for the list command and could be reused as a pattern for any system that needs to analyze a set of scheduled items and produce various filtered views.
An abstract base class for Oh Dear ping payloads, with concrete implementations for starting, finished, and failed events. Each subclass implements a static `canHandle` method to determine if it applies to a given log item, and provides `url()` and `data()` methods to build the specific ping endpoint (e.g., /starting, /finished, /failed) and payload data. The factory (`OhDearPayloadFactory`) selects the correct payload class. This strategy pattern is clean, testable, and could be extracted for any system that sends different types of notifications based on event type.
An abstraction over the Oh Dear REST API, providing methods to fetch a monitor, create a cron check, and sync multiple cron checks. It uses Laravel's HTTP client with token authentication and wraps requests in try-catch blocks to throw exceptions with descriptive messages. The API URL is configurable via the constructor, making it testable (as demonstrated by the `FakeOhDear` test double). This pattern is a textbook example of wrapping an external API for dependency injection and testability.
The central Eloquent model that tracks each scheduled task's last run timestamps, grace time, and Oh Dear registration status. It implements event handler methods (`markAsStarting`, `markAsFinished`, `markAsFailed`, `markAsSkipped`) that create log items and update timestamps. The `pingOhDear` method dispatches a queued job if a ping URL is configured. This model encapsulates both persistence and notification logic, demonstrating a rich domain model pattern within a Laravel package. The use of `UsesScheduleMonitoringModels` trait to resolve configurable model bindings adds flexibility for customization.
A queued job that sends HTTP pings to Oh Dear endpoints with configurable retry (3 attempts, custom delay), timeout (via `retryUntil`), and optional debug logging. It fires an `OhDearPingFailed` event on failure, allowing applications to react. The job uses `$deleteWhenMissingModels = true` to clean up if the log item is deleted. This is a well-constructed job that demonstrates robust error handling, configurable retries, and event-driven monitoringβa reusable pattern for any Laravel package that needs to make external HTTP calls asynchronously.