서버 장애의 80%는 사전 모니터링으로 예방할 수 있습니다. CPU, 메모리, 디스크, 네트워크 등 핵심 시스템 메트릭을 실시간으로 확인하고 임계치를 설정하는 것은 시스템 관리의 기본입니다. 이 글에서는 Linux에서 사용 가능한 모던 모니터링 명령어와 도구들을 실전 활용법과 함께 상세히 다룹니다.

CPU 모니터링

htop / btop - 대화형 프로세스 관리

# btop 설치 (htop의 진화형)
sudo apt install btop    # Ubuntu
brew install btop        # macOS

# btop 실행
btop
# CPU 코어별 사용률, 메모리, 네트워크, 디스크를 한 화면에
# 프로세스 트리, 정렬, 필터, 시그널 전송 지원

mpstat - CPU 코어별 상세 통계

# 모든 CPU 코어의 1초 간격 통계
mpstat -P ALL 1

# 출력 해석
# %usr: 사용자 프로세스 CPU 사용률
# %sys: 커널 CPU 사용률
# %iowait: I/O 대기 시간 (높으면 디스크 병목)
# %idle: 유휴 시간

# 특정 코어만 확인
mpstat -P 0,1,2,3 1 5    # 코어 0~3, 1초 간격, 5회

# iowait이 높을 때 (디스크 병목)
# -> iotop으로 어떤 프로세스가 I/O를 많이 쓰는지 확인
sudo iotop -oP

pidstat - 프로세스별 CPU 사용률

# 프로세스별 CPU 사용률 (1초 간격)
pidstat 1

# 특정 프로세스의 CPU + 메모리 + I/O
pidstat -p $(pgrep java) -u -r -d 1

# 스레드별 CPU 사용률
pidstat -t -p $(pgrep nginx) 1

메모리 모니터링

# free - 메모리 요약
free -h
# 출력:
#               total    used    free    shared  buff/cache   available
# Mem:           32Gi    12Gi    4.5Gi   256Mi      15Gi        19Gi
# Swap:          8.0Gi   0Bi     8.0Gi

# 핵심 지표:
# - available: 실제 사용 가능한 메모리 (free + reclaimable cache)
# - buff/cache: 커널이 캐시로 사용 중 (필요 시 해제 가능)
# - swap used: 0이 아니면 물리 메모리 부족 신호

# 1초 간격으로 반복 확인
watch -n 1 free -h

# vmstat - 가상 메모리 상세
vmstat 1
# si/so: swap in/out (0이어야 정상)
# bi/bo: block I/O
# wa: I/O wait

# 메모리를 많이 쓰는 프로세스 Top 10
ps aux --sort=-%mem | head -11

# /proc/meminfo에서 상세 정보
cat /proc/meminfo | grep -E 'MemTotal|MemFree|MemAvailable|Buffers|Cached|SwapTotal|SwapFree'

디스크 모니터링

# df - 파일시스템 용량
df -hT
# -h: 읽기 쉬운 단위
# -T: 파일시스템 타입 표시

# inode 사용량 (파일 개수 제한)
df -i

