105 lines
4.9 KiB
Bash
Executable File
105 lines
4.9 KiB
Bash
Executable File
#!/bin/bash
|
|
# ansipa_pbs — CheckMK local check for a Proxmox Backup Server.
|
|
#
|
|
# Install: copy to /usr/lib/check_mk_agent/local/ansipa_pbs and chmod 755
|
|
# (ansipa-infra-checkmk-install.sh does this for you, along with installing
|
|
# the CheckMK agent itself and registering the host).
|
|
#
|
|
# Requires only `proxmox-backup-manager` (ships with proxmox-backup-server)
|
|
# and `df` — no jq/python3 dependency. JSON is requested as "json-pretty"
|
|
# (one key per line) and scraped with a small grep/awk parser. Any command
|
|
# that fails or returns nothing degrades that one service to CheckMK state 3
|
|
# (UNKNOWN) rather than aborting the others.
|
|
#
|
|
# Emits (CheckMK local-check format: "<state> <service> <perfdata> <text>"):
|
|
# Ansipa_PBS_Datastores worst datastore disk utilisation (via df on path)
|
|
# Ansipa_PBS_LastBackup freshness + outcome of the last backup task
|
|
# Ansipa_PBS_TaskFailures any failed task (GC/verify/sync/prune/backup) in 24h
|
|
#
|
|
# CPU/RAM/disk-root are already covered by CheckMK's stock Linux checks —
|
|
# not duplicated here.
|
|
|
|
command -v proxmox-backup-manager >/dev/null 2>&1 \
|
|
|| { echo "3 Ansipa_PBS - proxmox-backup-manager not found (not a PBS host?)"; exit 0; }
|
|
|
|
# Extract every value of a JSON key from json-pretty text (one "key": value per line).
|
|
_jp() { grep -oP "^\s*\"$1\"\s*:\s*\"?\K[^\",]+" || true; }
|
|
|
|
# ── Datastore disk usage (df on each datastore path — version-independent) ───
|
|
DSTAT=$(proxmox-backup-manager datastore list --output-format json-pretty 2>/dev/null || true)
|
|
if [[ -z "$DSTAT" ]]; then
|
|
echo "3 Ansipa_PBS_Datastores - could not query datastore list"
|
|
else
|
|
mapfile -t DNAMES < <(_jp name <<< "$DSTAT")
|
|
mapfile -t DPATHS < <(_jp path <<< "$DSTAT")
|
|
WORST=0; WORST_NAME=""; PERF=""
|
|
for i in "${!DNAMES[@]}"; do
|
|
p="${DPATHS[$i]:-}"
|
|
[[ -d "$p" ]] || continue
|
|
pct=$(df -P "$p" 2>/dev/null | awk 'NR==2{gsub("%","",$5); print $5}')
|
|
[[ "$pct" =~ ^[0-9]+$ ]] || continue
|
|
PERF+=" ${DNAMES[$i]}_pct=${pct}%;85;95"
|
|
(( pct > WORST )) && { WORST=$pct; WORST_NAME="${DNAMES[$i]}"; }
|
|
done
|
|
if [[ -z "$WORST_NAME" ]]; then
|
|
echo "3 Ansipa_PBS_Datastores - no readable datastore paths found"
|
|
elif (( WORST >= 95 )); then
|
|
echo "2 Ansipa_PBS_Datastores${PERF} CRIT — ${WORST_NAME} at ${WORST}%"
|
|
elif (( WORST >= 85 )); then
|
|
echo "1 Ansipa_PBS_Datastores${PERF} WARN — ${WORST_NAME} at ${WORST}%"
|
|
else
|
|
echo "0 Ansipa_PBS_Datastores${PERF} worst: ${WORST_NAME} at ${WORST}%"
|
|
fi
|
|
fi
|
|
|
|
# ── Recent task history (shared by the next two checks) ──────────────────────
|
|
TSTAT=$(proxmox-backup-manager task list --output-format json-pretty --limit 500 2>/dev/null || true)
|
|
if [[ -z "$TSTAT" ]]; then
|
|
echo "3 Ansipa_PBS_LastBackup - could not query task list"
|
|
echo "3 Ansipa_PBS_TaskFailures - could not query task list"
|
|
else
|
|
mapfile -t WTYPE < <(_jp worker_type <<< "$TSTAT")
|
|
mapfile -t TSTATUS < <(_jp status <<< "$TSTAT")
|
|
mapfile -t TSTART < <(_jp starttime <<< "$TSTAT")
|
|
|
|
# ── Most recent backup task ──────────────────────────────────────────────
|
|
LAST_TS=0; LAST_STATUS=""
|
|
for i in "${!WTYPE[@]}"; do
|
|
[[ "${WTYPE[$i]}" == "backup" ]] || continue
|
|
st="${TSTART[$i]:-0}"
|
|
[[ "$st" =~ ^[0-9]+$ ]] || continue
|
|
if (( st > LAST_TS )); then LAST_TS=$st; LAST_STATUS="${TSTATUS[$i]:-}"; fi
|
|
done
|
|
if [[ "$LAST_TS" -eq 0 ]]; then
|
|
echo "1 Ansipa_PBS_LastBackup - no backup task found in recent history"
|
|
else
|
|
AGE_H=$(( ( $(date +%s) - LAST_TS ) / 3600 ))
|
|
PERF="last_backup_hours=${AGE_H}"
|
|
if [[ "$LAST_STATUS" != "OK" ]]; then
|
|
echo "2 Ansipa_PBS_LastBackup ${PERF} Last backup task FAILED (${AGE_H}h ago): ${LAST_STATUS}"
|
|
elif (( AGE_H >= 48 )); then
|
|
echo "1 Ansipa_PBS_LastBackup ${PERF} Last successful backup ${AGE_H}h ago (stale)"
|
|
else
|
|
echo "0 Ansipa_PBS_LastBackup ${PERF} Last backup OK, ${AGE_H}h ago"
|
|
fi
|
|
fi
|
|
|
|
# ── Any failed task in the last 24h (GC / verify / sync / prune / backup) ─
|
|
NOW=$(date +%s); FAILED=0; TOTAL24=0
|
|
for i in "${!TSTART[@]}"; do
|
|
st="${TSTART[$i]:-0}"
|
|
[[ "$st" =~ ^[0-9]+$ ]] || continue
|
|
(( NOW - st <= 86400 )) || continue
|
|
TOTAL24=$((TOTAL24+1))
|
|
[[ "${TSTATUS[$i]:-}" == "OK" ]] || FAILED=$((FAILED+1))
|
|
done
|
|
PERF="failed=${FAILED};1;3 total=${TOTAL24}"
|
|
if (( FAILED >= 3 )); then
|
|
echo "2 Ansipa_PBS_TaskFailures ${PERF} ${FAILED}/${TOTAL24} tasks failed in the last 24h"
|
|
elif (( FAILED >= 1 )); then
|
|
echo "1 Ansipa_PBS_TaskFailures ${PERF} ${FAILED}/${TOTAL24} task(s) failed in the last 24h"
|
|
else
|
|
echo "0 Ansipa_PBS_TaskFailures ${PERF} ${TOTAL24} task(s) in last 24h, none failed"
|
|
fi
|
|
fi
|