Skip to main content

Alert Rules

Alerts are composed of rules, mounts, global settings, and notification channels.

Built-in Rules

IDNameMetricConditionCooldown
-1node_offlinenode.offline>= 10
-2raid_failedraid.failed>= 130 minutes
-3smart_faileddisk.smart.failed>= 130 minutes
-4smart_nvme_critical_warningdisk.smart.nvme.critical_warning>= 130 minutes

Built-in rules are mounted by default. Rule mounts can disable or enable rules for specific nodes.

Supported Metrics

MetricDescriptionSupports core_plus
cpu.usage_ratioCPU usage ratio 0..1No
cpu.load11-minute loadYes
cpu.load55-minute loadYes
cpu.load1515-minute loadYes
mem.usedUsed memory bytesNo
mem.used_ratioMemory usage ratio 0..1No
disk.usage.used_ratioMain mount disk usage ratioNo
disk.smart.failedCount of devices with health=failedNo
disk.smart.nvme.critical_warningCount of NVMe devices with non-zero critical_warningNo
disk.smart.attribute_failingCount of ATA SMART attributes currently in FAILING_NOWNo
disk.smart.max_temp_cMax SMART device temperature in CNo
net.recv_bpsReceive rate in B/sNo
net.sent_bpsSend rate in B/sNo
conn.tcpTCP connection countNo
raid.failedFailed RAID members or unhealthy arraysNo
thermal.max_temp_cMax thermal sensor temperature in CNo

disk.usage.used_ratio uses / first. If / is missing, it falls back to the first mount for compatibility.

disk.smart.failed counts only health=failed. Collection states such as no_cache, no_tool, unsupported, and stale are not counted as disk failures.

disk.smart.nvme.critical_warning counts only devices that report critical_warning with a non-zero value. If no device reports the field, the metric is not evaluated.

disk.smart.attribute_failing counts only failing_attrs[].when_failed=FAILING_NOW. If no failing attribute data is available, the metric is not evaluated.

SMART notifications list at most 3 affected devices in the title, 5 devices in detail, and 8 failing attributes per device. Device and attribute labels replace control/format characters with spaces and are limited to 128 Unicode characters; the full detail is limited to 2048 characters. NVMe details include the raw critical warning and media_errors when available, labeled with SMART UI item 0E.

Operators

  • >
  • >=
  • <
  • <=
  • ==
  • !=

Duration

Allowed values:

  • 0
  • 60
  • 300

Unit is seconds. Missing duration_sec defaults to 60 when creating a rule.

Rule names are trimmed, contain 1–128 Unicode characters, and cannot contain control characters. threshold and threshold_offset must be finite. cooldown_min must be in 0..525600.

Threshold Mode

ModeDescription
staticUse threshold directly
core_plusLoad metrics only; threshold is CPU cores + threshold + threshold_offset

In static mode, threshold_offset must be 0.

CPU core count uses logical cores first, then physical cores.

Lifecycle

  1. A node report places the latest snapshot in a process-local dirty queue.
  2. The alert service reads that snapshot or the current PostgreSQL projection.
  3. Enabled rules and node mount state are compiled.
  4. Matching conditions open events after duration is met.
  5. Non-matching conditions close events.
  6. If notification targets can be loaded, payloads are written to the notification outbox according to global settings.
  7. One process-local worker delivers PostgreSQL outbox rows without runtime leases.

The alert service does not open new alert events during the first minute after startup.

Open firing events persist in PostgreSQL and are restored after restart. Pending and cooldown state and the dirty queue are process-local and reset on restart. Startup reconciliation, restored open events, and later reports resume evaluation.

Alert events and notification outbox rows share one persistence boundary. If the first target load fails without a last-good snapshot, the transition is delayed; an available last-good snapshot is used to commit the event and outbox. Delivery failures do not roll back alert events. Retry, pause, block, and discard behavior is documented under Notifications.

Alert Records

Alert records store events after rules open and close. The admin console can filter records by node, status, metric, and time range.

Endpoints:

GET /api/admin/alerts/events
GET /api/admin/alerts/events/summary
GET /api/admin/alerts/events/servers

GET /api/admin/alerts/events supports server_id, status, metric, from, to, cursor, and limit. status allows open, closed, or all; omitted status returns only open events.

GET /api/admin/alerts/events/summary returns open-alert summaries grouped by node. The node list alert entry uses this summary. It is loaded when entering the node page and is not realtime polling.

Its open_count is the number of open alert events. The dashboard summary “Anomalies” count uses offline, RAID, CPU, and disk conditions and is not this field.

Rule Mounts

Rule mounts are (rule_id, server_id) -> enabled.

Endpoint:

PUT /api/admin/alerts/mounts

Request:

{
"rule_ids": [-1, 10],
"server_ids": [1, 2],
"mounted": true
}

rule_ids may include built-in rule IDs. server_ids must reference existing nodes.

Global Alert Settings

Endpoint:

PUT /api/admin/alerts/settings

Request:

{
"enabled": true,
"channel_ids": [1, 2]
}

channel_ids can be an empty array, which enables alerts without sending notifications.