Alert Rules
Evaluate JSON ping payloads with field-level rules to catch silent failures automatically.
Overview
Alert Rules let you define conditions that Cronping evaluates against JSON ping payloads. A job that pings "success" but reports rows_processed=0 is a silent failure — the most common false positive in cron monitoring. Alert rules catch these automatically.
Each heartbeat can have up to 20 rules. When a success ping arrives with a JSON body, Cronping parses it and checks every rule. If a rule matches, it either marks the heartbeat as Down (fail action) or logs a warning (warn action).
How it works
- Your job sends a
POSTping with a JSON body:
curl -fsS -m 10 https://ping.cronping.com/<token> \
-H "Content-Type: application/json" \
-d '{"rows_processed": 0, "file_size_bytes": 204800, "duration_ms": 120}'-
Cronping records the ping as "success" and then evaluates all configured alert rules against the JSON payload.
-
If any rule with action Fail matches, Cronping overrides the success and treats the ping as a failure — the heartbeat goes Down and alerts fire immediately.
-
If rules with action Warn match (but no fail rules), Cronping logs the warning but keeps the heartbeat Up.
Configuring rules
Navigate to your heartbeat's edit page and scroll to the Alert Rules section.
Each rule has four fields:
| Field | Description | Example |
|---|---|---|
| Field | JSON field path (dot-notation for nested objects) | rows_processed |
| Operator | Comparison operator | <= |
| Value | Expected value to compare against | 0 |
| Action | What to do when the rule matches: Fail or Warn | fail |
Supported operators
| Operator | Symbol | Works with | Example |
|---|---|---|---|
| Equals | == | strings, numbers | status == error |
| Not equals | != | strings, numbers | status != ok |
| Greater than | > | numbers | duration_ms > 60000 |
| Greater or equal | >= | numbers | file_size_bytes >= 1024 |
| Less than | < | numbers | rows_processed < 1 |
| Less or equal | <= | numbers | error_count <= 5 |
| Contains | — | strings | message contains timeout |
| Not contains | — | strings | output not contains ERROR |
Actions
| Action | Effect |
|---|---|
| Fail | Mark heartbeat as Down and trigger alerts immediately |
| Warn | Log warning in the system — heartbeat stays Up |
Nested fields
Alert rules support dot-notation to access nested JSON objects. For example, given this payload:
{
"backup": {
"size": 0,
"tables": 12,
"status": "completed"
},
"duration_ms": 4500
}You can create a rule with field backup.size and operator < with value 1 to catch empty backups.
Rule evaluation behavior
- JSON only — Rules are only evaluated when the ping body is valid JSON. Plain text or empty bodies are silently skipped.
- Missing fields — If a field referenced by a rule doesn't exist in the payload, the rule is skipped (not treated as a violation).
- Success pings only — Rules are evaluated on success pings (including exit code
0). Fail pings and start pings are not evaluated since they already have explicit status. - Multiple rules — All rules are evaluated. If multiple fail rules match, the heartbeat is marked down once with all violation details included in the alert.
- Numeric comparisons — For
>,>=,<,<=operators, both the actual value and the expected value must be valid numbers. Otherwise the comparison is skipped.
Alert messages
When rules trigger a failure, the alert notification includes the violation details:
[ALERT RULE VIOLATION]
• rows_processed < 1 (actual: 0) [fail]
• file_size_bytes >= 102400 (actual: 204800) [warn]
--- Original payload ---
{"rows_processed": 0, "file_size_bytes": 204800, "duration_ms": 120}This information appears in all notification channels — email, Slack, Discord, Teams, webhooks, PagerDuty, Telegram, and Incident.io — as part of the log excerpt.
Examples
Detect empty database backups
A backup job reports the number of rows exported:
ROWS=$(pg_dump mydb | wc -l)
curl -fsS -m 10 https://ping.cronping.com/<token> \
-d "{\"rows_processed\": $ROWS}"Rule: rows_processed < 1 → Fail
If the backup exports 0 rows, Cronping marks the heartbeat as Down and sends an alert.
Monitor file size thresholds
A report generation job includes the output file size:
SIZE=$(stat -f%z report.pdf 2>/dev/null || stat -c%s report.pdf)
curl -fsS -m 10 https://ping.cronping.com/<token> \
-d "{\"file_size_bytes\": $SIZE}"Rule: file_size_bytes < 1024 → Fail
Warn on slow execution
A data pipeline sends its execution time:
START=$(date +%s%3N)
python pipeline.py
END=$(date +%s%3N)
DURATION=$((END - START))
curl -fsS -m 10 https://ping.cronping.com/<token> \
-d "{\"duration_ms\": $DURATION, \"status\": \"ok\"}"Rule: duration_ms > 60000 → Warn
The heartbeat stays Up but the warning is logged. Use this to detect performance degradation before it becomes critical.
Check nested status fields
A complex job reports structured output:
curl -fsS -m 10 https://ping.cronping.com/<token> \
-H "Content-Type: application/json" \
-d '{"backup": {"status": "failed", "error": "disk full"}, "duration_ms": 120}'Rule: backup.status == failed → Fail
Overlap detection
In addition to alert rules, Cronping supports Overlap Detection — a separate feature that monitors for concurrent job executions.
When a heartbeat receives a /start ping while a previous run is still open (started but not finished), this is flagged as an overlap event. Two modes are available:
| Mode | Behavior |
|---|---|
| Off | Ignore overlapping runs (default) |
| Warn | Log the overlap event — heartbeat status is not affected |
| Fail | Treat as failure — heartbeat goes Down and alerts fire |
Configure overlap detection in the heartbeat edit form under Notifications → Overlap detection.
Use case
A nightly ETL job scheduled every 24 hours accidentally runs twice due to a cron misconfiguration:
curl -fsS -m 10 https://ping.cronping.com/<token>/startIf the previous run hasn't finished yet, Cronping detects the collision and acts based on the configured mode.
Log context in alerts
When an alert fires — whether from a missed ping, an explicit /fail, or a rule violation — Cronping automatically attaches the most recent log output to the notification.
The log excerpt is sourced from (in priority order):
- Body of the most recent
/failping - Body of the most recent
/logping - Body of the most recent success ping
The excerpt is truncated to 50 lines / 10 KB for readability. All notification channels include the log excerpt: email (monospace block), Slack (code block), Discord (field), Teams (monospace block), webhook (log_excerpt field), PagerDuty (custom_details), Telegram (code block), and Incident.io (metadata).
Sending log output with a ping
#!/bin/sh
OUTPUT=$(/usr/bin/backup.sh 2>&1)
EXIT_CODE=$?
curl -fsS -m 10 https://ping.cronping.com/<token>/$EXIT_CODE \
-X POST --data-raw "$OUTPUT"If the backup fails, the alert email will include the script output — no more SSH-ing in to find out what went wrong.