#!/usr/bin/env bash set -euo pipefail NTFY_SCRIPT="${NTFY_SCRIPT:-/mnt/user/services/homelab-infra/ops/restore-tests/send-ntfy.sh}" NTFY_TOPIC="${NTFY_TOPIC:-homelab-alerts}" SEND_NTFY="${SEND_NTFY:-1}" OUTPUT_PATH="${OUTPUT_PATH:-/mnt/user/services/posture-check/docker-critical-events-last.log}" EVENT_FILTERS="${EVENT_FILTERS:---filter event=die --filter event=oom --filter event=kill}" mkdir -p "$(dirname "$OUTPUT_PATH")" json_value() { local key="$1" local json="$2" printf '%s' "$json" | sed -n "s/.*\"$key\":\"\\([^\"]*\\)\".*/\\1/p" | head -n 1 } event_summary() { local event="$1" local action name image exit_code signal action="$(json_value "Action" "$event")" name="$(json_value "name" "$event")" image="$(json_value "image" "$event")" exit_code="$(json_value "exitCode" "$event")" signal="$(json_value "signal" "$event")" printf 'Container: %s\nAction: %s\nImage: %s\nExit-Code: %s\nSignal: %s\n\nFull event logged in: %s\n' \ "${name:-unknown}" \ "${action:-unknown}" \ "${image:-unknown}" \ "${exit_code:-n/a}" \ "${signal:-n/a}" \ "$OUTPUT_PATH" } event_title() { local event="$1" local action name exit_code action="$(json_value "Action" "$event")" name="$(json_value "name" "$event")" exit_code="$(json_value "exitCode" "$event")" if [ -n "$exit_code" ]; then printf 'Docker critical: %s %s exit=%s' "${name:-unknown}" "${action:-event}" "$exit_code" else printf 'Docker critical: %s %s' "${name:-unknown}" "${action:-event}" fi } should_send_event() { local event="$1" local action exit_code action="$(json_value "Action" "$event")" exit_code="$(json_value "exitCode" "$event")" case "$action" in die) [ "${exit_code:-}" != "0" ] ;; oom|kill) return 0 ;; *) return 1 ;; esac } send_event() { local line="$1" local title message local timestamp timestamp="$(date -Iseconds)" title="$(event_title "$line")" message="$(event_summary "$line")" printf '%s %s\n' "$timestamp" "$line" | tee -a "$OUTPUT_PATH" >/dev/null if [ "$SEND_NTFY" = "1" ] && [ -f "$NTFY_SCRIPT" ]; then bash "$NTFY_SCRIPT" "$NTFY_TOPIC" "$title" "$message" high || true fi } if ! command -v docker >/dev/null 2>&1; then echo "docker command not found" >&2 exit 127 fi # shellcheck disable=SC2086 docker events $EVENT_FILTERS --format '{{json .}}' | while IFS= read -r event; do [ -n "$event" ] || continue should_send_event "$event" || continue send_event "$event" done