# du - 디렉토리별 용량
du -sh /var/log/*  | sort -rh | head -20
# 로그 디렉토리에서 큰 파일 찾기

# ncdu - 대화형 디스크 사용량 분석
sudo apt install ncdu
ncdu /
# 시각적 트리 뷰로 큰 디렉토리/파일 빠르게 찾기

# iostat - 디스크 I/O 성능
iostat -xz 1
# %util: 디스크 활용률 (80% 이상이면 병목)
# await: I/O 대기 시간 (ms)
# r/s, w/s: 초당 읽기/쓰기 횟수
# rkB/s, wkB/s: 초당 읽기/쓰기 KB

# 어떤 프로세스가 I/O를 많이 쓰는지
sudo iotop -oP -b -d 2 -n 5
# -o: I/O 발생 프로세스만
# -P: 프로세스 단위 (스레드 아닌)
# -b: 배치 모드

# 디스크 성능 벤치마크
fio --name=randread --ioengine=libaio --iodepth=32 \
    --rw=randread --bs=4k --direct=1 --size=1G \
    --numjobs=4 --runtime=60 --group_reporting

네트워크 모니터링

# ss - 소켓 통계 (netstat 대체)
ss -tuln          # TCP/UDP 리스닝 포트
ss -tp            # TCP 연결 + 프로세스 정보
ss -s             # 소켓 요약 통계
ss state time-wait | wc -l   # TIME_WAIT 연결 수

# 특정 포트 확인
ss -tlnp | grep :8080

# nethogs - 프로세스별 대역폭 사용량
sudo nethogs eth0
# 어떤 프로세스가 네트워크를 많이 쓰는지 실시간 확인

# iftop - 연결별 대역폭
sudo iftop -i eth0 -nNP
# 어떤 IP와 얼마나 통신하는지 시각화

# nload - 인터페이스별 트래픽 그래프
nload eth0
# 실시간 인바운드/아웃바운드 그래프

# 네트워크 지연 진단
mtr google.com
# traceroute + ping 결합 - 경로별 지연/손실 실시간 확인

# 대역폭 측정
iperf3 -s              # 서버 모드
iperf3 -c server-ip    # 클라이언트에서 측정

통합 모니터링 스크립트

#!/bin/bash
# system-health.sh - 시스템 상태 요약

echo "========== SYSTEM HEALTH CHECK =========="
echo "Date: $(date '+%Y-%m-%d %H:%M:%S')"
echo "Hostname: $(hostname)"
echo "Uptime: $(uptime -p)"
echo ""

# CPU
echo "--- CPU ---"
CPU_USAGE=$(top -bn1 | grep 'Cpu(s)' | awk '{print $2 + $4}')%
LOAD=$(cat /proc/loadavg | awk '{print $1, $2, $3}')
echo "Usage: $CPU_USAGE | Load Average: $LOAD"
echo ""

# 메모리
echo "--- MEMORY ---"
free -h | awk '/^Mem:/ {printf "Used: %s / %s (Available: %s)\n", $3, $2, $7}'
free -h | awk '/^Swap:/ {printf "Swap: %s / %s\n", $3, $2}'
echo ""

# 디스크
echo "--- DISK ---"
df -hT | awk 'NR==1 || $6+0 > 70 {print}'  # 70% 이상만 경고
echo ""

# 네트워크
echo "--- TOP CONNECTIONS ---"
ss -tn state established | awk '{print $5}' | \
  cut -d: -f1 | sort | uniq -c | sort -rn | head -5
echo ""

# 고부하 프로세스
echo "--- TOP PROCESSES (CPU) ---"
ps aux --sort=-%cpu | head -6
echo ""
echo "--- TOP PROCESSES (MEM) ---"
ps aux --sort=-%mem | head -6

echo "=========================================="

자동 알림 설정 (cron + 메일)

#!/bin/bash
# alert-check.sh - 임계치 초과 시 알림

THRESHOLD_CPU=80
THRESHOLD_MEM=90
THRESHOLD_DISK=85

# CPU 체크
CPU=$(top -bn1 | grep 'Cpu(s)' | awk '{printf "%.0f", $2 + $4}')
if [ "$CPU" -gt "$THRESHOLD_CPU" ]; then
  echo "CPU Alert: ${CPU}% (threshold: ${THRESHOLD_CPU}%)" | \
    mail -s "[ALERT] High CPU on $(hostname)" admin@example.com
fi

# 메모리 체크
MEM=$(free | awk '/Mem:/ {printf "%.0f", $3/$2 * 100}')
if [ "$MEM" -gt "$THRESHOLD_MEM" ]; then
  echo "Memory Alert: ${MEM}% used" | \
    mail -s "[ALERT] High Memory on $(hostname)" admin@example.com
fi

# 디스크 체크
df -h | awk 'NR>1 {gsub(/%/,"",$5); if($5 > '$THRESHOLD_DISK') \
  printf "Disk Alert: %s at %s%%\n", $6, $5}' | \
  while read line; do
    echo "$line" | mail -s "[ALERT] Disk on $(hostname)" admin@example.com
  done
# crontab 등록 (5분 간격)
crontab -e
*/5 * * * * /opt/scripts/alert-check.sh 2>/dev/null

시스템 모니터링은 문제가 발생하기 전에 미리 감지하는 것이 핵심입니다. btop으로 실시간 상황을 파악하고, iostat과 pidstat으로 병목 지점을 정밀 분석하며, 자동 알림 스크립트로 임계치 초과를 즉시 인지하는 3단계 모니터링 체계를 구축하면 대부분의 시스템 장애를 사전에 예방할 수 있습니다.