[Shell Script] 서버 점검을 위한 스크립트 작성하기 #1

시나리오

매일 아침 운영 중인 리눅스 서버의 상태를 체크하는 것은 매우 번거로운 일이다.

서버의 로그를 일일이 확인하거나 시스템의 상태를 점검하는 작업이 수동으로 이루어지면 중요한 이슈를 놓치기 쉽고, 관리자에게는 큰 부담이 된다.


문제 정의

  • “서버의 리소스 사용량, 디스크 공간, 메모리 사용률, CPU 로드, 시스템 로그, 네트워크 상태” 등을 매일 점검해야 한다.
  • 그러나 이러한 작업을 일일이 수동으로 수행하면 실수가 발생할 수 있으며, 긴급한 이슈를 즉시 파악하기 어렵다.

스크립트 목적

  • 자동화된 점검 스크립트를 통해 서버의 주요 상태를 주기적으로 모니터링하고, 이상 상황이 감지되면 관리자에게 즉시 알림을 보냄으로써 문제를 조기에 발견하고 해결할 수 있다.

점검 대상

서버의 점검 대상은 다음과 같다.

  • 시스템 정보 출력: 운영체제 버전 및 현재 시간 출력
  • 부팅 정보 출력: 시스템 부팅 시간 및 운영 시간 출력
  • 현재 로그인 사용자 목록 출력
  • 파일 시스템 사용량 출력: 각 파일 시스템의 사용 용량 및 상태 출력
  • 시스템 리소스 모니터링: CPU, Memory, Swap
  • 실행 중인 프로세스 모니터링: 웹 서버, 도커 컨테이너 등의 실행 여부 확인
  • 디스크 상태 확인: SMART Health status를 통한 디스크 상태 확인

점검 주기

  • 매일 오전 8시에 자동으로 스크립트가 실행되어 점검 작업을 수행함.
  • 필요 시 주간 또는 월간으로 수집 데이터를 AI에 넘겨 요약 리포트 제공

결과 보고 방식

  • 점검 결과는 텍스트 파일로 저장하고, 이상이 감지된 경우 이메일, 슬랙, 텔레그램 등으로 알림을 보냄.
  • 이번 스크립트에서는 텔레그램 API를 사용할 것임.

스크립트

  • * Debian 환경에서 정상 작동함.
#!/usr/bin/bash

clear

# 시작 시간
CHECK_TIME="$(date '+%Y%m%d_%H:%M')"

# 로그 파일 지정
LOG_FILE="$CHECK_TIME.log"
exec 3>> "$LOG_FILE"

# 텔레그램 봇 정보
TELEGRAM_INFOS=( $(awk -F '=' '{print $2}' .telegram.env) )
TELEGRAM_TOKEN="${TELEGRAM_INFOS[0]}"
TELEGRAM_CHATID="${TELEGRAM_INFOS[1]}"

# 텔레그램 API 엔드포인트
TELEGRAM_TEXT_API_URL="https://api.telegram.org/bot${TELEGRAM_TOKEN}/sendMessage"
TELEGRAM_DOCUMENT_API_URL="https://api.telegram.org/bot${TELEGRAM_TOKEN}/sendDocument"

# 시스템 정보 출력
systemInfo() {
    echo "======================================================" >&3
    OS_VER="$(grep -i release /etc/*-release | perl -ane print)"
    echo "OS ver: $OS_VER" >&3
    echo "======================================================" >&3
    echo >&3
}

# 시스템 리소스 모니터링
systemResource() {
    echo "+------------------------------------------------------+" >&3
    echo "| 1. 시스템 점검 (CPU, Memory, Swap)                     |" >&3
    echo "+------------------------------------------------------+" >&3

    CPU_STATUS="$(sar 1 3 | grep 'Average' | perl -ane 'printf "$F[2]%"')"
    MEM_STATUS="$(free -h | grep 'Mem' | perl -ane 'printf "$F[1]/$F[2]"')"
    SWAP_STATUS="$(free -h | grep 'Swap' | perl -ane 'printf "$F[1]/$F[2]"')"
    echo "CPU STAT: $CPU_STATUS" >&3
    echo "MEM STAT: $MEM_STATUS" >&3
    echo "SWAP STAT: $SWAP_STATUS" >&3
    echo >&3
}

# 파일 시스템 상태
fileSystemUsage() {
    echo "+------------------------------------------------------+" >&3
    echo "| 2. 파일 시스템 사용량 점검                               |" >&3
    echo "+------------------------------------------------------+" >&3
    FILE_SYS="$(df -h | awk 'NR == 1; NR > 1 {print $0 | "sort -k6"}' >&3)"
    echo "File system usage: $FILE_SYS" >&3
    echo >&3
}

