├── .php_cs.dist.php
├── CHANGELOG.md
├── LICENSE.md
├── README.md
├── UPGRADING.md
├── composer.json
├── config
└── schedule-monitor.php
├── database
├── factories
│ ├── MonitoredScheduledTaskFactory.php
│ └── MonitoredScheduledTaskLogItemFactory.php
└── migrations
│ └── create_schedule_monitor_tables.php.stub
├── resources
└── views
│ ├── alert.blade.php
│ ├── components
│ ├── duplicate-tasks.blade.php
│ ├── monitored-tasks.blade.php
│ ├── ready-for-monitoring-tasks.blade.php
│ ├── task.blade.php
│ ├── title.blade.php
│ └── unnamed-tasks.blade.php
│ ├── list.blade.php
│ └── sync.blade.php
└── src
├── Commands
├── ListCommand.php
├── SyncCommand.php
└── VerifyCommand.php
├── EventHandlers
├── BackgroundCommandListener.php
└── ScheduledTaskEventSubscriber.php
├── Exceptions
└── InvalidClassException.php
├── Jobs
└── PingOhDearJob.php
├── Models
├── MonitoredScheduledTask.php
└── MonitoredScheduledTaskLogItem.php
├── ScheduleMonitorServiceProvider.php
└── Support
├── Concerns
├── UsesMonitoredScheduledTasks.php
└── UsesScheduleMonitoringModels.php
├── OhDearPayload
├── OhDearPayloadFactory.php
└── Payloads
│ ├── FailedPayload.php
│ ├── FinishedPayload.php
│ ├── Payload.php
│ └── StartingPayload.php
└── ScheduledTasks
├── MonitoredScheduledTasks.php
├── ScheduledTaskFactory.php
├── ScheduledTasks.php
└── Tasks
├── ClosureTask.php
├── CommandTask.php
├── JobTask.php
├── ShellTask.php
└── Task.php
/.php_cs.dist.php:
--------------------------------------------------------------------------------
1 | in([
5 | __DIR__ . '/src',
6 | __DIR__ . '/tests',
7 | ])
8 | ->name('*.php')
9 | ->notName('*.blade.php')
10 | ->ignoreDotFiles(true)
11 | ->ignoreVCS(true);
12 |
13 | return (new PhpCsFixer\Config())
14 | ->setRules([
15 | '@PSR2' => true,
16 | 'array_syntax' => ['syntax' => 'short'],
17 | 'ordered_imports' => ['sort_algorithm' => 'alpha'],
18 | 'no_unused_imports' => true,
19 | 'not_operator_with_successor_space' => true,
20 | 'trailing_comma_in_multiline' => true,
21 | 'phpdoc_scalar' => true,
22 | 'unary_operator_spaces' => true,
23 | 'binary_operator_spaces' => true,
24 | 'blank_line_before_statement' => [
25 | 'statements' => ['break', 'continue', 'declare', 'return', 'throw', 'try'],
26 | ],
27 | 'phpdoc_single_line_var_spacing' => true,
28 | 'phpdoc_var_without_name' => true,
29 | 'method_argument_space' => [
30 | 'on_multiline' => 'ensure_fully_multiline',
31 | 'keep_multiple_spaces_after_comma' => true,
32 | ],
33 | 'single_trait_insert_per_statement' => true,
34 | ])
35 | ->setFinder($finder);
36 |
--------------------------------------------------------------------------------
/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | # Changelog
2 |
3 | All notable changes to `laravel-schedule-monitor` will be documented in this file
4 |
5 | ## 3.10.3 - 2025-02-21
6 |
7 | ### What's Changed
8 |
9 | * set default oh dear api url by @resohead in https://github.com/spatie/laravel-schedule-monitor/pull/125
10 |
11 | **Full Changelog**: https://github.com/spatie/laravel-schedule-monitor/compare/3.10.2...3.10.3
12 |
13 | ## 3.10.2 - 2025-02-21
14 |
15 | ### What's Changed
16 |
17 | * Additional custom ping endpoint and config by @resohead in https://github.com/spatie/laravel-schedule-monitor/pull/123
18 |
19 | ### New Contributors
20 |
21 | * @resohead made their first contribution in https://github.com/spatie/laravel-schedule-monitor/pull/123
22 |
23 | **Full Changelog**: https://github.com/spatie/laravel-schedule-monitor/compare/3.10.1...3.10.2
24 |
25 | ## 3.10.1 - 2025-02-21
26 |
27 | ### What's Changed
28 |
29 | * Laravel 12.x Compatibility by @laravel-shift in https://github.com/spatie/laravel-schedule-monitor/pull/122
30 |
31 | **Full Changelog**: https://github.com/spatie/laravel-schedule-monitor/compare/3.10.0...3.10.1
32 |
33 | ## 2.4.8 - 2025-02-17
34 |
35 | ### What's Changed
36 |
37 | * Update MonitoredScheduledTask.php to get the failed response to be st… by @675076143 in https://github.com/spatie/laravel-schedule-monitor/pull/121
38 |
39 | ### New Contributors
40 |
41 | * @675076143 made their first contribution in https://github.com/spatie/laravel-schedule-monitor/pull/121
42 |
43 | **Full Changelog**: https://github.com/spatie/laravel-schedule-monitor/compare/2.4.7...2.4.8
44 |
45 | ## 3.10.0 - 2025-02-05
46 |
47 | ### What's Changed
48 |
49 | * Add support for a custom ping endpoint in Oh Dear by @mattiasgeniar in https://github.com/spatie/laravel-schedule-monitor/pull/119
50 |
51 | **Full Changelog**: https://github.com/spatie/laravel-schedule-monitor/compare/3.9.2...3.10.0
52 |
53 | ## 3.9.2 - 2025-01-17
54 |
55 | ### What's Changed
56 |
57 | * Use explicit nullable type is Task::nextRunAt by @bastien-phi in https://github.com/spatie/laravel-schedule-monitor/pull/117
58 |
59 | **Full Changelog**: https://github.com/spatie/laravel-schedule-monitor/compare/3.9.1...3.9.2
60 |
61 | ## 3.9.1 - 2025-01-17
62 |
63 | ### What's Changed
64 |
65 | * Fix CronExpression deprecation using constructor instead of factory method by @bastien-phi in https://github.com/spatie/laravel-schedule-monitor/pull/118
66 |
67 | ### New Contributors
68 |
69 | * @bastien-phi made their first contribution in https://github.com/spatie/laravel-schedule-monitor/pull/118
70 |
71 | **Full Changelog**: https://github.com/spatie/laravel-schedule-monitor/compare/3.9.0...3.9.1
72 |
73 | ## 3.9.0 - 2025-01-06
74 |
75 | ### What's Changed
76 |
77 | * Store schedule monitoring configurations in its own singleton by @m-bymike in https://github.com/spatie/laravel-schedule-monitor/pull/114
78 |
79 | ### New Contributors
80 |
81 | * @m-bymike made their first contribution in https://github.com/spatie/laravel-schedule-monitor/pull/114
82 |
83 | **Full Changelog**: https://github.com/spatie/laravel-schedule-monitor/compare/3.8.2...3.9.0
84 |
85 | ## 3.8.2 - 2024-12-16
86 |
87 | ### What's Changed
88 |
89 | * don't write to horizon config when not available by @Propaganistas in https://github.com/spatie/laravel-schedule-monitor/pull/116
90 |
91 | ### New Contributors
92 |
93 | * @Propaganistas made their first contribution in https://github.com/spatie/laravel-schedule-monitor/pull/116
94 |
95 | **Full Changelog**: https://github.com/spatie/laravel-schedule-monitor/compare/3.8.1...3.8.2
96 |
97 | ## 3.8.1 - 2024-07-29
98 |
99 | ### What's Changed
100 |
101 | * Fix prune link in config file comment by @pelmered in https://github.com/spatie/laravel-schedule-monitor/pull/113
102 |
103 | ### New Contributors
104 |
105 | * @pelmered made their first contribution in https://github.com/spatie/laravel-schedule-monitor/pull/113
106 |
107 | **Full Changelog**: https://github.com/spatie/laravel-schedule-monitor/compare/3.8.0...3.8.1
108 |
109 | ## 3.8.0 - 2024-06-17
110 |
111 | ### What's Changed
112 |
113 | * Update README.md typo by @acip in https://github.com/spatie/laravel-schedule-monitor/pull/111
114 | * Make `graceTimeInMinutes` configurable by @faustbrian in https://github.com/spatie/laravel-schedule-monitor/pull/112
115 |
116 | ### New Contributors
117 |
118 | * @acip made their first contribution in https://github.com/spatie/laravel-schedule-monitor/pull/111
119 | * @faustbrian made their first contribution in https://github.com/spatie/laravel-schedule-monitor/pull/112
120 |
121 | **Full Changelog**: https://github.com/spatie/laravel-schedule-monitor/compare/3.7.1...3.8.0
122 |
123 | ## 3.7.1 - 2024-03-28
124 |
125 | ### What's Changed
126 |
127 | * Fix wrong lastRunFinishedTooLate behaviour when lastStartedAt and lastFinishedAt are within a second because of a very fast task by @mathiasmoser in https://github.com/spatie/laravel-schedule-monitor/pull/109
128 |
129 | ### New Contributors
130 |
131 | * @mathiasmoser made their first contribution in https://github.com/spatie/laravel-schedule-monitor/pull/109
132 |
133 | **Full Changelog**: https://github.com/spatie/laravel-schedule-monitor/compare/3.7.0...3.7.1
134 |
135 | ## 3.7.0 - 2024-03-02
136 |
137 | ### What's Changed
138 |
139 | * Laravel 11.x Compatibility by @laravel-shift in https://github.com/spatie/laravel-schedule-monitor/pull/106
140 |
141 | ### New Contributors
142 |
143 | * @laravel-shift made their first contribution in https://github.com/spatie/laravel-schedule-monitor/pull/106
144 |
145 | **Full Changelog**: https://github.com/spatie/laravel-schedule-monitor/compare/3.6.0...3.7.0
146 |
147 | ## 3.6.0 - 2024-02-28
148 |
149 | ### What's Changed
150 |
151 | * New method runsInBackground() added in Spatie\ScheduleMonitor\Support\ScheduledTasks\Tasks\Task:class by @ravi289 in https://github.com/spatie/laravel-schedule-monitor/pull/105
152 |
153 | ### New Contributors
154 |
155 | * @ravi289 made their first contribution in https://github.com/spatie/laravel-schedule-monitor/pull/105
156 |
157 | **Full Changelog**: https://github.com/spatie/laravel-schedule-monitor/compare/3.5.0...3.6.0
158 |
159 | ## 3.5.0 - 2024-01-26
160 |
161 | ### What's Changed
162 |
163 | * Allow tasks to be monitored but not synced with oh dear by @oddvalue in https://github.com/spatie/laravel-schedule-monitor/pull/102
164 |
165 | ### New Contributors
166 |
167 | * @oddvalue made their first contribution in https://github.com/spatie/laravel-schedule-monitor/pull/102
168 |
169 | **Full Changelog**: https://github.com/spatie/laravel-schedule-monitor/compare/3.4.3...3.5.0
170 |
171 | ## 3.4.3 - 2024-01-19
172 |
173 | ### What's Changed
174 |
175 | * Update nunomaduro/termwind to 2.0 by @yoeriboven in https://github.com/spatie/laravel-schedule-monitor/pull/99
176 |
177 | **Full Changelog**: https://github.com/spatie/laravel-schedule-monitor/compare/3.4.2...3.4.3
178 |
179 | ## 3.4.2 - 2023-12-14
180 |
181 | ### What's Changed
182 |
183 | * fix: PHP warning about creation of dynamic properties by @Pr3d4dor in https://github.com/spatie/laravel-schedule-monitor/pull/98
184 |
185 | ### New Contributors
186 |
187 | * @Pr3d4dor made their first contribution in https://github.com/spatie/laravel-schedule-monitor/pull/98
188 |
189 | **Full Changelog**: https://github.com/spatie/laravel-schedule-monitor/compare/3.4.1...3.4.2
190 |
191 | ## 3.4.1 - 2023-11-29
192 |
193 | ### What's Changed
194 |
195 | * Update README.md by @robjbrain in https://github.com/spatie/laravel-schedule-monitor/pull/96
196 | * Update MonitoredScheduledTask.php to get the failed response to be st… by @AKHIL-882 in https://github.com/spatie/laravel-schedule-monitor/pull/97
197 |
198 | ### New Contributors
199 |
200 | * @robjbrain made their first contribution in https://github.com/spatie/laravel-schedule-monitor/pull/96
201 | * @AKHIL-882 made their first contribution in https://github.com/spatie/laravel-schedule-monitor/pull/97
202 |
203 | **Full Changelog**: https://github.com/spatie/laravel-schedule-monitor/compare/3.4.0...3.4.1
204 |
205 | ## 3.4.0 - 2023-08-01
206 |
207 | ### What's Changed
208 |
209 | - Add note that syncing will remove other monitors by @keithbrink in https://github.com/spatie/laravel-schedule-monitor/pull/90
210 | - Fix anchor in link to Laravel docs by @limenet in https://github.com/spatie/laravel-schedule-monitor/pull/92
211 | - Non destructive sync option (keep-old) by @keithbrink in https://github.com/spatie/laravel-schedule-monitor/pull/91
212 |
213 | ### New Contributors
214 |
215 | - @keithbrink made their first contribution in https://github.com/spatie/laravel-schedule-monitor/pull/90
216 | - @limenet made their first contribution in https://github.com/spatie/laravel-schedule-monitor/pull/92
217 |
218 | **Full Changelog**: https://github.com/spatie/laravel-schedule-monitor/compare/3.3.0...3.4.0
219 |
220 | ## 3.3.0 - 2023-05-24
221 |
222 | ### What's Changed
223 |
224 | - Add a boolean parameter to the doNotMonitor function by @bilfeldt in https://github.com/spatie/laravel-schedule-monitor/pull/88
225 |
226 | **Full Changelog**: https://github.com/spatie/laravel-schedule-monitor/compare/3.2.1...3.3.0
227 |
228 | ## 3.2.1 - 2023-02-01
229 |
230 | - fix silent by default
231 |
232 | ## 3.2.0 - 2023-02-01
233 |
234 | - silence jobs by default
235 |
236 | **Full Changelog**: https://github.com/spatie/laravel-schedule-monitor/compare/3.1.1...3.2.0
237 |
238 | ## 3.1.1 - 2023-01-23
239 |
240 | - support L10
241 |
242 | ## 3.0.4 - 2022-10-02
243 |
244 | - update deps
245 |
246 | **Full Changelog**: https://github.com/spatie/laravel-schedule-monitor/compare/3.0.3...3.0.4
247 |
248 | ## 3.0.3 - 2022-05-13
249 |
250 | ## What's Changed
251 |
252 | - fix: Use `flex` and `content-repeat` on Termwind outputs. by @xiCO2k in https://github.com/spatie/laravel-schedule-monitor/pull/76
253 |
254 | **Full Changelog**: https://github.com/spatie/laravel-schedule-monitor/compare/3.0.2...3.0.3
255 |
256 | ## 3.0.2 - 2022-05-05
257 |
258 | ## What's Changed
259 |
260 | - Update readme about model pruning by @patrickbrouwers in https://github.com/spatie/laravel-schedule-monitor/pull/71
261 | - PHPUnit to Pest Converter by @freekmurze in https://github.com/spatie/laravel-schedule-monitor/pull/73
262 | - chore: add multitenancy documentation by @ju5t in https://github.com/spatie/laravel-schedule-monitor/pull/75
263 | - Add Termwind to improve the Command Outputs. by @xiCO2k in https://github.com/spatie/laravel-schedule-monitor/pull/74
264 |
265 | ## New Contributors
266 |
267 | - @ju5t made their first contribution in https://github.com/spatie/laravel-schedule-monitor/pull/75
268 | - @xiCO2k made their first contribution in https://github.com/spatie/laravel-schedule-monitor/pull/74
269 |
270 | **Full Changelog**: https://github.com/spatie/laravel-schedule-monitor/compare/3.0.1...3.0.2
271 |
272 | ## 3.0.1 - 2022-02-13
273 |
274 | ## What's Changed
275 |
276 | - Fix return type by @SamuelNitsche in https://github.com/spatie/laravel-schedule-monitor/pull/70
277 |
278 | ## New Contributors
279 |
280 | - @SamuelNitsche made their first contribution in https://github.com/spatie/laravel-schedule-monitor/pull/70
281 |
282 | **Full Changelog**: https://github.com/spatie/laravel-schedule-monitor/compare/3.0.0...3.0.1
283 |
284 | ## 3.0.0 - 2022-01-14
285 |
286 | - Support Laravel 9
287 |
288 | ## 2.4.7 - 2021-11-17
289 |
290 | ## What's Changed
291 |
292 | - Update lorisleiva/cron-translator to version 0.3 by @bilfeldt in https://github.com/spatie/laravel-schedule-monitor/pull/67
293 |
294 | ## New Contributors
295 |
296 | - @bilfeldt made their first contribution in https://github.com/spatie/laravel-schedule-monitor/pull/67
297 |
298 | **Full Changelog**: https://github.com/spatie/laravel-schedule-monitor/compare/2.4.6...2.4.7
299 |
300 | ## 2.4.6 - 2021-11-02
301 |
302 | - Make sure retryUntil is returning a DateTime (#66)
303 |
304 | ## 2.4.5 - 2021-09-16
305 |
306 | - take environments property into account for scheduled tasks (#64)
307 |
308 | ## 2.4.4 - 2021-09-07
309 |
310 | - add `retryUntil` for PingOhdearJobs (#63)
311 |
312 | ## 2.4.3 - 2021-08-02
313 |
314 | - automatically retry ping if OhDear had downtime (#54)
315 |
316 | ## 2.4.2 - 2021-07-22
317 |
318 | - add link to docs
319 |
320 | ## 2.4.1 - 2021-06-15
321 |
322 | - update user API token url (#50)
323 |
324 | ## 2.4.0 - 2021-06-10
325 |
326 | - enable custom models
327 |
328 | ## 2.3.0 - 2021-05-13
329 |
330 | - add `storeOutputInDb`
331 |
332 | ## 2.2.1 - 2021-03-29
333 |
334 | - upgrade to latest lorisleiva/cron-translator version (#40)
335 |
336 | ## 2.2.0 - 2021-01-15
337 |
338 | - throw an exception if pinging Oh Dear has failed [#37](https://github.com/spatie/laravel-schedule-monitor/pull/37)
339 | - pass 0 instead of null parameters to Oh dear for Background tasks [#37](https://github.com/spatie/laravel-schedule-monitor/pull/37)
340 |
341 | ## 2.1.0 - 2020-12-04
342 |
343 | - add support for PHP 8
344 |
345 | ## 2.0.2 - 2020-10-14
346 |
347 | - drop support for Laravel 7
348 | - fix command description
349 |
350 | ## 2.0.1 - 2020-10-06
351 |
352 | - report right exit code for scheduled tasks in background
353 |
354 | ## 2.0.0 - 2020-09-29
355 |
356 | - add support for timezones
357 |
358 | ## 1.0.4 - 2020-09-08
359 |
360 | - add support for Laravel 8
361 |
362 | ## 1.0.3 - 2020-07-14
363 |
364 | - fix link config file
365 |
366 | ## 1.0.2 - 2020-07-14
367 |
368 | - add `CarbonImmutable` support (#3)
369 |
370 | ## 1.0.1 - 2020-07-12
371 |
372 | - improve output of commands
373 |
374 | ## 1.0.0 - 2020-07-09
375 |
376 | - initial release
377 |
--------------------------------------------------------------------------------
/LICENSE.md:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) Immutable
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in
13 | all copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21 | THE SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Monitor scheduled tasks in a Laravel app
2 |
3 | [](https://packagist.org/packages/spatie/laravel-schedule-monitor)
4 | [](https://packagist.org/packages/spatie/laravel-schedule-monitor)
5 |
6 | This package will monitor your Laravel schedule. It will write an entry to a log table in the db each time a schedule tasks starts, end, fails or is skipped. Using the `list` command you can check when the scheduled tasks have been executed.
7 |
8 | 
9 |
10 | This package can also sync your schedule with [Oh Dear](https://ohdear.app). Oh Dear will send you a notification whenever a scheduled task doesn't run on time or fails.
11 |
12 | ## Support us
13 |
14 | [](https://spatie.be/github-ad-click/laravel-schedule-monitor)
15 |
16 | We invest a lot of resources into creating [best in class open source packages](https://spatie.be/open-source). You can support us by [buying one of our paid products](https://spatie.be/open-source/support-us).
17 |
18 | We highly appreciate you sending us a postcard from your hometown, mentioning which of our package(s) you are using. You'll find our address on [our contact page](https://spatie.be/about-us). We publish all received postcards on [our virtual postcard wall](https://spatie.be/open-source/postcards).
19 |
20 | ## Installation
21 |
22 | You can install the package via composer:
23 |
24 | ```bash
25 | composer require spatie/laravel-schedule-monitor
26 | ```
27 |
28 | If you need Laravel 8 support, you can install v2 of the package using `composer require spatie/laravel-schedule-monitor:^2`.
29 |
30 | #### Preparing the database
31 |
32 | You must publish and run migrations:
33 |
34 | ```bash
35 | php artisan vendor:publish --provider="Spatie\ScheduleMonitor\ScheduleMonitorServiceProvider" --tag="schedule-monitor-migrations"
36 | php artisan migrate
37 | ```
38 |
39 | #### Publishing the config file
40 |
41 | You can publish the config file with:
42 | ```bash
43 | php artisan vendor:publish --provider="Spatie\ScheduleMonitor\ScheduleMonitorServiceProvider" --tag="schedule-monitor-config"
44 | ```
45 |
46 | This is the contents of the published config file:
47 |
48 | ```php
49 | return [
50 | /*
51 | * The schedule monitor will log each start, finish and failure of all scheduled jobs.
52 | * After a while the `monitored_scheduled_task_log_items` might become big.
53 | * Here you can specify the amount of days log items should be kept.
54 | *
55 | * Use Laravel's pruning command to delete old `MonitoredScheduledTaskLogItem` models.
56 | * More info: https://laravel.com/docs/9.x/eloquent#mass-assignment
57 | */
58 | 'delete_log_items_older_than_days' => 30,
59 |
60 | /*
61 | * The date format used for all dates displayed on the output of commands
62 | * provided by this package.
63 | */
64 | 'date_format' => 'Y-m-d H:i:s',
65 |
66 | 'models' => [
67 | /*
68 | * The model you want to use as a MonitoredScheduledTask model needs to extend the
69 | * `Spatie\ScheduleMonitor\Models\MonitoredScheduledTask` Model.
70 | */
71 | 'monitored_scheduled_task' => Spatie\ScheduleMonitor\Models\MonitoredScheduledTask::class,
72 |
73 | /*
74 | * The model you want to use as a MonitoredScheduledTaskLogItem model needs to extend the
75 | * `Spatie\ScheduleMonitor\Models\MonitoredScheduledTaskLogItem` Model.
76 | */
77 | 'monitored_scheduled_log_item' => Spatie\ScheduleMonitor\Models\MonitoredScheduledTaskLogItem::class,
78 | ],
79 |
80 | /*
81 | * Oh Dear can notify you via Mail, Slack, SMS, web hooks, ... when a
82 | * scheduled task does not run on time.
83 | *
84 | * More info: https://ohdear.app/cron-checks
85 | */
86 | 'oh_dear' => [
87 | /*
88 | * You can generate an API token at the Oh Dear user settings screen
89 | *
90 | * https://ohdear.app/user/api-tokens
91 | */
92 | 'api_token' => env('OH_DEAR_API_TOKEN', ''),
93 |
94 | /*
95 | * The id of the site you want to sync the schedule with.
96 | *
97 | * You'll find this id on the settings page of a site at Oh Dear.
98 | */
99 | 'site_id' => env('OH_DEAR_SITE_ID'),
100 |
101 | /*
102 | * To keep scheduled jobs as short as possible, Oh Dear will be pinged
103 | * via a queued job. Here you can specify the name of the queue you wish to use.
104 | */
105 | 'queue' => env('OH_DEAR_QUEUE'),
106 |
107 | /*
108 | * `PingOhDearJob`s will automatically be skipped if they've been queued for
109 | * longer than the time configured here.
110 | */
111 | 'retry_job_for_minutes' => 10,
112 | ],
113 | ];
114 | ```
115 |
116 | #### Cleaning the database
117 |
118 | The schedule monitor will log each start, finish and failure of all scheduled jobs. After a while the `monitored_scheduled_task_log_items` might become big.
119 |
120 | Use [Laravel's model pruning feature](https://laravel.com/docs/9.x/eloquent#pruning-models) , you can delete old `MonitoredScheduledTaskLogItem` models. Models older than the amount of days configured in the `delete_log_items_older_than_days` in the `schedule-monitor` config file, will be deleted.
121 |
122 | ```php
123 | // app/Console/Kernel.php
124 |
125 | use Spatie\ScheduleMonitor\Models\MonitoredScheduledTaskLogItem;
126 |
127 | class Kernel extends ConsoleKernel
128 | {
129 | protected function schedule(Schedule $schedule)
130 | {
131 | $schedule->command('model:prune', ['--model' => MonitoredScheduledTaskLogItem::class])->daily();
132 | }
133 | }
134 | ```
135 |
136 | #### Syncing the schedule
137 |
138 | Every time you deploy your application, you should execute the `schedule-monitor:sync` command
139 |
140 | ```bash
141 | php artisan schedule-monitor:sync
142 | ```
143 |
144 | This command is responsible for syncing your schedule with the database, and optionally Oh Dear. We highly recommend adding this command to the script that deploys your production environment.
145 |
146 | In a non-production environment you should manually run `schedule-monitor:sync`. You can verify if everything synced correctly using `schedule-monitor:list`.
147 |
148 | **Note:** Running the sync command will remove any other cron monitors that you've defined other than the application schedule.
149 |
150 | If you would like to use non-destructive syncs to Oh Dear so that you can monitor other cron tasks outside of Laravel, you can use the `--keep-old` flag. This will only push new tasks to Oh Dear, rather than a full sync. Note that this will not remove any tasks from Oh Dear that are no longer in your schedule.
151 |
152 | ## Usage
153 |
154 | To monitor your schedule you should first run `schedule-monitor:sync`. This command will take a look at your schedule and create an entry for each task in the `monitored_scheduled_tasks` table.
155 |
156 | 
157 |
158 | To view all monitored scheduled tasks, you can run `schedule-monitor:list`. This command will list all monitored scheduled tasks. It will show you when a scheduled task has last started, finished, or failed.
159 |
160 | 
161 |
162 | The package will write an entry to the `monitored_scheduled_task_log_items` table in the db each time a schedule tasks starts, end, fails or is skipped. Take a look at the contents of that table if you want to know when and how scheduled tasks did execute. The log items also hold other interesting metrics like memory usage, execution time, and more.
163 |
164 | ### Naming tasks
165 |
166 | Schedule monitor will try to automatically determine a name for a scheduled task. For commands this is the command name, for anonymous jobs the class name of the first argument will be used. For some tasks, like scheduled closures, a name cannot be determined automatically.
167 |
168 | To manually set a name of the scheduled task, you can tack on `monitorName()`.
169 |
170 | Here's an example.
171 |
172 | ```php
173 | // in app/Console/Kernel.php
174 |
175 | protected function schedule(Schedule $schedule)
176 | {
177 | $schedule->command('your-command')->daily()->monitorName('a-custom-name');
178 | $schedule->call(fn () => 1 + 1)->hourly()->monitorName('addition-closure');
179 | }
180 | ```
181 |
182 | When you change the name of task, the schedule monitor will remove all log items of the monitor with the old name, and create a new monitor using the new name of the task.
183 |
184 | ### Setting a grace time
185 |
186 | When the package detects that the last run of a scheduled task did not run in time, the `schedule-monitor` list will display that task using a red background color. In this screenshot the task named `your-command` ran too late.
187 |
188 | 
189 |
190 | The package will determine that a task ran too late if it was not finished at the time it was supposed to run + the grace time. You can think of the grace time as the number of minutes that a task under normal circumstances needs to finish. By default, the package grants a grace time of 5 minutes to each task.
191 |
192 | You can customize the grace time by using the `graceTimeInMinutes` method on a task. In this example a grace time of 10 minutes is used for the `your-command` task.
193 |
194 | ```php
195 | // in app/Console/Kernel.php
196 |
197 | protected function schedule(Schedule $schedule)
198 | {
199 | $schedule->command('your-command')->daily()->graceTimeInMinutes(10);
200 | }
201 | ```
202 |
203 | ### Ignoring scheduled tasks
204 |
205 | You can avoid a scheduled task being monitored by tacking on `doNotMonitor` when scheduling the task.
206 |
207 | ```php
208 | // in app/Console/Kernel.php
209 |
210 | protected function schedule(Schedule $schedule)
211 | {
212 | $schedule->command('your-command')->daily()->doNotMonitor();
213 | }
214 | ```
215 |
216 | ### Storing output in the database
217 |
218 | You can store the output by tacking on `storeOutputInDb` when scheduling the task.
219 |
220 | ```php
221 | // in app/Console/Kernel.php
222 |
223 | protected function schedule(Schedule $schedule)
224 | {
225 | $schedule->command('your-command')->daily()->storeOutputInDb();
226 | }
227 | ```
228 |
229 | The output will be stored in the `monitored_scheduled_task_log_items` table, in the `output` key of the `meta` column.
230 |
231 | ### Multitenancy
232 |
233 | If you're using [spatie/laravel-multitenancy](https://github.com/spatie/laravel-multitenancy) you should add the `PingOhDearJob` to
234 | the `not_tenant_aware_jobs` array in `config/multitenancy.php`.
235 |
236 | ```php
237 | 'not_tenant_aware_jobs' => [
238 | // ...
239 | \Spatie\ScheduleMonitor\Jobs\PingOhDearJob::class,
240 | ]
241 | ```
242 |
243 | Without it, the `PingOhDearJob` will fail as no tenant will be set.
244 |
245 | ### Getting notified when a scheduled task doesn't finish in time
246 |
247 | This package can sync your schedule with the [Oh Dear](https://ohdear.app) cron check. Oh Dear will send you a notification whenever a scheduled task does not finish on time.
248 |
249 | To get started you will first need to install the Oh Dear SDK.
250 |
251 | ```bash
252 | composer require ohdearapp/ohdear-php-sdk
253 | ```
254 |
255 | Next you, need to make sure the `api_token` and `site_id` keys of the `schedule-monitor` are filled with an API token, and an Oh Dear site id. To verify that these values hold correct values you can run this command.
256 |
257 | ```bash
258 | php artisan schedule-monitor:verify
259 | ```
260 |
261 | 
262 |
263 | To sync your schedule with Oh Dear run this command:
264 |
265 | ```bash
266 | php artisan schedule-monitor:sync
267 | ```
268 |
269 | 
270 |
271 | After that, the `list` command should show that all the scheduled tasks in your app are registered on Oh Dear.
272 |
273 | 
274 |
275 | To keep scheduled jobs as short as possible, Oh Dear will be pinged via queued jobs. To ensure speedy delivery to Oh Dear, and to avoid false positive notifications, we highly recommend creating a dedicated queue for these jobs. You can put the name of that queue in the `queue` key of the config file.
276 |
277 | Oh Dear will wait for the completion of a schedule tasks for a given amount of minutes. This is called the grace time. By default, all scheduled tasks will have a grace time of 5 minutes. To customize this value, you can tack on `graceTimeInMinutes` to your scheduled tasks.
278 |
279 | Here's an example where Oh Dear will send a notification if the task didn't finish by 00:10.
280 |
281 | ```php
282 | // in app/Console/Kernel.php
283 |
284 | protected function schedule(Schedule $schedule)
285 | {
286 | $schedule->command('your-command')->daily()->graceTimeInMinutes(10);
287 | }
288 | ```
289 |
290 | ### Disabling Oh Dear for individual tasks
291 |
292 | If you want to have a task monitored by the schedule monitor, but not by Oh Dear, you can tack on `doMonitorAtOhDear` to your scheduled tasks.
293 |
294 | ```php
295 | // in app/Console/Kernel.php
296 |
297 | protected function schedule(Schedule $schedule)
298 | {
299 | $schedule->command('your-command')->daily()->doNotMonitorAtOhDear();
300 | }
301 | ```
302 |
303 | ## Unsupported methods
304 |
305 | Currently, this package does not work for tasks that use these methods:
306 |
307 | - `between`
308 | - `unlessBetween`
309 | - `when`
310 | - `skip`
311 |
312 | ## Third party scheduled task monitors
313 |
314 | We assume that, when your scheduled tasks do not run properly, a scheduled task that sends out notifications would probably not run either. That's why this package doesn't send out notifications by itself.
315 |
316 | These services can notify you when scheduled tasks do not run properly:
317 |
318 | - [Oh Dear](https://ohdear.app)
319 | - [thenping.me](https://thenping.me)
320 | - [Healthchecks.io](https://healthchecks.io)
321 | - [Cronitor](https://cronitor.io)
322 | - [Cronhub](https://cronhub.io/)
323 | - [DeadMansSnitch](https://deadmanssnitch.com/)
324 | - [CronAlarm](https://www.cronalarm.com/)
325 | - [PushMon](https://www.pushmon.com/)
326 |
327 | ## Testing
328 |
329 | ``` bash
330 | composer test
331 | ```
332 |
333 | ## Changelog
334 |
335 | Please see [CHANGELOG](CHANGELOG.md) for more information on what has changed recently.
336 |
337 | ## Contributing
338 |
339 | Please see [CONTRIBUTING](https://github.com/spatie/.github/blob/main/CONTRIBUTING.md) for details.
340 |
341 | ## Security
342 |
343 | If you've found a bug regarding security please mail [security@spatie.be](mailto:security@spatie.be) instead of using the issue tracker.
344 |
345 | ## Credits
346 |
347 | - [Freek Van der Herten](https://github.com/freekmurze)
348 | - [All Contributors](../../contributors)
349 |
350 | ## License
351 |
352 | The MIT License (MIT). Please see [License File](LICENSE.md) for more information.
353 |
--------------------------------------------------------------------------------
/UPGRADING.md:
--------------------------------------------------------------------------------
1 | ## Upgrading
2 |
3 | ### From v2 to v3
4 |
5 | The `CleanCommand` has been removed. You can now use Laravel's pruning feature to [delete old log items](https://github.com/spatie/laravel-schedule-monitor#cleaning-the-database).
6 |
7 | ### From v1 to v2
8 |
9 | Add a column `timezone` (string, nullable) to the `monitored_scheduled_tasks` table. In existing rows you should fill to column with the timezone in your app.
10 |
--------------------------------------------------------------------------------
/composer.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "spatie/laravel-schedule-monitor",
3 | "description": "Monitor scheduled tasks in a Laravel app",
4 | "keywords": [
5 | "spatie",
6 | "laravel-schedule-monitor"
7 | ],
8 | "homepage": "https://github.com/spatie/laravel-schedule-monitor",
9 | "license": "MIT",
10 | "authors": [
11 | {
12 | "name": "Freek Van der Herten",
13 | "email": "freek@spatie.be",
14 | "homepage": "https://spatie.be",
15 | "role": "Developer"
16 | }
17 | ],
18 | "require": {
19 | "php": "^8.1",
20 | "illuminate/bus": "^9.0|^10.0|^11.0|^12.0",
21 | "lorisleiva/cron-translator": "^0.3.0|^0.4.0",
22 | "nesbot/carbon": "^2.63|^3.0",
23 | "nunomaduro/termwind": "^1.10.1|^2.0",
24 | "spatie/laravel-package-tools": "^1.9"
25 | },
26 | "require-dev": {
27 | "mockery/mockery": "^1.4",
28 | "ohdearapp/ohdear-php-sdk": "^3.0",
29 | "orchestra/testbench": "^7.0|^8.0|^9.0|^10.0",
30 | "pestphp/pest": "^1.20|^2.34|^3.7",
31 | "pestphp/pest-plugin-laravel": "^1.2|^2.3|^3.1",
32 | "spatie/pest-plugin-snapshots": "^1.1|^2.1",
33 | "spatie/phpunit-snapshot-assertions": "^4.2|^5.1",
34 | "spatie/test-time": "^1.2"
35 | },
36 | "suggest": {
37 | "ohdearapp/ohdear-php-sdk": "Needed to sync your schedule with Oh Dear"
38 | },
39 | "autoload": {
40 | "psr-4": {
41 | "Spatie\\ScheduleMonitor\\": "src",
42 | "Spatie\\ScheduleMonitor\\Database\\Factories\\": "database/factories"
43 | }
44 | },
45 | "autoload-dev": {
46 | "psr-4": {
47 | "Spatie\\ScheduleMonitor\\Tests\\": "tests"
48 | }
49 | },
50 | "scripts": {
51 | "test": "vendor/bin/pest",
52 | "test-coverage": "vendor/bin/phpunit --coverage-html coverage",
53 | "format": "vendor/bin/php-cs-fixer fix --allow-risky=yes"
54 | },
55 | "config": {
56 | "sort-packages": true,
57 | "allow-plugins": {
58 | "composer/package-versions-deprecated": true,
59 | "pestphp/pest-plugin": true
60 | }
61 | },
62 | "extra": {
63 | "laravel": {
64 | "providers": [
65 | "Spatie\\ScheduleMonitor\\ScheduleMonitorServiceProvider"
66 | ]
67 | }
68 | },
69 | "minimum-stability": "dev",
70 | "prefer-stable": true
71 | }
72 |
--------------------------------------------------------------------------------
/config/schedule-monitor.php:
--------------------------------------------------------------------------------
1 | 30,
13 |
14 | /*
15 | * The date format used for all dates displayed on the output of commands
16 | * provided by this package.
17 | */
18 | 'date_format' => 'Y-m-d H:i:s',
19 |
20 | 'models' => [
21 | /*
22 | * The model you want to use as a MonitoredScheduledTask model needs to extend the
23 | * `Spatie\ScheduleMonitor\Models\MonitoredScheduledTask` Model.
24 | */
25 | 'monitored_scheduled_task' => Spatie\ScheduleMonitor\Models\MonitoredScheduledTask::class,
26 |
27 | /*
28 | * The model you want to use as a MonitoredScheduledTaskLogItem model needs to extend the
29 | * `Spatie\ScheduleMonitor\Models\MonitoredScheduledTaskLogItem` Model.
30 | */
31 | 'monitored_scheduled_log_item' => Spatie\ScheduleMonitor\Models\MonitoredScheduledTaskLogItem::class,
32 | ],
33 |
34 | /*
35 | * Oh Dear can notify you via Mail, Slack, SMS, web hooks, ... when a
36 | * scheduled task does not run on time.
37 | *
38 | * More info: https://ohdear.app/docs/features/cron-job-monitoring
39 | */
40 | 'oh_dear' => [
41 | /*
42 | * You can generate an API token at the Oh Dear user settings screen
43 | *
44 | * https://ohdear.app/user/api-tokens
45 | */
46 | 'api_token' => env('OH_DEAR_API_TOKEN', ''),
47 |
48 | /*
49 | * The id of the site you want to sync the schedule with.
50 | *
51 | * You'll find this id on the settings page of a site at Oh Dear.
52 | */
53 | 'site_id' => env('OH_DEAR_SITE_ID'),
54 |
55 | /*
56 | * To keep scheduled jobs as short as possible, Oh Dear will be pinged
57 | * via a queued job. Here you can specify the name of the queue you wish to use.
58 | */
59 | 'queue' => env('OH_DEAR_QUEUE'),
60 |
61 | /*
62 | * `PingOhDearJob`s will automatically be skipped if they've been queued for
63 | * longer than the time configured here.
64 | */
65 | 'retry_job_for_minutes' => 10,
66 |
67 | /*
68 | * When set to true, we will automatically add the `PingOhDearJob` to Horizon's
69 | * silenced jobs.
70 | */
71 | 'silence_ping_oh_dear_job_in_horizon' => true,
72 |
73 | /*
74 | * Send the start of a scheduled job to Oh Dear. This is not needed
75 | * for notifications to work correctly.
76 | */
77 | 'send_starting_ping' => env('OH_DEAR_SEND_STARTING_PING', false),
78 |
79 | /**
80 | * The amount of minutes a scheduled task is allowed to run before it is
81 | * considered late.
82 | */
83 | 'grace_time_in_minutes' => 5,
84 |
85 | /**
86 | * Which endpoint to ping on Oh Dear.
87 | */
88 | 'endpoint_url' => env('OH_DEAR_PING_ENDPOINT_URL'),
89 |
90 | /**
91 | * The URL of the Oh Dear API.
92 | */
93 | 'api_url' => env('OH_DEAR_API_URL', 'https://ohdear.app/api/'),
94 | ],
95 | ];
96 |
--------------------------------------------------------------------------------
/database/factories/MonitoredScheduledTaskFactory.php:
--------------------------------------------------------------------------------
1 | $this->faker->name,
16 | 'type' => $this->faker->randomElement(['command', 'shell', 'job', 'closure']),
17 | 'cron_expression' => '* * * * *',
18 | 'grace_time_in_minutes' => 5,
19 | ];
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/database/factories/MonitoredScheduledTaskLogItemFactory.php:
--------------------------------------------------------------------------------
1 | MonitoredScheduledTask::factory(),
17 | 'type' => $this->faker->randomElement([
18 | MonitoredScheduledTaskLogItem::TYPE_STARTING,
19 | MonitoredScheduledTaskLogItem::TYPE_FINISHED,
20 | MonitoredScheduledTaskLogItem::TYPE_SKIPPED,
21 | ]),
22 | 'meta' => [],
23 | ];
24 | }
25 |
26 | public function configure()
27 | {
28 | return $this->afterMaking(function(MonitoredScheduledTaskLogItem $logItem) {
29 | $scheduledTask = $logItem->monitoredScheduledTask;
30 |
31 | $scheduledTask->ping_url = config('schedule-monitor.oh_dear.endpoint_url', 'https://ping.ohdear.app');
32 | $scheduledTask->save();
33 |
34 | return $logItem;
35 | });
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/database/migrations/create_schedule_monitor_tables.php.stub:
--------------------------------------------------------------------------------
1 | bigIncrements('id');
13 |
14 | $table->string('name');
15 | $table->string('type')->nullable();
16 | $table->string('cron_expression');
17 | $table->string('timezone')->nullable();
18 | $table->string('ping_url')->nullable();
19 |
20 | $table->dateTime('last_started_at')->nullable();
21 | $table->dateTime('last_finished_at')->nullable();
22 | $table->dateTime('last_failed_at')->nullable();
23 | $table->dateTime('last_skipped_at')->nullable();
24 |
25 | $table->dateTime('registered_on_oh_dear_at')->nullable();
26 | $table->dateTime('last_pinged_at')->nullable();
27 | $table->integer('grace_time_in_minutes');
28 |
29 | $table->timestamps();
30 | });
31 |
32 |
33 | Schema::create('monitored_scheduled_task_log_items', function (Blueprint $table) {
34 | $table->bigIncrements('id');
35 |
36 | $table->unsignedBigInteger('monitored_scheduled_task_id');
37 | $table
38 | ->foreign('monitored_scheduled_task_id', 'fk_scheduled_task_id')
39 | ->references('id')
40 | ->on('monitored_scheduled_tasks')
41 | ->cascadeOnDelete();
42 |
43 | $table->string('type');
44 |
45 | $table->json('meta')->nullable();
46 |
47 | $table->timestamps();
48 | });
49 | }
50 | }
51 |
--------------------------------------------------------------------------------
/resources/views/alert.blade.php:
--------------------------------------------------------------------------------
1 |