Profile picture

[Shell Script] 서버 점검용 bash 스크립트 작성

JaehyoJJAng2024년 05월 12일

시나리오

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

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


문제 정의

  • "서버의 리소스 사용량, 디스크 공간, 메모리 사용률, 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


Loading script...