Skip to content

feat: silence detection – alert when jobs stop running entirely (v4.5.0) - #103

Merged
csoscd merged 1 commit into
mainfrom
feature/silence-detection
Jul 7, 2026
Merged

feat: silence detection – alert when jobs stop running entirely (v4.5.0)#103
csoscd merged 1 commit into
mainfrom
feature/silence-detection

Conversation

@csoscd

@csoscd csoscd commented Jul 7, 2026

Copy link
Copy Markdown
Owner

Summary

  • Silence Detection (opt-in per job): check-limits.php uses CronExpression::getPreviousRunDate() to detect when an active job has missed its scheduled start without leaving any execution_log entry. Alerts via Mail + Telegram.
  • Three maintenance-window guards prevent false positives: agent-wide maintenance, all-targets-in-maintenance, and last-row-was-sentinel (maintenance just ended).
  • Dedup: max 1 alert per hour per job (last_silence_alert_at); reset automatically when the job restarts.
  • GET /health extended with silent_jobs (int|null) and last_execution_at (string|null) for external monitors (UptimeKuma, Grafana).
  • REST API: notify_on_silence and silence_grace_minutes readable/writable on all job endpoints; last_silence_alert_at read-only.
  • Web UI: Silence-Alarm checkbox + optional grace-period input in the notifications tab.
  • DB migration: 016_silence_detection.sql adds 3 columns to cronjobs.

Affected files

File Change
agent/sql/migrations/016_silence_detection.sql NEW – 3 columns on cronjobs
agent/bin/check-limits.php New silence-detection loop with CronExpression + 3 MW guards
agent/bin/send-notification.php type = "silence" dispatch branch
agent/src/Notification/MailNotifier.php sendSilenceAlert() + amber HTML template
agent/src/Notification/TelegramNotifier.php sendSilenceAlert()
agent/src/Endpoints/ExecutionStartEndpoint.php Reset last_silence_alert_at = NULL on job start
agent/src/Endpoints/Cron{List,Get,Create,Update}Endpoint.php New fields in SQL + normaliseRow + validate
agent/agent.php /health extended with DB metrics
web/src/Controller/CronController.php New fields read/write
web/templates/cron/form.php Silence checkbox + grace field + JS toggle
web/lang/de.php + en.php 5 new translation keys
API.md Job object, POST/PUT body, changelog
agent/VERSION + web/VERSION → 4.5.0
CHANGELOG.md + README.md Updated

Test plan

  • Deploy migration 016_silence_detection.sql on target DB
  • Create a job with notify_on_silence = 1, let it become overdue → silence alert received via Mail + Telegram
  • Job starts again → last_silence_alert_at = NULL, no further alert
  • GET /health shows silent_jobs: 1 while overdue, 0 after recovery
  • silence_grace_minutes per job overrides global silence.grace_minutes
  • Job in maintenance window → no false-positive alert
  • REST API: notify_on_silence and silence_grace_minutes round-trip correctly

Adds per-job opt-in silence detection. check-limits.php now uses
CronExpression::getPreviousRunDate() to calculate the last expected
start time and alerts (mail + Telegram) when no real execution has
been recorded within the schedule interval plus a configurable grace
period.

Three maintenance-window guards prevent false positives:
- Guard 1: agent-wide maintenance window → skip entirely
- Guard 2: all job targets in maintenance → skip
- Guard 3: most recent execution_log row was a maintenance sentinel
  (exit_code = -4) → skip (maintenance just ended)

New job fields: notify_on_silence (bool, opt-in), silence_grace_minutes
(int|null, per-job override), last_silence_alert_at (system-managed,
reset by ExecutionStartEndpoint on next run, dedup: max 1 alert/hour).

GET /health extended with silent_jobs (count) and last_execution_at
(timestamp of most recent execution) for external monitoring.

REST API (GET/POST/PUT /api/v1/jobs): notify_on_silence and
silence_grace_minutes are readable and writable; last_silence_alert_at
is read-only.

Web UI: Silence-Alarm checkbox and optional grace-period field in the
notifications tab; grace field shown/hidden via JS.

DB migration: 016_silence_detection.sql adds three columns to cronjobs.
@csoscd
csoscd merged commit e44f93d into main Jul 7, 2026
9 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant