프로젝트 3: 서버 모니터링 대시보드
세 번째 프로젝트는 서버 모니터링입니다. CPU가 갑자기 100%로 치솟거나 디스크가 가득 차면 빠르게 알아야 합니다. 터미널에서 바로 현황을 확인하고, 임계값을 넘으면 색상으로 경고를 표시합니다.
요구사항
- CPU, 메모리, 디스크, 네트워크 연결 수를 측정합니다.
- 임계값은 설정 파일에서 읽습니다.
- 정상은 초록, 경고는 노랑, 위험은 빨강으로 표시합니다.
- 측정값을 CSV 형식으로 기록합니다.
설정 파일
# 새 파일: /home/ubuntu/scripts/monitor.conf# CPU 사용률 임계값 (%)CPU_WARN=70CPU_CRIT=90# 메모리 사용률 임계값 (%)MEM_WARN=80MEM_CRIT=95# 디스크 사용률 임계값 (%)DISK_WARN=80DISK_CRIT=90# 네트워크 연결 수 임계값NET_WARN=500NET_CRIT=1000# CSV 히스토리 파일HISTORY_FILE="/tmp/server_monitor_history.csv"# 히스토리 보관 줄 수 (0이면 무제한)HISTORY_MAX_LINES=1000
모니터링 스크립트
#!/usr/bin/env bash# 새 파일: /home/ubuntu/scripts/server_monitor.shset -euo pipefail# ==============================================================# 설정 파일 로드# ==============================================================SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"CONFIG_FILE="${SCRIPT_DIR}/monitor.conf"if [[ -f "$CONFIG_FILE" ]]; then source "$CONFIG_FILE"else # 기본값 CPU_WARN=70; CPU_CRIT=90 MEM_WARN=80; MEM_CRIT=95 DISK_WARN=80; DISK_CRIT=90 NET_WARN=500; NET_CRIT=1000 HISTORY_FILE="/tmp/server_monitor_history.csv" HISTORY_MAX_LINES=1000fi# ==============================================================# 색상 정의# ==============================================================RED='\033[0;31m'YELLOW='\033[1;33m'GREEN='\033[0;32m'CYAN='\033[0;36m'BOLD='\033[1m'RESET='\033[0m'# ==============================================================# 색상 판단 함수# ==============================================================# 사용법: color_status <현재값> <경고임계값> <위험임계값>color_status() { local value="$1" local warn="$2" local crit="$3" local int_value="${value%.*}" # 소수점 제거 if (( int_value >= crit )); then echo -e "${RED}" elif (( int_value >= warn )); then echo -e "${YELLOW}" else echo -e "${GREEN}" fi}print_metric() { local label="$1" local value="$2" local unit="$3" local warn="$4" local crit="$5" local extra="${6:-}" local color color=$(color_status "$value" "$warn" "$crit") local int_value="${value%.*}" local status_icon if (( int_value >= crit )); then status_icon="[위험]" elif (( int_value >= warn )); then status_icon="[경고]" else status_icon="[정상]" fi printf " ${BOLD}%-20s${RESET} ${color}%6s%s %s${RESET} %s\n" \ "$label" "$value" "$unit" "$status_icon" "$extra"}# ==============================================================# 지표 수집 함수# ==============================================================get_cpu_usage() { # top을 2회 실행 후 두 번째 결과로 더 정확한 값 측정 top -bn2 | grep "Cpu(s)" | tail -1 | awk '{ # idle이 4번째 숫자 - 100에서 빼면 사용률 for(i=1;i<=NF;i++) if($i ~ /id,/) { idle=$(i-1); break } printf "%.1f", 100 - idle }'}get_mem_usage() { free | awk 'NR==2{ used=$3; total=$2 printf "%.1f", used/total*100 }'}get_mem_detail() { free -h | awk 'NR==2{print $3 "/" $2}'}get_disk_usage() { df / | awk 'NR==2{print $5}' | tr -d '%'}get_disk_detail() { df -h / | awk 'NR==2{print $3 "/" $2}'}get_net_connections() { ss -tun 2>/dev/null | grep -c "ESTAB" || echo "0"}get_load_avg() { uptime | awk -F'load average:' '{print $2}' | tr -d ' '}# ==============================================================# 대시보드 출력# ==============================================================clearTIMESTAMP=$(date '+%Y-%m-%d %H:%M:%S')HOSTNAME=$(hostname)echo -e "${BOLD}${CYAN}"echo "╔══════════════════════════════════════════════════╗"echo "║ 서버 모니터링 대시보드 ║"echo "╚══════════════════════════════════════════════════╝"echo -e "${RESET}"echo -e " 호스트: ${BOLD}${HOSTNAME}${RESET} 시간: ${TIMESTAMP}"echo " 부하 평균: $(get_load_avg)"echo ""echo -e "${BOLD} 지표 현재값 상태 상세${RESET}"echo " ─────────────────────────────────────────────────"# 지표 수집CPU=$(get_cpu_usage)MEM=$(get_mem_usage)MEM_DETAIL=$(get_mem_detail)DISK=$(get_disk_usage)DISK_DETAIL=$(get_disk_detail)NET=$(get_net_connections)# 출력print_metric "CPU 사용률" "$CPU" "%" "$CPU_WARN" "$CPU_CRIT"print_metric "메모리 사용률" "$MEM" "%" "$MEM_WARN" "$MEM_CRIT" "($MEM_DETAIL)"print_metric "디스크 사용률" "$DISK" "%" "$DISK_WARN" "$DISK_CRIT" "($DISK_DETAIL)"print_metric "네트워크 연결" "$NET" "개" "$NET_WARN" "$NET_CRIT"echo ""# ==============================================================# CSV 히스토리 기록# ==============================================================# 헤더가 없으면 추가if [[ ! -f "$HISTORY_FILE" ]]; then echo "timestamp,cpu,mem,disk,net_connections" > "$HISTORY_FILE"fiecho "${TIMESTAMP},${CPU},${MEM},${DISK},${NET}" >> "$HISTORY_FILE"# 히스토리 줄 수 제한if [[ "${HISTORY_MAX_LINES:-0}" -gt 0 ]]; then CURRENT_LINES=$(wc -l < "$HISTORY_FILE") if (( CURRENT_LINES > HISTORY_MAX_LINES + 1 )); then # 헤더 보존하면서 오래된 줄 제거 HEADER=$(head -1 "$HISTORY_FILE") TAIL_LINES=$(tail -n "$HISTORY_MAX_LINES" "$HISTORY_FILE") { echo "$HEADER"; echo "$TAIL_LINES"; } > "${HISTORY_FILE}.tmp" mv "${HISTORY_FILE}.tmp" "$HISTORY_FILE" fifiecho -e " 히스토리: ${HISTORY_FILE}"echo ""
실행 결과
chmod +x /home/ubuntu/scripts/server_monitor.sh/home/ubuntu/scripts/server_monitor.sh
터미널에서 보이는 결과입니다.
╔══════════════════════════════════════════════════╗
║ 서버 모니터링 대시보드 ║
╚══════════════════════════════════════════════════╝
호스트: myserver 시간: 2026-04-24 09:20:01
부하 평균: 0.15, 0.12, 0.10
지표 현재값 상태 상세
─────────────────────────────────────────────────
CPU 사용률 3.2% [정상]
메모리 사용률 45.8% [정상] (1876M/4096M)
디스크 사용률 34% [정상] (17G/50G)
네트워크 연결 3개 [정상]
히스토리: /tmp/server_monitor_history.csv
정상 구간은 초록, 경고 구간은 노랑, 위험 구간은 빨강으로 표시됩니다. 실제 터미널에서 실행하면 색상이 보입니다.
CSV 히스토리 확인
cat /tmp/server_monitor_history.csv
timestamp,cpu,mem,disk,net_connections
2026-04-24 09:20:01,3.2,45.8,34,3
2026-04-24 09:25:01,2.8,46.1,34,4
2026-04-24 09:30:01,4.5,46.3,34,3
crontab 등록
crontab -e
# 5분마다 서버 상태 기록 (대시보드 없이 히스토리만)
*/5 * * * * /home/ubuntu/scripts/server_monitor.sh > /dev/null 2>&1