0
# Cron Monitoring
1
2
Scheduled job monitoring with automatic check-ins, failure detection, and alerting for cron jobs and scheduled tasks with support for various scheduling systems.
3
4
## Capabilities
5
6
### Monitor Decorator
7
8
Automatic monitoring for scheduled functions using a decorator that handles check-ins and failure detection.
9
10
```python { .api }
11
def monitor(
12
monitor_slug: str = None,
13
**monitor_config
14
) -> Callable:
15
"""
16
Decorator for automatic cron job monitoring.
17
18
Parameters:
19
- monitor_slug: Unique identifier for the monitor (auto-generated if None)
20
- **monitor_config: Monitor configuration options
21
22
Returns:
23
Callable: Decorator function that wraps the target function
24
"""
25
```
26
27
**Usage Examples:**
28
29
```python
30
import sentry_sdk
31
32
# Simple monitoring with auto-generated slug
33
@sentry_sdk.monitor
34
def daily_cleanup():
35
"""Daily cleanup job - monitored automatically."""
36
cleanup_temp_files()
37
remove_old_logs()
38
vacuum_database()
39
40
# Custom monitor slug and configuration
41
@sentry_sdk.monitor(
42
monitor_slug="hourly-data-sync",
43
schedule_type="crontab",
44
schedule="0 * * * *", # Every hour
45
checkin_margin=5, # 5 minute margin
46
max_runtime=1800, # 30 minute timeout
47
timezone="UTC"
48
)
49
def sync_data():
50
"""Hourly data synchronization job."""
51
fetch_external_data()
52
process_updates()
53
update_cache()
54
55
# Interval-based monitoring
56
@sentry_sdk.monitor(
57
monitor_slug="process-queue",
58
schedule_type="interval",
59
schedule={"value": 5, "unit": "minute"},
60
checkin_margin=2,
61
max_runtime=300
62
)
63
def process_message_queue():
64
"""Process message queue every 5 minutes."""
65
messages = get_pending_messages()
66
for message in messages:
67
process_message(message)
68
```
69
70
### Manual Check-ins
71
72
Manual control over monitor check-ins for complex scheduling scenarios or custom job runners.
73
74
```python { .api }
75
def capture_checkin(
76
monitor_slug: str = None,
77
check_in_id: str = None,
78
status: MonitorStatus = None,
79
duration: float = None,
80
**monitor_config
81
) -> str:
82
"""
83
Send a check-in for a cron monitor.
84
85
Parameters:
86
- monitor_slug: Unique monitor identifier
87
- check_in_id: Check-in ID for updating existing check-in
88
- status: Check-in status (ok, error, in_progress, timeout)
89
- duration: Job duration in seconds
90
- **monitor_config: Monitor configuration for auto-creation
91
92
Returns:
93
str: Check-in ID for future updates
94
"""
95
```
96
97
**Usage Examples:**
98
99
```python
100
import sentry_sdk
101
import time
102
103
def run_batch_job():
104
# Start check-in
105
check_in_id = sentry_sdk.capture_checkin(
106
monitor_slug="batch-processing",
107
status=sentry_sdk.MonitorStatus.IN_PROGRESS,
108
schedule_type="crontab",
109
schedule="0 2 * * *", # Daily at 2 AM
110
max_runtime=3600
111
)
112
113
start_time = time.time()
114
115
try:
116
# Run the actual job
117
process_daily_batch()
118
119
# Success check-in
120
duration = time.time() - start_time
121
sentry_sdk.capture_checkin(
122
monitor_slug="batch-processing",
123
check_in_id=check_in_id,
124
status=sentry_sdk.MonitorStatus.OK,
125
duration=duration
126
)
127
128
except Exception as e:
129
# Failure check-in
130
duration = time.time() - start_time
131
sentry_sdk.capture_checkin(
132
monitor_slug="batch-processing",
133
check_in_id=check_in_id,
134
status=sentry_sdk.MonitorStatus.ERROR,
135
duration=duration
136
)
137
raise
138
139
# Simple success check-in
140
def simple_job():
141
try:
142
perform_task()
143
sentry_sdk.capture_checkin(
144
monitor_slug="simple-task",
145
status=sentry_sdk.MonitorStatus.OK
146
)
147
except Exception:
148
sentry_sdk.capture_checkin(
149
monitor_slug="simple-task",
150
status=sentry_sdk.MonitorStatus.ERROR
151
)
152
raise
153
```
154
155
## Monitor Configuration
156
157
### Schedule Types
158
159
#### Crontab Schedule
160
161
```python
162
@sentry_sdk.monitor(
163
schedule_type="crontab",
164
schedule="0 0 * * *", # Daily at midnight
165
timezone="America/New_York"
166
)
167
def daily_report():
168
generate_daily_report()
169
```
170
171
#### Interval Schedule
172
173
```python
174
@sentry_sdk.monitor(
175
schedule_type="interval",
176
schedule={"value": 30, "unit": "minute"}, # Every 30 minutes
177
checkin_margin=5
178
)
179
def check_system_health():
180
monitor_system_metrics()
181
```
182
183
### Monitor Status Types
184
185
```python { .api }
186
class MonitorStatus:
187
OK = "ok" # Job completed successfully
188
ERROR = "error" # Job failed with an error
189
IN_PROGRESS = "in_progress" # Job is currently running
190
TIMEOUT = "timeout" # Job exceeded max_runtime
191
UNKNOWN = "unknown" # Unknown status
192
```
193
194
### Configuration Options
195
196
- **schedule_type**: "crontab" or "interval"
197
- **schedule**: Cron expression or interval object
198
- **timezone**: Timezone for schedule interpretation
199
- **checkin_margin**: Grace period in minutes for late jobs
200
- **max_runtime**: Maximum expected runtime in seconds
201
- **failure_issue_threshold**: Consecutive failures before alert
202
- **recovery_threshold**: Consecutive successes to clear alert
203
204
## Integration Examples
205
206
### Celery Beat Integration
207
208
```python
209
import sentry_sdk
210
from celery import Celery
211
from celery.schedules import crontab
212
213
app = Celery('tasks')
214
215
@app.task
216
@sentry_sdk.monitor(
217
monitor_slug="celery-cleanup",
218
schedule_type="crontab",
219
schedule="0 3 * * *",
220
timezone="UTC"
221
)
222
def cleanup_task():
223
"""Celery task with Sentry monitoring."""
224
cleanup_old_data()
225
return "Cleanup completed"
226
227
# Celery Beat configuration
228
app.conf.beat_schedule = {
229
'cleanup-task': {
230
'task': 'tasks.cleanup_task',
231
'schedule': crontab(hour=3, minute=0),
232
},
233
}
234
```
235
236
### APScheduler Integration
237
238
```python
239
import sentry_sdk
240
from apscheduler.schedulers.blocking import BlockingScheduler
241
242
scheduler = BlockingScheduler()
243
244
@sentry_sdk.monitor(
245
monitor_slug="apscheduler-job",
246
schedule_type="interval",
247
schedule={"value": 10, "unit": "minute"}
248
)
249
def scheduled_job():
250
"""APScheduler job with monitoring."""
251
process_pending_tasks()
252
253
scheduler.add_job(
254
func=scheduled_job,
255
trigger="interval",
256
minutes=10,
257
id='my_job'
258
)
259
260
scheduler.start()
261
```
262
263
### Crontab Integration
264
265
```bash
266
# System crontab entry
267
0 */6 * * * /usr/bin/python /path/to/monitored_script.py
268
```
269
270
```python
271
#!/usr/bin/env python
272
# monitored_script.py
273
import sentry_sdk
274
275
sentry_sdk.init(dsn="your-dsn-here")
276
277
@sentry_sdk.monitor(
278
monitor_slug="system-cron-job",
279
schedule_type="crontab",
280
schedule="0 */6 * * *", # Every 6 hours
281
max_runtime=1800
282
)
283
def main():
284
"""Script run by system cron."""
285
perform_maintenance_tasks()
286
287
if __name__ == "__main__":
288
main()
289
```
290
291
### Custom Job Runner Integration
292
293
```python
294
import sentry_sdk
295
import time
296
from datetime import datetime
297
298
class JobRunner:
299
def __init__(self):
300
self.jobs = []
301
302
def add_job(self, func, schedule, monitor_slug):
303
self.jobs.append({
304
'func': func,
305
'schedule': schedule,
306
'monitor_slug': monitor_slug,
307
'last_run': None
308
})
309
310
def run_job(self, job):
311
"""Run a single job with monitoring."""
312
monitor_slug = job['monitor_slug']
313
314
# Start check-in
315
check_in_id = sentry_sdk.capture_checkin(
316
monitor_slug=monitor_slug,
317
status=sentry_sdk.MonitorStatus.IN_PROGRESS
318
)
319
320
start_time = time.time()
321
322
try:
323
# Execute the job
324
job['func']()
325
job['last_run'] = datetime.now()
326
327
# Success check-in
328
duration = time.time() - start_time
329
sentry_sdk.capture_checkin(
330
monitor_slug=monitor_slug,
331
check_in_id=check_in_id,
332
status=sentry_sdk.MonitorStatus.OK,
333
duration=duration
334
)
335
336
except Exception as e:
337
# Error check-in
338
duration = time.time() - start_time
339
sentry_sdk.capture_checkin(
340
monitor_slug=monitor_slug,
341
check_in_id=check_in_id,
342
status=sentry_sdk.MonitorStatus.ERROR,
343
duration=duration
344
)
345
# Log error but continue with other jobs
346
print(f"Job {monitor_slug} failed: {e}")
347
348
# Usage
349
runner = JobRunner()
350
runner.add_job(
351
func=lambda: backup_database(),
352
schedule="0 2 * * *",
353
monitor_slug="nightly-backup"
354
)
355
```
356
357
## Error Handling and Recovery
358
359
### Automatic Error Detection
360
361
The monitor decorator automatically detects and reports:
362
- Unhandled exceptions as ERROR status
363
- Function execution time for performance tracking
364
- Missing check-ins for scheduled jobs
365
366
### Recovery Scenarios
367
368
```python
369
import sentry_sdk
370
import time
371
372
@sentry_sdk.monitor(
373
monitor_slug="resilient-job",
374
schedule_type="interval",
375
schedule={"value": 15, "unit": "minute"},
376
failure_issue_threshold=3, # Alert after 3 consecutive failures
377
recovery_threshold=2 # Clear alert after 2 consecutive successes
378
)
379
def resilient_job():
380
"""Job with retry logic and monitoring."""
381
max_retries = 3
382
383
for attempt in range(max_retries):
384
try:
385
perform_critical_operation()
386
return # Success
387
except Exception as e:
388
if attempt == max_retries - 1:
389
# Final attempt failed, let monitor record ERROR
390
raise
391
else:
392
# Retry after delay
393
time.sleep(30 * (attempt + 1))
394
```
395
396
## Best Practices
397
398
### Monitor Naming
399
400
Use descriptive, kebab-case monitor slugs:
401
- `daily-data-backup`
402
- `hourly-cache-refresh`
403
- `weekly-report-generation`
404
405
### Schedule Configuration
406
407
- Set appropriate `checkin_margin` for network delays
408
- Configure `max_runtime` based on historical job duration
409
- Use UTC timezone for consistency across environments
410
411
### Error Handling
412
413
- Always use try/catch blocks for critical jobs
414
- Implement retry logic for transient failures
415
- Send contextual information with check-ins
416
417
### Performance Monitoring
418
419
Monitor job performance trends:
420
- Track duration changes over time
421
- Set alerts for abnormal runtime increases
422
- Monitor resource usage during job execution
423
424
Cron monitoring provides comprehensive visibility into scheduled job health, enabling proactive maintenance and reliable automation workflows.