# 디스크 상태
DiskStatus() {
    echo "+------------------------------------------------------+" >&3
    echo "| 3. SMART Health Status                               |" >&3
    echo "+------------------------------------------------------+" >&3
    DISK_STATUS="$(smartctl -H /dev/sda | grep 'SMART Health Status:' | perl -ane 'printf "$F[3]"')"
    echo "SMART Health Status: $DISK_STATUS" >&3
    echo >&3
}


# 파일 시스템 사용량에 따른 상태 모니터링
FSUsageStatus() {
    echo "+------------------------------------------------------+" >&3
    echo "| 4. 파일 시스템 상태 체크                                |" >&3
    echo "+------------------------------------------------------+" >&3

    LEV_INFO=70 # INFO
    LEV_WAR=80 # Warning
    LEV_CRI=90 # Critical

    df -H | egrep -v '^Filesystem|tmpfs|cdrom|loop|udev'| while read -r output;
    do
        fs=$(echo "$output" | awk '{print $1}')
        size=$(echo "$output" | awk '{print $2}')
        used=$(echo "$output" | awk '{print $3}')
        avail=$(echo "$output" | awk '{print $4}')
        use_per=$(echo "$output" | awk '{print $5}' | cut -d'%' -f1)
        fmount=$(echo "$output" | awk '{print $6}')

    # 파일 시스템 상태에 따른 경고 수준 설정
    if [[ "$user_per" -ge "$LEV_CRI" ]]; then
        echo -e "[Critical] $fmount \t $size \t $used \t $avail \t" >&3
    elif [[ "$user_per" -ge "$LEV_WAR" ]]; then
        echo -e "[Warning] $fmount \t $size \t $used \t $avail \t" >&3
    elif [[ "$user_per" -ge "$LEV_INFO" ]]; then
        echo -e "[INFO] $fmount \t $size \t $used \t $avail \t" >&3
    else
        echo -e "[Nice] $fmount \t $size \t $used \t $avail \t" >&3
    fi
    echo >&3
    done
}

# 시스템 부팅 정보
systemBootInfo() {
    echo "+------------------------------------------------------+" >&3
    echo "| 5. 시스템 부팅 정보                                     |" >&3
    echo "+------------------------------------------------------+" >&3

    SYS_BOOT="$(who -b | perl -ane 'printf "$F[2] $F[3]"')"
    echo "$SYS_BOOT" >&3
    uptime >&3
    echo >&3
}

# 현재 로그인 사용자 목록 출력
LoginUsers() {
    echo "+------------------------------------------------------+" >&3
    echo "| 6. 로그인 사용자 목록                                   |" >&3
    echo "+------------------------------------------------------+" >&3
    who -u >&3
    echo >&3
}

# 프로세스 모니터링
processCheck() {
    echo "+------------------------------------------------------+" >&3
    echo "| 7. 프로세스 상태                                       |" >&3
    echo "+------------------------------------------------------+" >&3

    container="$(ps -ef | grep 'container' | grep -v grep | wc -l)"

    # 프로세스 상태 출력 
    if [[ $container -ge 1 ]]; then
        echo "Container=running" >&3
    else
        echo "Container=False" >&3
    fi
    echo >&3
}

# 텔레그램 전송
TelegramFile() {
    echo $LOG_FILE
    curl -s -X POST $TELEGRAM_DOCUMENT_API_URL -F "chat_id=$TELEGRAM_CHATID" -F "document=@$LOG_FILE"
}

TelegramText() {
    message="$1"
    curl -s -X POST $TELEGRAM_TEXT_API_URL -F "chat_id=$TELEGRAM_CHATID" -F "text=$message"
}


echo "======================================================"
echo "1. 시스템 정보 수집 중 ..."
systemInfo
echo "======================================================"

echo

echo "======================================================"
echo "2. 시스템 리소스 수집 중 ..."
systemResource
echo "======================================================"

echo

echo "======================================================"
echo "3. 파일 시스템 상태 수집 중 ..."
fileSystemUsage
echo "======================================================"

echo

echo "======================================================"
echo "4. 디스크 상태 수집 중 ..."
DiskStatus
echo "======================================================"

echo

echo "======================================================"
echo "5. 파일 시스템 사용량에 따른 상태 수집 중 ..."
FSUsageStatus
echo "======================================================"

echo

echo "======================================================"
echo "6. 시스템 부팅 정보 수집 중 ..."
systemBootInfo
echo "======================================================"

echo

echo "======================================================"
echo "7. 로그인 사용자 목록 수집 중 ..."
LoginUsers
echo "======================================================"

echo

echo "======================================================"
echo "8. 프로세스 상태 수집 중 ..."
processCheck
echo "======================================================"

echo

echo "======================================================"
echo "9. 텔레그램 메시지 전송 중 ..."
TelegramText "[$CHECK_TIME] 시스템 점검 파일"
TelegramFile
echo "======================================================"

실행 결과

chmod u+x script.sh
bash script.sh

image
image


텔레그램 결과
image

관련 글