| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222 |
- #!/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"
- <!DOCTYPE html>
- <html lang="en">
- <head>
- <meta charset="UTF-8">
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
- <title>$SRV Storage</title>
- <style>
- :root {
- --bg: #0f172a;
- --surface: #1e293b;
- --text: #f8fafc;
- --text-muted: #94a3b8;
- --border: #334155;
- --ok-bg: rgba(34, 197, 94, 0.15);
- --ok-text: #4ade80;
- --warn-bg: rgba(239, 68, 68, 0.15);
- --warn-text: #f87171;
- }
- body {
- background-color: var(--bg);
- color: var(--text);
- font-family: system-ui, sans-serif;
- padding: 2rem;
- margin: 0;
- }
- .container {
- max-width: 1200px;
- margin: 0 auto;
- }
- .header {
- display: flex;
- justify-content: space-between;
- align-items: flex-end;
- border-bottom: 1px solid var(--border);
- padding-bottom: 1rem;
- margin-bottom: 2rem;
- }
- .header h1 {
- margin: 0;
- font-size: 1.5rem;
- font-weight: 500;
- }
- table {
- width: 100%;
- border-collapse: collapse;
- background-color: var(--surface);
- border-radius: 8px;
- overflow: hidden;
- }
- th, td {
- padding: 1rem 1.25rem;
- text-align: left;
- border-bottom: 1px solid var(--border);
- }
- th {
- background-color: rgba(0, 0, 0, 0.2);
- color: var(--text-muted);
- font-weight: 600;
- font-size: 0.75rem;
- text-transform: uppercase;
- }
- tr:last-child td {
- border-bottom: none;
- }
- tr:hover {
- background-color: rgba(255, 255, 255, 0.02);
- }
- .serial {
- color: var(--text-muted);
- font-family: monospace;
- font-size: 0.85rem;
- }
- .badge {
- padding: 0.25rem 0.75rem;
- border-radius: 999px;
- font-size: 0.75rem;
- font-weight: 600;
- display: inline-block;
- }
- .badge.ok {
- background-color: var(--ok-bg);
- color: var(--ok-text);
- }
- .badge.warn {
- background-color: var(--warn-bg);
- color: var(--warn-text);
- }
- .timestamp {
- font-size: 0.85rem;
- color: var(--text-muted);
- margin-top: 1.5rem;
- text-align: center;
- }
- </style>
- </head>
- <body>
- <div class="container">
- <div class="header">
- <h1>Drive overview on <span style="color: var(--text-muted);">[$SRV]</span></h1>
- </div>
- <table>
- <thead>
- <tr>
- <th>Device</th>
- <th>Model</th>
- <th>Serial</th>
- <th>Size (GB)</th>
- <th>Type</th>
- <th>Temp (°C)</th>
- <th>Hours</th>
- <th>Health</th>
- <th>Realloc</th>
- </tr>
- </thead>
- <tbody>
- 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"
- <tr>
- <td style="font-weight: 500;">/dev/$d</td>
- <td>${HMOD}</td>
- <td class="serial">${HSER}</td>
- <td>$HCAP</td>
- <td>$HTYPE</td>
- <td>${HTEMP}</td>
- <td>${HHOURS}</td>
- <td><span class="badge $CLASS_HEA">${HHEA}</span></td>
- <td><span class="badge $CLASS_REA">${HREALLOC}</span></td>
- </tr>
- 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"
- </tbody>
- </table>
- <div class="timestamp">Last updated: $(date +'%Y-%m-%d %H:%M:%S')</div>
- </div>
- </body>
- </html>
- EOF
|