updated variables for coffee report.
This commit is contained in:
@@ -156,41 +156,54 @@ fi
|
|||||||
# -----------------------------------------------------------------------------------------------
|
# -----------------------------------------------------------------------------------------------
|
||||||
section "📀 ARRAY"
|
section "📀 ARRAY"
|
||||||
|
|
||||||
# unRAID array info — parse var/local/emhttp correctly
|
# unRAID array info — parse disks.ini correctly
|
||||||
|
# Format uses ["diskN"] ["parity"] ["parity2"] etc.
|
||||||
if [[ -f /var/local/emhttp/disks.ini ]]; then
|
if [[ -f /var/local/emhttp/disks.ini ]]; then
|
||||||
# Count data disks only (disk1, disk2 etc — not parity, cache, flash)
|
DISK_COUNT=$(grep -c '^\["disk[0-9]' /var/local/emhttp/disks.ini 2>/dev/null || echo "?")
|
||||||
DISK_COUNT=$(grep -c "^\[disk[0-9]" /var/local/emhttp/disks.ini 2>/dev/null || echo "?")
|
PARITY_COUNT=$(grep -c '^\["parity' /var/local/emhttp/disks.ini 2>/dev/null || echo "?")
|
||||||
PARITY_COUNT=$(grep -c "^\[parity" /var/local/emhttp/disks.ini 2>/dev/null || echo 0)
|
DISK_COUNT="${DISK_COUNT//[^0-9]/}"; DISK_COUNT="${DISK_COUNT:-?}"
|
||||||
line "Array disks: $DISK_COUNT data + $PARITY_COUNT parity"
|
PARITY_COUNT="${PARITY_COUNT//[^0-9]/}"; PARITY_COUNT="${PARITY_COUNT:-?}"
|
||||||
|
line "Array: ${DISK_COUNT} data disks + ${PARITY_COUNT} parity"
|
||||||
else
|
else
|
||||||
line "Array: disks.ini not found — array may not be started"
|
line "Array: disks.ini not found"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Parity status from var/local/emhttp
|
# Parity status from parity-checks.log
|
||||||
PARITY_FILE="/var/local/emhttp/parity-date.txt"
|
PARITY_LOG="/boot/config/parity-checks.log"
|
||||||
if [[ -f "$PARITY_FILE" ]]; then
|
if [[ -f "$PARITY_LOG" ]]; then
|
||||||
PARITY_INFO=$(cat "$PARITY_FILE" 2>/dev/null)
|
LAST_CHECK=$(tail -1 "$PARITY_LOG" 2>/dev/null)
|
||||||
if echo "$PARITY_INFO" | grep -q "progress"; then
|
if [[ -n "$LAST_CHECK" ]]; then
|
||||||
finding "Parity check in progress"
|
PARITY_DATE=$(echo "$LAST_CHECK" | cut -d'|' -f1 | xargs)
|
||||||
else
|
PARITY_ERRORS=$(echo "$LAST_CHECK" | cut -d'|' -f4)
|
||||||
PARITY_DATE=$(echo "$PARITY_INFO" | grep -oE '[0-9]{4}-[0-9]{2}-[0-9]{2}' | head -1)
|
PARITY_ACTION=$(echo "$LAST_CHECK" | cut -d'|' -f6)
|
||||||
PARITY_ERRORS=$(echo "$PARITY_INFO" | grep -oE 'errors=[0-9]+' | cut -d= -f2 || echo 0)
|
PARITY_DURATION=$(echo "$LAST_CHECK" | cut -d'|' -f2)
|
||||||
PARITY_ERRORS="${PARITY_ERRORS:-0}"
|
PARITY_DUR_HR=$(( PARITY_DURATION / 3600 ))
|
||||||
|
PARITY_DUR_MIN=$(( (PARITY_DURATION % 3600) / 60 ))
|
||||||
|
|
||||||
|
# Negative = sync corrections (not data errors), positive = real errors
|
||||||
if [[ "$PARITY_ERRORS" -gt 0 ]]; then
|
if [[ "$PARITY_ERRORS" -gt 0 ]]; then
|
||||||
issue "Parity: $PARITY_ERRORS errors on last check (${PARITY_DATE:-unknown})"
|
issue "Parity: $PARITY_ERRORS errors on last check ($PARITY_DATE)"
|
||||||
|
elif [[ "$PARITY_ERRORS" -lt 0 ]]; then
|
||||||
|
CORRECTIONS=$(( PARITY_ERRORS * -1 ))
|
||||||
|
line "Parity: OK — last: $PARITY_DATE ($PARITY_ACTION, ${PARITY_DUR_HR}h${PARITY_DUR_MIN}m, $CORRECTIONS correction(s)) ✅"
|
||||||
else
|
else
|
||||||
line "Parity: OK — last check: ${PARITY_DATE:-unknown}, 0 errors ✅"
|
line "Parity: OK — last: $PARITY_DATE ($PARITY_ACTION, ${PARITY_DUR_HR}h${PARITY_DUR_MIN}m, 0 errors) ✅"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Check if currently running
|
||||||
|
RESYNC=$(grep "^mdResync=" /var/local/emhttp/var.ini 2>/dev/null | cut -d= -f2 | tr -d '"')
|
||||||
|
if [[ "$RESYNC" != "0" ]]; then
|
||||||
|
finding "Parity check currently in progress"
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
else
|
else
|
||||||
line "Parity: no check recorded yet"
|
line "Parity: no check log found"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# ZFS pool health — filter ignored pools
|
# ZFS pool health — filter ignored pools
|
||||||
if command -v zpool >/dev/null 2>&1; then
|
if command -v zpool >/dev/null 2>&1; then
|
||||||
while IFS=$'\t' read -r pool health; do
|
while IFS=$'\t' read -r pool health; do
|
||||||
[[ -z "$pool" ]] && continue
|
[[ -z "$pool" ]] && continue
|
||||||
# Skip pools in ZFS_REPORT_IGNORE_POOLS
|
|
||||||
SKIP=false
|
SKIP=false
|
||||||
for ignore in "${ZFS_REPORT_IGNORE_POOLS[@]:-}"; do
|
for ignore in "${ZFS_REPORT_IGNORE_POOLS[@]:-}"; do
|
||||||
[[ "$pool" == "$ignore" ]] && SKIP=true && break
|
[[ "$pool" == "$ignore" ]] && SKIP=true && break
|
||||||
@@ -204,10 +217,12 @@ if command -v zpool >/dev/null 2>&1; then
|
|||||||
done < <(zpool list -H -o name,health 2>/dev/null)
|
done < <(zpool list -H -o name,health 2>/dev/null)
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Drive temperatures from SMART — fixed parsing
|
# Drive temperatures from SMART — build lookup table first then display per disk
|
||||||
if command -v smartctl >/dev/null 2>&1; then
|
if command -v smartctl >/dev/null 2>&1; then
|
||||||
|
declare -A DISK_TEMPS
|
||||||
TEMP_WARN=false
|
TEMP_WARN=false
|
||||||
TEMP_SUMMARY=""
|
ALL_NORMAL=true
|
||||||
|
|
||||||
for disk in /dev/sd? /dev/nvme?; do
|
for disk in /dev/sd? /dev/nvme?; do
|
||||||
[[ ! -e "$disk" ]] && continue
|
[[ ! -e "$disk" ]] && continue
|
||||||
DISK_NAME=$(basename "$disk")
|
DISK_NAME=$(basename "$disk")
|
||||||
@@ -217,38 +232,54 @@ if command -v smartctl >/dev/null 2>&1; then
|
|||||||
done
|
done
|
||||||
[[ "$SKIP" == true ]] && continue
|
[[ "$SKIP" == true ]] && continue
|
||||||
|
|
||||||
# Try multiple SMART temp attribute names — different drives use different fields
|
|
||||||
TEMP=$(smartctl -A "$disk" 2>/dev/null | awk '
|
TEMP=$(smartctl -A "$disk" 2>/dev/null | awk '
|
||||||
/^190 / || /^194 / { print $10; exit }
|
/^190 / || /^194 / { print $10; exit }
|
||||||
/Temperature_Celsius/ { print $10; exit }
|
/Temperature_Celsius/ { print $10; exit }
|
||||||
/Airflow_Temperature/ { print $10; exit }
|
/Airflow_Temperature/ { print $10; exit }
|
||||||
')
|
')
|
||||||
|
|
||||||
# NVMe uses different output format
|
|
||||||
if [[ -z "$TEMP" ]]; then
|
if [[ -z "$TEMP" ]]; then
|
||||||
TEMP=$(smartctl -A "$disk" 2>/dev/null | \
|
TEMP=$(smartctl -A "$disk" 2>/dev/null | \
|
||||||
awk '/^Temperature:/ { print $2; exit }')
|
awk '/^Temperature:/ { print $2; exit }')
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Strip any non-numeric chars
|
|
||||||
TEMP="${TEMP//[^0-9]/}"
|
TEMP="${TEMP//[^0-9]/}"
|
||||||
[[ -z "$TEMP" ]] && continue
|
[[ -z "$TEMP" ]] && continue
|
||||||
TEMP_INT="$TEMP"
|
|
||||||
|
|
||||||
if [[ "$TEMP_INT" -ge "${SMART_TEMP_CRIT:-55}" ]]; then
|
DISK_TEMPS["$DISK_NAME"]="$TEMP"
|
||||||
issue "Drive $DISK_NAME: ${TEMP_INT}°C — CRITICAL"
|
|
||||||
|
if [[ "$TEMP" -ge "${SMART_TEMP_CRIT:-55}" ]]; then
|
||||||
|
issue "Drive $DISK_NAME: ${TEMP}°C — CRITICAL"
|
||||||
TEMP_WARN=true
|
TEMP_WARN=true
|
||||||
elif [[ "$TEMP_INT" -ge "${SMART_TEMP_WARN:-45}" ]]; then
|
ALL_NORMAL=false
|
||||||
finding "Drive $DISK_NAME: ${TEMP_INT}°C — warm"
|
elif [[ "$TEMP" -ge "${SMART_TEMP_WARN:-45}" ]]; then
|
||||||
|
finding "Drive $DISK_NAME: ${TEMP}°C — warm"
|
||||||
TEMP_WARN=true
|
TEMP_WARN=true
|
||||||
|
ALL_NORMAL=false
|
||||||
fi
|
fi
|
||||||
[[ -n "$TEMP_SUMMARY" ]] && TEMP_SUMMARY+=", "
|
|
||||||
TEMP_SUMMARY+="${DISK_NAME}:${TEMP_INT}°C"
|
|
||||||
done
|
done
|
||||||
if [[ "$TEMP_WARN" == false ]]; then
|
|
||||||
|
if [[ "$ALL_NORMAL" == true ]]; then
|
||||||
line "Drive temps: all normal ✅"
|
line "Drive temps: all normal ✅"
|
||||||
fi
|
fi
|
||||||
[[ -n "$TEMP_SUMMARY" ]] && line "Temps: $TEMP_SUMMARY"
|
|
||||||
|
# Show per-disk summary with device name from disks.ini + temp
|
||||||
|
if [[ -f /var/local/emhttp/disks.ini ]] && [[ ${#DISK_TEMPS[@]} -gt 0 ]]; then
|
||||||
|
# Parse disk → device mapping from disks.ini
|
||||||
|
DISK_SUMMARY=""
|
||||||
|
CURRENT_DISK=""
|
||||||
|
while IFS= read -r ini_line; do
|
||||||
|
if echo "$ini_line" | grep -qE '^\["(disk[0-9]+|parity[0-9]?|cache)"\]'; then
|
||||||
|
CURRENT_DISK=$(echo "$ini_line" | grep -o '"[^"]*"' | head -1 | tr -d '"')
|
||||||
|
elif echo "$ini_line" | grep -q '^device='; then
|
||||||
|
DEV=$(echo "$ini_line" | cut -d= -f2 | tr -d '"')
|
||||||
|
TEMP="${DISK_TEMPS[$DEV]:-}"
|
||||||
|
if [[ -n "$TEMP" ]]; then
|
||||||
|
[[ -n "$DISK_SUMMARY" ]] && DISK_SUMMARY+=", "
|
||||||
|
DISK_SUMMARY+="${CURRENT_DISK}(${DEV}):${TEMP}°C"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
done < /var/local/emhttp/disks.ini
|
||||||
|
[[ -n "$DISK_SUMMARY" ]] && line "Temps: $DISK_SUMMARY"
|
||||||
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# -----------------------------------------------------------------------------------------------
|
# -----------------------------------------------------------------------------------------------
|
||||||
@@ -493,7 +524,7 @@ ROOTFS_PCT_CR=$(df / --output=pcent 2>/dev/null | tail -1 | tr -d ' %')
|
|||||||
MEM_AVAIL_CR=$(awk '/MemAvailable/ {printf "%.1f", $2/1048576}' /proc/meminfo)
|
MEM_AVAIL_CR=$(awk '/MemAvailable/ {printf "%.1f", $2/1048576}' /proc/meminfo)
|
||||||
MEM_TOTAL_CR=$(awk '/MemTotal/ {printf "%.0f", $2/1048576}' /proc/meminfo)
|
MEM_TOTAL_CR=$(awk '/MemTotal/ {printf "%.0f", $2/1048576}' /proc/meminfo)
|
||||||
LOAD_CR=$(awk '{print $1}' /proc/loadavg)
|
LOAD_CR=$(awk '{print $1}' /proc/loadavg)
|
||||||
ZOMBIE_CR=$(ps aux | awk '{print $8}' | grep -c "^Z$" 2>/dev/null || echo 0)
|
ZOMBIE_CR=$(ps aux | awk '{print $8}' | grep -c "^Z$" 2>/dev/null)
|
||||||
ZOMBIE_CR="${ZOMBIE_CR//[^0-9]/}"
|
ZOMBIE_CR="${ZOMBIE_CR//[^0-9]/}"
|
||||||
ZOMBIE_CR="${ZOMBIE_CR:-0}"
|
ZOMBIE_CR="${ZOMBIE_CR:-0}"
|
||||||
ARC_GB_CR="n/a"
|
ARC_GB_CR="n/a"
|
||||||
|
|||||||
Reference in New Issue
Block a user