cron-monitor/php-sdk
A PHP SDK for integrating applications with Cron Monitor. Report cron job heartbeats, execution status, and failures so you can track scheduled tasks and catch missed or broken jobs. Simple to add to Laravel or any PHP project.
Architecture fit. The SDK is a thin, framework-agnostic HTTP client that emits three signals per job run — start, success, fail — to a hosted endpoint (cronheart.com by default). It owns no scheduling, storage, or state of its own, so it slots into an existing Laravel scheduler without touching job definitions, queue topology, or deploy shape. For a TPM the relevant architectural property is non-invasiveness: one provider registration, one macro chained onto existing entries, one middleware for queue jobs that run outside the scheduler. The client is explicitly fail-open ("never throws, never breaks the job"), with a 5s timeout and a single retry — the correct posture for observability embedded in a schedule runner, and a strong argument when selling the change to SRE and security. Architecturally this is a good fit provided we accept a third-party SaaS in the schedule-runner path; it is a poor fit as a self-contained capability.
Integration feasibility. High for a conventional Laravel 10/11 app on PHP 8.2+ with Composer. composer require cron-monitor/php-sdk, publish config/cron-monitor.php, map monitor UUIDs to env vars, then chain ->monitor(config('cron-monitor.monitors')['reports:nightly'] ?? ''). Auto-discovery handles the provider; extra.laravel.dont-discover apps need manual registration in bootstrap/providers.php (11) or config/app.php (10). Hard gates: PHP 8.2 minimum, and ext-curl unless a PSR-18 client is bound. The bundled SKILL.md is unusually rigorous — ordered steps, explicit verification commands (php artisan list cron-monitor, debug:config cron_monitor) — which materially lowers integration risk versus a typical 0-star package and gives the TPM a ready-made acceptance checklist.
Technical risk.
cron-monitor:sync with no code change on our side.cmk_… API token is account-wide. Pings never need the account token — that separation should be an explicit decision, not inherited.config:cache; an empty CRON_MONITOR_API_KEY= in Laravel .env is transmitted as an empty bearer token. Each yields plausible-looking misconfiguration the code does not prevent.Key questions.
.env on disk, and who holds the account-level token?cron-monitor:sync --apply idempotent and safe to run concurrently, and should it run in the deploy pipeline or as a reconciliation job?vendor/bin/cron-monitor signup creating an account from a terminal, given email verification and address handling?Stack fit. Target is Laravel 10/11 on PHP 8.2+ with Composer. In Laravel 11 scheduling lives in routes/console.php; in Laravel 10, app/Console/Kernel.php — only the file location differs, not the ->monitor(...) call. The MonitorQueueJob middleware covers queued jobs that bypass the scheduler. A mixed estate (Symfony console commands, Symfony Scheduler, plain PHP cron entries) is covered by the same package via the bundle and the vendor/bin/cron-monitor start|success|fail shell wrapper — useful for consolidating on one tool instead of three.
Migration path. Land one non-critical scheduled command first, gated on an env var so the monitor is a no-op where UUIDs are empty. Verify in staging that success, failure, and absence of a run all behave as expected on the service side before expanding. Resist the attribute form in production: it reads process env directly and does not survive config:cache, so the config-map form is the supported path.
Compatibility. Encode in the runbook: PHP < 8.2 is a hard stop; curl=no requires a bound PSR-18 client; dont-discover requires manual provider registration; the monitors map must be read through config(), never env() at the call site; committed .env files carry empty-value placeholders only — except in Laravel, where an empty CRON_MONITOR_API_KEY line must be omitted entirely rather than left blank.
Sequencing.
php artisan schedule:list plus crontab and systemd entries to enumerate every scheduled entry and assign a criticality tier.composer require, vendor:publish --tag=cron-monitor-config, populate UUID mapping from env, add empty placeholders.->monitor() on one tier-3 job, deploy, confirm heartbeats.cron-monitor:sync --dry-run, review the diff, then --apply; wire into the pipeline only after confirming idempotency.Maintenance. The client is small, MIT, and dependency-light — ongoing code maintenance is near zero. The real maintenance surface is configuration: UUID↔job mappings, monitor names, and the account token. Pin the version in composer.json, track upstream releases, and be prepared to fork; a 0-star single-maintainer package is a bus-factor risk, though a fork is cheap at this code size. Budget recurring effort for reconciling orphaned monitors after renames.
Support. No commercial support path for the client beyond the maintainer; the SaaS relationship is the actual support contract. Escalation for missed alerts routes to the vendor, not to our team, so the TPM must nail the SLA and support-channel questions before rollout. Internally, one owner should hold the account token and the monitor inventory.
Scaling. Cost and effort scale linearly with monitor count, not with traffic — a natural fit for tens of scheduled jobs, awkward for sub-minute or very high-frequency work where ping volume dominates. Each new environment (staging, self-hosted) is an endpoint config decision; keep allow_insecure_endpoint off in production and ensure production pings target the correct instance.
Failure modes. Application-side failure is designed out: no throws, one bounded retry, 5s ceiling. The failure modes that matter are silent — network egress blocked, UUID misconfigured, monitor name drifted, config:cache breaking attribute-style resolution, an empty bearer token silently rejected. Each looks healthy locally and produces no heartbeat in the service. The mitigation is procedural: alert on missing heartbeats by default, smoke-test a deliberately skipped run every quarter, and verify cron-monitor:sync --dry-run output as part of release review.
Ramp-up. An engineer can complete the first monitored job in under an hour given the ordered SKILL.md recipe; the TPM's ramp-up is the inventory and tiering exercise, which is the genuinely valuable artifact. That mapping surfaces orphaned crons, duplicate jobs, and unowned tasks — a deliverable worth having regardless of whether the package survives procurement review. Plan one sprint for a pilot on three revenue-critical jobs, a quarter of alert-quality measurement, then a go/no-go on broader coverage and paid tier.
How can I help you explore Laravel packages today?