ZFS and disk health alerts
You’ll get: one incident per pool when ZFS reports a vdev problem, and one per disk when smartd flags a SMART failure — deduplicated so a noisy pool doesn’t spam you with a new incident per event.
Before you start
Section titled “Before you start”An ingest key from a generic InfraInbox source, shaped like iik_src_… (see Events API: curl and scripts).
ZFS: a ZED zedlet
Section titled “ZFS: a ZED zedlet”ZED (the ZFS Event Daemon) runs every executable script under /etc/zfs/zed.d/ whose name starts with all- for every event it sees. Create one:
#!/usr/bin/env bashset -uo pipefailURL="https://infrainbox.example.com/v1/events"KEY="iik_src_XXXXXXXXXXXX"pool="${ZEVENT_POOL:-unknown}"class="${ZEVENT_SUBCLASS:-${ZEVENT_CLASS:-}}"dedup="zfs:${pool}"
post() { curl -fsS -m 10 -H "Authorization: Bearer $KEY" -H "Content-Type: application/json" -d "$1" "$URL"}
case "$class" in statechange) if [ "${ZEVENT_VDEV_STATE_STR:-}" = "ONLINE" ]; then post "{\"title\":\"$pool is healthy again\",\"action\":\"resolve\",\"dedupKey\":\"$dedup\"}" else post "{\"title\":\"$pool: ${ZEVENT_VDEV_PATH:-a device} is ${ZEVENT_VDEV_STATE_STR:-degraded}\",\"severity\":\"CRITICAL\",\"type\":\"zfs.statechange\",\"resource\":\"zpool:$pool\",\"dedupKey\":\"$dedup\"}" fi ;; checksum|io|probe_failure) post "{\"title\":\"$pool: $class on ${ZEVENT_VDEV_PATH:-a device}\",\"severity\":\"WARNING\",\"type\":\"zfs.$class\",\"resource\":\"zpool:$pool\",\"dedupKey\":\"$dedup\"}" ;;esacsudo chmod +x /etc/zfs/zed.d/all-infrainbox.shsudo systemctl restart zfs-zed # or `zed`, depending on your distributionTest it without waiting for a real fault, by invoking it with the same environment variables ZED would set:
sudo ZEVENT_POOL=tank ZEVENT_SUBCLASS=statechange ZEVENT_VDEV_STATE_STR=FAULTED \ ZEVENT_VDEV_PATH=/dev/sdb1 /etc/zfs/zed.d/all-infrainbox.shDisks: a smartd exec script
Section titled “Disks: a smartd exec script”#!/usr/bin/env bashset -uo pipefailURL="https://infrainbox.example.com/v1/events"KEY="iik_src_XXXXXXXXXXXX"dev="${SMARTD_DEVICE:-unknown}"msg="${SMARTD_MESSAGE:-SMART failure}"
curl -fsS -m 10 \ -H "Authorization: Bearer $KEY" \ -H "Content-Type: application/json" \ -d "{\"title\":\"${SMARTD_DEVICESTRING:-$dev}: $msg\",\"severity\":\"CRITICAL\",\"type\":\"smart.failure\",\"resource\":\"disk:$dev\",\"dedupKey\":\"smart:$dev\"}" \ "$URL"sudo chmod +x /usr/local/bin/smart-to-infrainbox.shAdd it to /etc/smartd.conf, either on a specific drive’s line or the catch-all:
DEVICESCAN -a -M exec /usr/local/bin/smart-to-infrainbox.shsudo systemctl restart smartdTo test it without waiting for a real failure, add -M test temporarily — it runs the exec script once, at smartd’s next start, as a test:
DEVICESCAN -a -M exec /usr/local/bin/smart-to-infrainbox.sh -M testsudo systemctl restart smartd# then remove -M test once you've confirmed the incident arrivedCheck it works
Section titled “Check it works”- The forced ZED test above opens a CRITICAL incident for pool
tank; re-running it withZEVENT_VDEV_STATE_STR=ONLINEresolves it. - The
smartd -M testrun produces one incident per configured disk; disable-M testafterwards so it doesn’t re-alert on every smartd restart.
smartd itself has no clean “back to healthy” signal the way ZED’s statechange does, so a disk’s incident stays open until you resolve it by hand once you’ve dealt with the drive.