PHPackages                             cronradar/laravel - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Logging &amp; Monitoring](/categories/logging)
4. /
5. cronradar/laravel

ActiveLibrary[Logging &amp; Monitoring](/categories/logging)

cronradar/laravel
=================

Monitor Laravel scheduled tasks with selective or MonitorAll modes. Auto-discovers keys and schedules.

0.0.9(2mo ago)05proprietaryPHPPHP ^8.1

Since Oct 2Pushed 1mo agoCompare

[ Source](https://github.com/cronradar/cronradar-laravel)[ Packagist](https://packagist.org/packages/cronradar/laravel)[ RSS](/packages/cronradar-laravel/feed)WikiDiscussions main Synced today

READMEChangelogDependencies (6)Versions (10)Used By (0)

CronRadar for Laravel
=====================

[](#cronradar-for-laravel)

Auto-discovery for the Laravel scheduler. Every task added to your `app/Console/Kernel.php` (or `routes/console.php` in Laravel 11+) is monitored automatically. Opt out per task with `->skipMonitor()`.

Built on top of the [`cronradar/cronradar`](https://packagist.org/packages/cronradar/cronradar) base SDK.

Install
-------

[](#install)

```
composer require cronradar/laravel
```

PHP 8.1+. Laravel 10, 11, and 12 supported. Auto-discovery via Laravel's package manifest — no `config/app.php` registration required.

Setup
-----

[](#setup)

Add the API key to your `.env`:

```
CRONRADAR_API_KEY=ck_app_xxxxxxxxxxxxxxxxxxxx
```

Get the API key from the CronRadar dashboard at [app.cronradar.com](https://app.cronradar.com) under your application's settings. API keys have the form `ck_app_`.

(Optional) publish the config file if you want to override defaults:

```
php artisan vendor:publish --tag=cronradar-config
```

That writes `config/cronradar.php` where you can change the base URL, default grace period, etc.

The package's service provider auto-registers a Schedule listener — no further bootstrap is needed.

Quickstart
----------

[](#quickstart)

Schedule tasks the way you always have. They're monitored automatically.

```
// routes/console.php (Laravel 11+) or app/Console/Kernel.php (Laravel 10)
use Illuminate\Support\Facades\Schedule;

Schedule::command('emails:send')
    ->hourly();

Schedule::command('reports:generate')
    ->dailyAt('02:00');

Schedule::call(fn () => MyService::nightlyJob())
    ->dailyAt('03:00');
```

That's it. The package:

- Hooks every `Schedule::command(...)`, `Schedule::call(...)`, `Schedule::job(...)`, `Schedule::exec(...)`
- Pre-syncs each scheduled task to CronRadar at boot (so they appear in the dashboard immediately)
- Translates the Laravel-fluent expression (`->hourly()`, `->dailyAt('02:00')`, etc.) to a standard cron expression
- Records `start` / `complete` / `fail` for every execution via the schedule's `before` and `after` hooks

Annotations
-----------

[](#annotations)

### Opt out per task

[](#opt-out-per-task)

Chain `->skipMonitor()` on any scheduled task:

```
Schedule::command('internal:cleanup')
    ->daily()
    ->skipMonitor();   // not monitored
```

### Override the monitor key

[](#override-the-monitor-key)

By default the key is derived from the command name (`emails:send` → `emails-send`) or the closure file/line for `Schedule::call(...)`. Override explicitly:

```
Schedule::command('reports:generate')
    ->daily()
    ->monitor('critical-daily-report');
```

Grace period is configured per-monitor on CronRadar (default 60 seconds; set via the dashboard) — it is not a per-task argument on the Laravel side.

Reference
---------

[](#reference)

### Schedule macros

[](#schedule-macros)

The package adds these methods to Laravel's `Illuminate\Console\Scheduling\Event`:

MethodPurpose`->skipMonitor()`Exclude this task from monitoring. Returns `$this` for chaining.`->monitor(?string $customKey = null)`Override the monitor key for this task. Returns `$this` for chaining.`->shouldSkipMonitor()`Returns true if `->skipMonitor()` was applied.`->isMonitored()`Returns true if the task will be monitored.### What gets monitored

[](#what-gets-monitored)

Every entry in your schedule list is auto-discovered, including:

- `Schedule::command(...)` — Artisan commands
- `Schedule::call(Closure)` — inline closures
- `Schedule::job(...)` — queued jobs
- `Schedule::exec(...)` — shell commands

The monitor key is derived as follows:

Schedule typeDefault key derivation`command('foo:bar')``foo-bar``job(SomeJob::class)``some-job` (class basename, lowercased + kebab)`exec('php artisan ...')`first non-flag token, normalized`call(Closure)``closure-{file-basename}-{line}`Override any of these with `->monitor(key: '...')`.

### Service provider behaviors

[](#service-provider-behaviors)

The package's `ServiceProvider` does the following at boot:

1. Reads the `Illuminate\Console\Scheduling\Schedule` instance after the application has finished registering schedules.
2. For each event, computes a CronRadar key and resolves the cron expression via `$event->expression`.
3. Calls `CronRadar::syncMonitor(...)` for each non-skipped event.
4. Wraps each event's `before(...)` and `after(...)` with `startJob` / `completeJob`. Failures are detected via Laravel's `onFailure` callback, which calls `failJob`.

This means schedule changes that ship via CI deploy: the next boot syncs the new monitors, and removed tasks sit "stale" in CronRadar until you delete them.

Configuration
-------------

[](#configuration)

Published config (`config/cronradar.php`) keys:

KeyDefaultPurpose`api_key``env('CRONRADAR_API_KEY')`API key. Required.`base_url``env('CRONRADAR_BASE_URL', 'https://cron.life')`Override the ingestion endpoint.`default_grace_period``env('CRONRADAR_DEFAULT_GRACE_PERIOD', 60)`Default seconds for tasks without `->monitor(gracePeriod: N)`.`enabled``env('CRONRADAR_ENABLED', true)`Master switch. Set to `false` in tests / local dev.`timeout``5`HTTP request timeout in seconds.All envs:

Environment variableRequiredDefaultPurpose`CRONRADAR_API_KEY`yes—API key. Format `ck_app_xxxxx`.`CRONRADAR_BASE_URL`no`https://cron.life`Override the ingestion endpoint.`CRONRADAR_ENABLED`no`true`Set to `false` to disable monitoring entirely (useful in tests).`CRONRADAR_DEFAULT_GRACE_PERIOD`no`60`Default grace period in seconds.`CRONRADAR_LOG_ERRORS`no`1`Set to `0` to suppress Laravel log warnings on network failure.Error handling
--------------

[](#error-handling)

The package upholds the same hard guarantees as the base SDK:

1. **Never throws to user code.** Network errors, timeouts, 4xx/5xx responses — all caught and logged via `Log::warning(...)`. A failing CronRadar API must not break a Laravel scheduled task.
2. **Never alters task execution.** The package uses Laravel's standard `before` / `after` / `onFailure` hooks; it never modifies task state, exit codes, or queueing behavior.

What this looks like at runtime:

SituationSDK behaviorLaravel behaviorCronRadar API unreachableLogs once; returnsTask runs and is logged normallySync on boot fails for one taskLogs; continuesOther tasks sync; `php artisan schedule:run` worksPer-task ping failsLogs; returnsTask state unchangedUser task throwsRecords `failJob` with exception messageLaravel logs the failure as usualCron expression not parseableWarns; that task is not monitoredLaravel runs it normally on its scheduleTroubleshooting
---------------

[](#troubleshooting)

### Tasks aren't showing up in the CronRadar dashboard

[](#tasks-arent-showing-up-in-the-cronradar-dashboard)

1. **Confirm `CRONRADAR_API_KEY` is set in `.env`** and that you've cleared config cache (`php artisan config:clear`).
2. **Confirm `php artisan schedule:list`** shows your tasks. If they're not in the schedule, the package can't see them.
3. **Run `php artisan schedule:run` manually** to trigger an execution and look for any CronRadar warnings in `storage/logs/laravel.log`.
4. **Verify outbound HTTPS to `https://cron.life`** isn't blocked by your hosting provider.

### `->skipMonitor()` is undefined

[](#-skipmonitor-is-undefined)

Macro registration didn't run. Causes:

- Service provider registration failed (check `php artisan package:discover`).
- You're calling `->skipMonitor()` on something other than `Illuminate\Console\Scheduling\Event` (e.g., a closure result).
- The package version is mismatched against your Laravel version. Confirm Laravel 10/11/12 and `cronradar/laravel` ^1.0.

### `php artisan schedule:run` works in production but tasks never re-monitor after a deploy

[](#php-artisan-schedulerun-works-in-production-but-tasks-never-re-monitor-after-a-deploy)

The schedule is read at boot. If your deploy doesn't restart workers / FPM, the new tasks aren't synced until something boots Laravel fresh. Either:

- Add `php artisan cronradar:sync` to your deploy step (force-resyncs the schedule), or
- Use `php artisan optimize:clear` + restart your workers.

### Closure-based tasks get ugly auto-keys like `closure-app-console-kernel-42`

[](#closure-based-tasks-get-ugly-auto-keys-like-closure-app-console-kernel-42)

That's the default key derivation for closures (file basename + line). For closures you care about, set an explicit key:

```
Schedule::call(fn () => doNightlyWork())
    ->dailyAt('03:00')
    ->monitor(key: 'nightly-work');
```

### How do I disable monitoring during tests?

[](#how-do-i-disable-monitoring-during-tests)

Set `CRONRADAR_ENABLED=false` in `phpunit.xml`:

```

```

The package becomes a no-op; your scheduled-task assertions and `Bus::fake()` setups behave exactly as without the package.

Links
-----

[](#links)

- **Documentation:** [docs.cronradar.com](https://docs.cronradar.com)
- **Agent-friendly index:** [docs.cronradar.com/llms.txt](https://docs.cronradar.com/llms.txt)
- **OpenAPI spec:** [api.cronradar.com/swagger/v1/swagger.json](https://api.cronradar.com/swagger/v1/swagger.json)
- **Packagist:** [packagist.org/packages/cronradar/laravel](https://packagist.org/packages/cronradar/laravel)
- **GitHub:** [github.com/cronradar/cronradar-laravel](https://github.com/cronradar/cronradar-laravel)
- **Base SDK:** [packagist.org/packages/cronradar/cronradar](https://packagist.org/packages/cronradar/cronradar)
- **Support:**

License
-------

[](#license)

© 2026 [CronRadar](https://cronradar.com) · Proprietary — see [LICENSE](./LICENSE).

###  Health Score

36

—

LowBetter than 79% of packages

Maintenance88

Actively maintained with recent releases

Popularity4

Limited adoption so far

Community2

Small or concentrated contributor base

Maturity40

Maturing project, gaining track record

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~26 days

Recently: every ~51 days

Total

9

Last Release

66d ago

### Community

Maintainers

![](https://avatars.githubusercontent.com/u/217820567?v=4)[cronradar](/maintainers/cronradar)[@cronradar](https://github.com/cronradar)

---

Tags

schedulerlaravelmonitoringartisancrontaskscheduled

###  Code Quality

TestsPHPUnit

### Embed Badge

![Health badge](/badges/cronradar-laravel/health.svg)

```
[![Health](https://phpackages.com/badges/cronradar-laravel/health.svg)](https://phpackages.com/packages/cronradar-laravel)
```

###  Alternatives

[nightowl/agent

NightOwl monitoring agent — collects telemetry from laravel/nightwatch and writes to PostgreSQL

771.7k](/packages/nightowl-agent)[lucianotonet/laravel-telescope-mcp

MCP Server extension for Laravel Telescope

2027.2k](/packages/lucianotonet-laravel-telescope-mcp)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
