79 lines
2.7 KiB
Bash
Executable File
79 lines
2.7 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# update-system-status.sh — Writes system-status.json for the Nexus One AI portal.
|
|
# Run via cron every 30 seconds (cron minimum is 1 minute; use two entries offset by 30s).
|
|
#
|
|
# CRON SETUP (run as the portal server user):
|
|
# crontab -e
|
|
# Add these two lines:
|
|
# * * * * * /opt/cezen-portal/update-system-status.sh
|
|
# * * * * * sleep 30 && /opt/cezen-portal/update-system-status.sh
|
|
#
|
|
# OUTPUT: /opt/cezen-portal/system-status.json
|
|
# Adjust PORTAL_DIR below to match your actual portal directory.
|
|
|
|
PORTAL_DIR="/opt/cezen-portal"
|
|
OUT="$PORTAL_DIR/system-status.json"
|
|
TMP="$OUT.tmp"
|
|
|
|
# ── CPU load (1-minute average as a percentage of total cores) ──
|
|
CPU_CORES=$(nproc)
|
|
CPU_LOAD_RAW=$(awk '{print $1}' /proc/loadavg)
|
|
CPU_PCT=$(awk "BEGIN {v=$CPU_LOAD_RAW/$CPU_CORES*100; if(v>100)v=100; printf \"%d\", v}")
|
|
|
|
# ── RAM ──
|
|
read -r total used free shared buff cache available <<< $(free -b | awk 'NR==2{print $2,$3,$4,$5,$6,$7,$7}')
|
|
RAM_TOTAL_GB=$(awk "BEGIN {printf \"%.0f\", $total/1024/1024/1024}")
|
|
RAM_USED_GB=$(awk "BEGIN {printf \"%.0f\", ($total-$available)/1024/1024/1024}")
|
|
RAM_PCT=$(awk "BEGIN {printf \"%d\", ($total-$available)/$total*100}")
|
|
|
|
# ── Disk (root filesystem) ──
|
|
DISK_INFO=$(df -B1 / | awk 'NR==2{print $2,$3,$5}')
|
|
read -r DISK_TOTAL_B DISK_USED_B DISK_PCT_RAW <<< "$DISK_INFO"
|
|
DISK_PCT=${DISK_PCT_RAW/\%/}
|
|
DISK_TOTAL_GB=$(awk "BEGIN {printf \"%.1f\", $DISK_TOTAL_B/1024/1024/1024/1024}")
|
|
DISK_USED_GB=$(awk "BEGIN {printf \"%.0f\", $DISK_USED_B/1024/1024/1024}")
|
|
|
|
# ── GPU (NVIDIA) ──
|
|
if command -v nvidia-smi &>/dev/null; then
|
|
GPU_INFO=$(nvidia-smi --query-gpu=utilization.gpu,temperature.gpu --format=csv,noheader,nounits 2>/dev/null | head -1)
|
|
GPU_PCT=$(echo "$GPU_INFO" | awk -F', ' '{print $1}' | tr -d ' ')
|
|
GPU_TEMP=$(echo "$GPU_INFO" | awk -F', ' '{print $2}' | tr -d ' ')
|
|
else
|
|
GPU_PCT="null"
|
|
GPU_TEMP="null"
|
|
fi
|
|
|
|
# ── Uptime ──
|
|
UPTIME_SEC=$(awk '{printf "%d", $1}' /proc/uptime)
|
|
UPTIME_DAYS=$((UPTIME_SEC / 86400))
|
|
UPTIME_HRS=$(( (UPTIME_SEC % 86400) / 3600 ))
|
|
UPTIME_MINS=$(( (UPTIME_SEC % 3600) / 60 ))
|
|
if [ "$UPTIME_DAYS" -gt 0 ]; then
|
|
UPTIME_STR="${UPTIME_DAYS}d ${UPTIME_HRS}h ${UPTIME_MINS}m"
|
|
elif [ "$UPTIME_HRS" -gt 0 ]; then
|
|
UPTIME_STR="${UPTIME_HRS}h ${UPTIME_MINS}m"
|
|
else
|
|
UPTIME_STR="${UPTIME_MINS} minutes"
|
|
fi
|
|
|
|
# ── Write JSON atomically ──
|
|
TIMESTAMP=$(date -u +"%Y-%m-%dT%H:%M:%SZ")
|
|
|
|
cat > "$TMP" <<JSON
|
|
{
|
|
"updated": "$TIMESTAMP",
|
|
"cpu_pct": $CPU_PCT,
|
|
"gpu_pct": $GPU_PCT,
|
|
"gpu_temp": $GPU_TEMP,
|
|
"ram_pct": $RAM_PCT,
|
|
"ram_used": "${RAM_USED_GB} GB",
|
|
"ram_total": "${RAM_TOTAL_GB} GB",
|
|
"disk_pct": $DISK_PCT,
|
|
"disk_used": "${DISK_USED_GB} GB",
|
|
"disk_total": "${DISK_TOTAL_GB} TB",
|
|
"uptime": "$UPTIME_STR"
|
|
}
|
|
JSON
|
|
|
|
mv "$TMP" "$OUT"
|