QueueKeeperCheck (queue_keeper_check v0.2.1)

Copy Markdown View Source

Read-only health check for Oban queues.

report = QueueKeeperCheck.run(MyApp.Repo)
IO.puts(QueueKeeperCheck.format(report))

Detects eight conditions (see checks/0 and QueueKeeperCheck.Config for thresholds):

  • :orphaned - jobs executing far longer than any job should run (execution age only; possibly orphaned by a node crash)
  • :hanging - jobs executing past their per-worker time budget
  • :backlog - too many due jobs, or the oldest due job waiting too long, per queue
  • :stalled - due jobs waiting and nothing in that queue attempted recently (queue stopped, or every slot busy with long-running jobs)
  • :retry_storm - many jobs of one worker failed and awaiting retry, or retried, within a short window
  • :discarded - spike of discarded jobs (silent failures)
  • :cancelled - spike of cancelled jobs
  • :cron_missing - an expected (cron) worker has had no job inserted for too long; opt-in via cron_missing: [expected: %{"MyApp.Nightly" => 90_000}]

Options: any check name with a keyword list of thresholds, plus

Invalid options raise ArgumentError. Database errors never raise: each check runs on its own, and a check that fails (timeout, missing table or column, connection error) is reported in report.errors with status :error (unless a finding is :critical). After a connection error the remaining checks are skipped.

Summary

Functions

All check names, in the order they run.

Plain-text rendering, one line per finding or error. Queue and worker names come from the database, so control and invisible formatting characters (including newlines and bidirectional overrides) are replaced with ?: a crafted name cannot forge extra lines or reorder text in a terminal or log.

Run the checks against repo and return a QueueKeeperCheck.Report.

Build (but do not send) a Slack incoming-webhook payload. Post it with your own HTTP client, e.g. Req.post!(webhook_url, json: QueueKeeperCheck.slack_payload(report)). &, < and > are escaped as Slack requires, so a queue or worker name cannot inject <!channel> mentions or links.

Functions

checks()

All check names, in the order they run.

format(r)

Plain-text rendering, one line per finding or error. Queue and worker names come from the database, so control and invisible formatting characters (including newlines and bidirectional overrides) are replaced with ?: a crafted name cannot forge extra lines or reorder text in a terminal or log.

run(repo, opts \\ [])

Run the checks against repo and return a QueueKeeperCheck.Report.

slack_payload(r)

Build (but do not send) a Slack incoming-webhook payload. Post it with your own HTTP client, e.g. Req.post!(webhook_url, json: QueueKeeperCheck.slack_payload(report)). &, < and > are escaped as Slack requires, so a queue or worker name cannot inject <!channel> mentions or links.