반응형
왜 서버 일일 점검을 자동화해야 할까?
리눅스 서버를 운영하다 보면 매일 반복해야 하는 점검 항목들이 있습니다. CPU 사용률은 정상인지, 디스크가 꽉 차가고 있지는 않은지, 핵심 서비스는 살아있는지 — 이걸 매일 수작업으로 확인하는 건 시간 낭비이자 실수의 원인이 됩니다. Bash 쉘 스크립트와 cron을 조합하면 이 모든 점검을 완전 자동화하고, 이상 발생 시 즉시 알림까지 받을 수 있습니다.
이 글에서는 실무에서 바로 쓸 수 있는 Daily Check 스크립트를 단계별로 구성하는 방법을 다룹니다.
점검 항목 설계
일일 점검 스크립트는 크게 5가지 영역을 커버해야 합니다.
- 시스템 리소스: CPU, 메모리, Load Average
- 디스크 사용량: 마운트 포인트별 사용률
- 서비스 상태: nginx, mysql, sshd 등 핵심 데몬
- 네트워크: 포트 오픈 여부, 외부 통신 가능 여부
- 로그 이상 감지: /var/log/syslog에서 ERROR, CRITICAL 키워드 탐지
스크립트 전체 구조
아래는 실무에서 사용할 수 있는 daily_check.sh의 전체 구조입니다. 각 섹션별로 함수로 분리해서 유지보수가 쉽게 작성했습니다.
기본 설정 및 변수 선언
#!/bin/bash
# daily_check.sh — 리눅스 서버 일일 점검 스크립트
DATE=$(date '+%Y-%m-%d %H:%M:%S')
HOSTNAME=$(hostname)
LOG_FILE="/var/log/daily_check.log"
ALERT_EMAIL="admin@example.com"
CPU_THRESHOLD=80
MEM_THRESHOLD=85
DISK_THRESHOLD=90
RESULT=""
ALERT=0
log() {
echo "[$DATE] $1" | tee -a "$LOG_FILE"
RESULT+="$1\n"
}
CPU / 메모리 점검 함수
check_cpu() {
log "=== CPU 점검 ==="
CPU_USAGE=$(top -bn1 | grep "Cpu(s)" | awk '{print $2}' | cut -d'%' -f1 | cut -d',' -f1)
CPU_INT=${CPU_USAGE%.*}
if [ "$CPU_INT" -ge "$CPU_THRESHOLD" ]; then
log "[WARNING] CPU 사용률 높음: ${CPU_USAGE}%"
ALERT=1
else
log "[OK] CPU 사용률: ${CPU_USAGE}%"
fi
}
check_memory() {
log "=== 메모리 점검 ==="
MEM_TOTAL=$(free -m | awk '/Mem:/{print $2}')
MEM_USED=$(free -m | awk '/Mem:/{print $3}')
MEM_PERCENT=$(echo "scale=1; $MEM_USED * 100 / $MEM_TOTAL" | bc)
MEM_INT=${MEM_PERCENT%.*}
if [ "$MEM_INT" -ge "$MEM_THRESHOLD" ]; then
log "[WARNING] 메모리 사용률 높음: ${MEM_PERCENT}% (${MEM_USED}MB / ${MEM_TOTAL}MB)"
ALERT=1
else
log "[OK] 메모리 사용률: ${MEM_PERCENT}%"
fi
}
디스크 점검 함수
check_disk() {
log "=== 디스크 점검 ==="
df -h --output=pcent,target | tail -n +2 | while read -r line; do
USAGE=$(echo "$line" | awk '{print $1}' | tr -d '%')
MOUNT=$(echo "$line" | awk '{print $2}')
if [ "$USAGE" -ge "$DISK_THRESHOLD" ]; then
log "[WARNING] 디스크 사용률 높음: $MOUNT — ${USAGE}%"
ALERT=1
else
log "[OK] $MOUNT — ${USAGE}%"
fi
done
}
서비스 상태 점검 함수
SERVICES=("nginx" "mysql" "sshd" "cron")
check_services() {
log "=== 서비스 상태 점검 ==="
for SERVICE in "${SERVICES[@]}"; do
if systemctl is-active --quiet "$SERVICE"; then
log "[OK] $SERVICE: 실행 중"
else
log "[CRITICAL] $SERVICE: 중지됨!"
ALERT=1
fi
done
}
로그 이상 감지 및 알림 발송
check_logs() {
log "=== 로그 이상 감지 ==="
ERROR_COUNT=$(grep -c -iE "error|critical|failed" /var/log/syslog 2>/dev/null || echo 0)
log "최근 syslog ERROR/CRITICAL 건수: ${ERROR_COUNT}건"
if [ "$ERROR_COUNT" -gt 10 ]; then
log "[WARNING] 오류 로그 다수 감지"
ALERT=1
fi
}
send_alert() {
if [ "$ALERT" -eq 1 ]; then
echo -e "$RESULT" | mail -s "[ALERT] $HOSTNAME 일일 점검 이상 감지 — $DATE" "$ALERT_EMAIL"
log "알림 이메일 발송 완료: $ALERT_EMAIL"
else
log "모든 점검 정상. 알림 없음."
fi
}
# 메인 실행
log "=============================="
log "서버 일일 점검 시작: $HOSTNAME"
log "=============================="
check_cpu
check_memory
check_disk
check_services
check_logs
send_alert
log "점검 완료"
cron으로 매일 자동 실행 설정
스크립트 작성이 끝났다면 실행 권한을 부여하고 cron에 등록합니다.
chmod +x /usr/local/bin/daily_check.sh
crontab -e
crontab에 아래 줄을 추가하면 매일 오전 8시에 자동 실행됩니다.
0 8 * * * /usr/local/bin/daily_check.sh >> /var/log/daily_check.log 2>&1
실무 활용 팁
- 알림 채널 확장: mail 대신 curl로 Slack Webhook이나 Telegram Bot API를 호출하면 모바일로 즉시 알림을 받을 수 있습니다.
- 점검 항목 모듈화: 함수 단위로 분리되어 있으므로 서버 역할에 따라 필요한 함수만 골라서 실행할 수 있습니다.
- 로그 로테이션: logrotate 설정으로 daily_check.log가 무한정 쌓이지 않도록 관리하세요.
- 임계값 외부화: 임계값 변수를 별도 설정 파일(.conf)로 분리하면 스크립트 수정 없이 값을 바꿀 수 있습니다.
마무리
Bash 스크립트 하나로 CPU, 메모리, 디스크, 서비스, 로그까지 한 번에 점검하고 이상 시 자동 알림까지 보내는 시스템을 구축할 수 있습니다. 처음에는 단순한 스크립트로 시작해서 운영 환경에 맞게 점진적으로 확장하는 것이 가장 현실적인 접근 방법입니다. 서버가 늘어날수록 자동화의 가치는 더욱 커집니다.
반응형
'IT > 리눅스' 카테고리의 다른 글
| 리눅스 파일 타임스탬프 완전 정복 — ctime, mtime, atime 차이점과 실무 활용법 (0) | 2026.03.18 |
|---|---|
| 리눅스 시스템 엔지니어를 위한 필수 네트워크 트러블슈팅 명령어 총정리 (0) | 2026.03.18 |
| linux disk 삭제 쉘 (0) | 2025.10.22 |
| 리눅스에서 Network Teaming과 Bonding의 차이점 완벽 비교 (0) | 2025.02.20 |
| NTP를 통한 서버 시간 동기화 완벽 가이드: 설정, 문제 해결, 보안 강화까지 (2) | 2024.12.12 |