#!/bin/bash
#########################################################################
# Script for check HDD state #
# Created by Pavol Macko - DoIT #
# ver 0.4 #
#########################################################################
#------------------------------ VARIABLES ------------------------------#
LOG="/tmp/hdd.log"
HTML_DIR="/var/www/hdd"
HTML_OUT="$HTML_DIR/hdd.html"
SRV=$(hostname -s)
EMAIL_TO="info@doit.sk"
EMAIL_SUBJECT="[CRITICAL] Disk Issue Detected on $SRV"
EMAIL_BODY=""
HAS_ERRORS=0
TEMP=55
#------------------------------- REPORT --------------------------------#
mkdir -p "$HTML_DIR"
echo -e "- \e[1;32mExtracting\e[0m Local Storage info from [\e[1;33m$SRV\e[0m]"
echo "DEV|MODEL|SERIAL|SIZE(GB)|TYPE|TEMP(C)|HOURS|HEALTH|REALLOC" > $LOG
cat << EOF > "$HTML_OUT"
$SRV Storage
| Device |
Model |
Serial |
Size (GB) |
Type |
Temp (°C) |
Hours |
Health |
Realloc |
EOF
#------------------------------- EXTRACT -------------------------------#
lsblk -d -n -b -o NAME,TYPE,TRAN,SIZE | awk '$2=="disk" && $1 !~ /^(zd|loop|md|dm-|ram)/' | while read -r d type tran bytes;
do
[[ "$tran" == "usb" ]] && continue
HCAP=$(awk -v b="$bytes" 'BEGIN { printf "%.2f", b / (1024^3) }')
SMART=$(smartctl -a /dev/$d 2>/dev/null)
[[ -z "$SMART" ]] && continue
HMOD=$(echo "$SMART" | grep -E "^(Device Model|Model Number):" | awk -F: '{print $2}' | xargs)
HSER=$(echo "$SMART" | grep -i "^Serial Number:" | awk -F: '{print $2}' | xargs)
HROT=$(echo "$SMART" | grep -i "^Rotation Rate:" | awk -F: '{print $2}' | xargs)
if [[ "$tran" == "nvme" ]] || [[ "$HROT" == *"Solid State"* ]] || [[ -z "$HROT" ]]; then
HTYPE="SSD/NVMe"
else
HTYPE="HDD"
fi
HHEA=$(echo "$SMART" | grep -iE "overall-health|SMART overall-health" | awk '{print $NF}')
HTEMP=$(echo "$SMART" | awk '/^194 Temperature_Celsius/ {print $10}; /^Temperature:/ {print $2}' | head -n 1)
HHOURS=$(echo "$SMART" | awk '/^ 9 Power_On_Hours/ {print $10}; /^Power On Hours:/ {print $4}' | tr -d ',' | head -n 1)
HREALLOC=$(echo "$SMART" | awk '/^ 5 Reallocated_Sector_Ct/ {print $10}' | head -n 1)
HMOD=${HMOD:--}
HSER=${HSER:--}
HTEMP=${HTEMP:--}
HHOURS=${HHOURS:--}
HHEA=${HHEA:--}
HREALLOC=${HREALLOC:--}
echo "$d|${HMOD}|${HSER}|$HCAP|$HTYPE|${HTEMP}|${HHOURS}|${HHEA}|${HREALLOC}" >> $LOG
CLASS_HEA="ok"
if [[ "$HHEA" != "PASSED" && "$HHEA" != "OK" ]]; then
CLASS_HEA="warn"
HAS_ERRORS=1
EMAIL_BODY="${EMAIL_BODY}\n- /dev/$d ($HMOD, SN: $HSER): Health status is '$HHEA'!"
fi
CLASS_REA="ok"
if [[ "$HREALLOC" =~ ^[0-9]+$ ]] && [[ "$HREALLOC" -gt 0 ]]; then
CLASS_REA="warn"
HAS_ERRORS=1
EMAIL_BODY="${EMAIL_BODY}\n- /dev/$d ($HMOD, SN: $HSER): Reallocated Sectors count is $HREALLOC!"
fi
if [[ "$HTEMP" =~ ^[0-9]+$ ]] && [[ "$HTEMP" -ge "$TEMP" ]]; then
HAS_ERRORS=1
EMAIL_BODY="${EMAIL_BODY}\n- /dev/$d ($HMOD, SN: $HSER): High Temperature ($HTEMP °C)!"
fi
cat << EOF >> "$HTML_OUT"
| /dev/$d |
${HMOD} |
${HSER} |
$HCAP |
$HTYPE |
${HTEMP} |
${HHOURS} |
${HHEA} |
${HREALLOC} |
EOF
done
if [[ "$HAS_ERRORS" -eq 1 ]]; then
FULL_MAIL_BODY="HDD/SSD alert triggered on server: $SRV\nDate: $(date +'%Y-%m-%d %H:%M:%S')\n\nDetected issues:$EMAIL_BODY\n\nCheck full dashboard at HTML report."
echo -e "$FULL_MAIL_BODY" | mail -s "$EMAIL_SUBJECT" "$EMAIL_TO"
fi
CLI_OUT=$(column -t -s '|' $LOG)
HEADER=$(echo "$CLI_OUT" | head -n 1)
DASHES=$(echo "$HEADER" | sed 's/[^ ]/-/g')
echo -e "\e[1;36m$DASHES\e[0m"
echo -e "\e[1;36m$HEADER\e[0m"
echo -e "\e[1;36m$DASHES\e[0m"
echo "$CLI_OUT" | tail -n +2
rm -f $LOG
cat << EOF >> "$HTML_OUT"
Last updated: $(date +'%Y-%m-%d %H:%M:%S')
EOF