Alerting

Get told when a container dies, gets OOM-killed, or starts logging errors.

LogDeck already watches every container's events and log stream. Alert rules put that to use: they match on what LogDeck sees and POST a JSON payload to one webhook URL. Rules are managed under Settings → Alerts in the UI, or with logdeck alerts from the terminal.

Rule types

Event rules

Event rules watch container lifecycle events. Two are alertable:

  • die — the container exited. Only a non-zero exit code fires the rule; a clean exit (code 0) is not an alert condition. When the engine event arrives without an exit code, LogDeck inspects the container to find it.
  • oom — the container was killed by the OOM killer.

An OOM kill usually emits oom immediately followed by a die with code 137. For a rule that watches both, LogDeck counts that pair as one incident rather than alerting twice.

Log rules

Log rules match lines as they stream. A rule can set a minimum level, a regex pattern, or both — both must match:

  • Minimum level — matches any line at that level or more severe (TRACE, DEBUG, INFO, WARN, ERROR, FATAL, PANIC). Lines LogDeck cannot classify never pass a level filter.
  • Pattern — an RE2 regular expression, tested against the parsed message and the raw line.

Targeting

Every rule can be narrowed by hosts, container names (exact), and Compose projects. The dimensions are combined with AND; a dimension you leave empty matches everything. A rule with no targeting at all watches every container on every host.

Rate thresholds and cooldowns

A single stray error is rarely worth a notification. Two controls turn matches into alerts:

  • Threshold and window — fire only after N matches within W seconds ("5 errors in 60 seconds"). The window defaults to 60 seconds. A threshold of 0 or 1 fires on every match.
  • Cooldown — the minimum time between deliveries for the same rule and container. It defaults to 300 seconds when unset. Matches that occur during a cooldown are not thrown away: they are counted, and the next alert reports how many were suppressed.

Threshold and cooldown state is kept in memory, so it resets when LogDeck restarts.

The webhook

There is one webhook URL for the whole instance, set under Settings → Alerts (or logdeck alerts webhook set <url>). Every fired alert is POSTed to it as JSON:

{
  "source": "logdeck",
  "version": 1,
  "text": "LogDeck alert: error spike: 5 matches (level >= ERROR) within 60s (prod/api)",
  "content": "LogDeck alert: error spike: 5 matches (level >= ERROR) within 60s (prod/api)",
  "alert": {
    "id": "...",
    "ruleId": "...",
    "ruleName": "error spike",
    "type": "log",
    "host": "prod",
    "containerId": "...",
    "containerName": "api",
    "reason": "5 matches (level >= ERROR) within 60s",
    "sample": "level=error msg=\"upstream timeout\"",
    "count": 5,
    "suppressed": 0,
    "firedAt": "2026-07-14T09:31:04Z"
  }
}
Why it works with Slack and Discord unchanged

The same human-readable summary is sent twice, as text and as content. Slack (and Mattermost) render text; Discord renders content. So a Slack or Discord incoming-webhook URL works as-is, with no proxy or template in between.

Anything else that accepts a JSON POST works too — the full alert object is in the body for receivers that want to parse it.

Delivery has a 10-second timeout. Network errors and 5xx responses are retried once after 5 seconds; other statuses are treated as permanent. The outcome of each delivery (status, HTTP code, error) is recorded in the alert history.

Use Send test in Settings (or logdeck alerts test) to verify the URL. With no webhook configured, rules still evaluate and fire — the alerts are simply recorded in history and delivered nowhere.

Alert history

LogDeck keeps the most recent 500 fired alerts, newest first, and mirrors them to alerts-history.json next to the config file — so history survives a restart, provided that directory is a mounted volume. Each entry records the rule, the container and host, the reason, a sample line for log rules, how many matches were suppressed, and the delivery result. Read it under Settings → Alerts, with logdeck alerts history, or from GET /api/v1/alerts/history. Clearing it is a single action in the UI, or logdeck alerts history clear.

Managing rules from the CLI

Everything in the Alerts settings card is available from the CLI, which makes rules reproducible across deployments.

# Point alerts somewhere
logdeck alerts webhook set https://hooks.slack.com/services/...
logdeck alerts test

# Tell me when anything gets OOM-killed
logdeck alerts rules create --type event --name oom-watch --events oom

# Tell me when the api container crash-loops: 3 non-zero exits in 5 minutes
logdeck alerts rules create --type event --name api-crashloop \
  --events die --container api --threshold 3 --window 5m

# Tell me when prod starts spewing errors, at most once every 10 minutes
logdeck alerts rules create --type log --name error-spike \
  --min-level ERROR --host prod --threshold 5 --window 60s --cooldown 10m

# Match a specific failure, wherever it happens
logdeck alerts rules create --type log --name upstream-timeouts \
  --pattern "upstream (timed out|timeout)" --project checkout

# Inspect and manage
logdeck alerts rules                  # list, with targets and triggers
logdeck alerts rules disable <id>     # or enable / delete
logdeck alerts history --limit 20

--host, --container, and --project are repeatable and narrow the rule. --window and --cooldown accept durations (60s, 5m) or bare seconds. See the CLI reference for every flag.

Storage

Rules live in the config file
Under alerts, alongside hosts and API tokens

Alert rules and the webhook URL are persisted to config.json (/data/config.json by default), and fired alerts to alerts-history.json beside it. Mount /data as a volume, or both are lost when the LogDeck container is recreated.

There are no alert-related environment variables: alerting is configured through the UI or the CLI only.