250 lines
8.1 KiB
Bash
Executable File
250 lines
8.1 KiB
Bash
Executable File
#!/bin/bash
|
|
|
|
# =============================================================================
|
|
# Document Server - Synology DS1525+ 모니터링 스크립트
|
|
# 시스템 리소스 및 서비스 상태 모니터링
|
|
# =============================================================================
|
|
|
|
set -e
|
|
|
|
# 색상 정의
|
|
RED='\033[0;31m'
|
|
GREEN='\033[0;32m'
|
|
YELLOW='\033[1;33m'
|
|
BLUE='\033[0;34m'
|
|
CYAN='\033[0;36m'
|
|
NC='\033[0m'
|
|
|
|
# 로그 함수
|
|
log_info() {
|
|
echo -e "${BLUE}[INFO]${NC} $1"
|
|
}
|
|
|
|
log_success() {
|
|
echo -e "${GREEN}[SUCCESS]${NC} $1"
|
|
}
|
|
|
|
log_warning() {
|
|
echo -e "${YELLOW}[WARNING]${NC} $1"
|
|
}
|
|
|
|
log_error() {
|
|
echo -e "${RED}[ERROR]${NC} $1"
|
|
}
|
|
|
|
# 환경 설정
|
|
COMPOSE_FILE="docker-compose.synology.yml"
|
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
PROJECT_DIR="$(dirname "$SCRIPT_DIR")"
|
|
|
|
cd "$PROJECT_DIR"
|
|
|
|
echo "=== 📊 Synology DS1525+ Document Server 모니터링 ==="
|
|
echo "$(date '+%Y-%m-%d %H:%M:%S')"
|
|
echo ""
|
|
|
|
# 1. 시스템 리소스 확인
|
|
log_info "🖥️ 시스템 리소스 상태"
|
|
|
|
# CPU 사용률
|
|
CPU_USAGE=$(top -bn1 | grep "Cpu(s)" | awk '{print $2}' | awk -F'%' '{print $1}')
|
|
echo -e "CPU 사용률: ${CYAN}${CPU_USAGE}%${NC}"
|
|
|
|
# 메모리 사용률 (32GB 기준)
|
|
MEMORY_INFO=$(free -h | grep "Mem:")
|
|
TOTAL_MEM=$(echo $MEMORY_INFO | awk '{print $2}')
|
|
USED_MEM=$(echo $MEMORY_INFO | awk '{print $3}')
|
|
AVAILABLE_MEM=$(echo $MEMORY_INFO | awk '{print $7}')
|
|
MEM_PERCENT=$(free | grep "Mem:" | awk '{printf "%.1f", ($3/$2) * 100.0}')
|
|
|
|
echo -e "메모리: ${CYAN}${USED_MEM}${NC}/${CYAN}${TOTAL_MEM}${NC} (${CYAN}${MEM_PERCENT}%${NC}) | 사용 가능: ${GREEN}${AVAILABLE_MEM}${NC}"
|
|
|
|
# 디스크 사용률
|
|
echo -e "\n${BLUE}💾 디스크 사용률:${NC}"
|
|
df -h /volume1 /volume2 | grep -E "(volume1|volume2)" | while read line; do
|
|
USAGE=$(echo $line | awk '{print $5}' | sed 's/%//')
|
|
MOUNT=$(echo $line | awk '{print $6}')
|
|
USED=$(echo $line | awk '{print $3}')
|
|
TOTAL=$(echo $line | awk '{print $2}')
|
|
|
|
if [ "$USAGE" -gt 90 ]; then
|
|
echo -e " ${RED}${MOUNT}${NC}: ${RED}${USED}${NC}/${TOTAL} (${RED}${USAGE}%${NC}) ⚠️"
|
|
elif [ "$USAGE" -gt 80 ]; then
|
|
echo -e " ${YELLOW}${MOUNT}${NC}: ${YELLOW}${USED}${NC}/${TOTAL} (${YELLOW}${USAGE}%${NC})"
|
|
else
|
|
echo -e " ${GREEN}${MOUNT}${NC}: ${CYAN}${USED}${NC}/${TOTAL} (${GREEN}${USAGE}%${NC})"
|
|
fi
|
|
done
|
|
|
|
echo ""
|
|
|
|
# 2. Docker 컨테이너 상태
|
|
log_info "🐳 Docker 컨테이너 상태"
|
|
|
|
if [ -f "$COMPOSE_FILE" ]; then
|
|
# 컨테이너 상태 확인
|
|
CONTAINERS=$(docker-compose -f "$COMPOSE_FILE" ps --format "table {{.Name}}\t{{.State}}\t{{.Ports}}")
|
|
echo "$CONTAINERS"
|
|
|
|
echo ""
|
|
|
|
# 각 서비스별 상태 확인
|
|
SERVICES=("database" "redis" "backend" "nginx")
|
|
for service in "${SERVICES[@]}"; do
|
|
STATUS=$(docker-compose -f "$COMPOSE_FILE" ps -q "$service" 2>/dev/null)
|
|
if [ -n "$STATUS" ]; then
|
|
HEALTH=$(docker inspect --format='{{.State.Health.Status}}' $(docker-compose -f "$COMPOSE_FILE" ps -q "$service") 2>/dev/null || echo "no-healthcheck")
|
|
if [ "$HEALTH" = "healthy" ]; then
|
|
log_success "$service: 정상 (healthy)"
|
|
elif [ "$HEALTH" = "unhealthy" ]; then
|
|
log_error "$service: 비정상 (unhealthy)"
|
|
else
|
|
log_warning "$service: 헬스체크 없음"
|
|
fi
|
|
else
|
|
log_error "$service: 실행 중이지 않음"
|
|
fi
|
|
done
|
|
else
|
|
log_error "Docker Compose 파일을 찾을 수 없습니다: $COMPOSE_FILE"
|
|
fi
|
|
|
|
echo ""
|
|
|
|
# 3. 리소스 사용량 (컨테이너별)
|
|
log_info "📈 컨테이너별 리소스 사용량"
|
|
|
|
if command -v docker &> /dev/null; then
|
|
# Docker stats 정보 (1회성)
|
|
docker stats --no-stream --format "table {{.Name}}\t{{.CPUPerc}}\t{{.MemUsage}}\t{{.MemPerc}}\t{{.NetIO}}\t{{.BlockIO}}" | head -10
|
|
else
|
|
log_error "Docker가 설치되지 않았습니다"
|
|
fi
|
|
|
|
echo ""
|
|
|
|
# 4. 네트워크 연결 상태
|
|
log_info "🌐 네트워크 연결 상태"
|
|
|
|
# 포트 확인
|
|
PORTS=("24100:nginx" "24101:database" "24102:backend" "24103:redis")
|
|
for port_info in "${PORTS[@]}"; do
|
|
PORT=$(echo $port_info | cut -d: -f1)
|
|
SERVICE=$(echo $port_info | cut -d: -f2)
|
|
|
|
if netstat -tuln | grep -q ":$PORT "; then
|
|
log_success "$SERVICE (포트 $PORT): 리스닝 중"
|
|
else
|
|
log_error "$SERVICE (포트 $PORT): 리스닝하지 않음"
|
|
fi
|
|
done
|
|
|
|
echo ""
|
|
|
|
# 5. 로그 파일 크기 확인
|
|
log_info "📝 로그 파일 상태"
|
|
|
|
LOG_DIRS=(
|
|
"/volume1/docker/document-server/logs"
|
|
"/volume1/docker/document-server/logs/nginx"
|
|
)
|
|
|
|
for log_dir in "${LOG_DIRS[@]}"; do
|
|
if [ -d "$log_dir" ]; then
|
|
LOG_SIZE=$(du -sh "$log_dir" 2>/dev/null | cut -f1)
|
|
echo -e " ${CYAN}${log_dir}${NC}: ${LOG_SIZE}"
|
|
|
|
# 큰 로그 파일 경고 (1GB 이상)
|
|
LOG_SIZE_MB=$(du -sm "$log_dir" 2>/dev/null | cut -f1)
|
|
if [ "$LOG_SIZE_MB" -gt 1024 ]; then
|
|
log_warning "로그 디렉토리가 1GB를 초과했습니다: $log_dir"
|
|
fi
|
|
else
|
|
log_warning "로그 디렉토리가 존재하지 않습니다: $log_dir"
|
|
fi
|
|
done
|
|
|
|
echo ""
|
|
|
|
# 6. 데이터베이스 연결 테스트
|
|
log_info "🗄️ 데이터베이스 연결 테스트"
|
|
|
|
if docker-compose -f "$COMPOSE_FILE" ps -q database >/dev/null 2>&1; then
|
|
DB_STATUS=$(docker-compose -f "$COMPOSE_FILE" exec -T database pg_isready -U docuser -d document_db 2>/dev/null)
|
|
if echo "$DB_STATUS" | grep -q "accepting connections"; then
|
|
log_success "PostgreSQL: 연결 가능"
|
|
|
|
# 데이터베이스 크기 확인
|
|
DB_SIZE=$(docker-compose -f "$COMPOSE_FILE" exec -T database psql -U docuser -d document_db -t -c "SELECT pg_size_pretty(pg_database_size('document_db'));" 2>/dev/null | xargs)
|
|
echo -e " 데이터베이스 크기: ${CYAN}${DB_SIZE}${NC}"
|
|
else
|
|
log_error "PostgreSQL: 연결 실패"
|
|
fi
|
|
else
|
|
log_error "데이터베이스 컨테이너가 실행 중이지 않습니다"
|
|
fi
|
|
|
|
echo ""
|
|
|
|
# 7. Redis 연결 테스트
|
|
log_info "💾 Redis 연결 테스트"
|
|
|
|
if docker-compose -f "$COMPOSE_FILE" ps -q redis >/dev/null 2>&1; then
|
|
REDIS_STATUS=$(docker-compose -f "$COMPOSE_FILE" exec -T redis redis-cli ping 2>/dev/null)
|
|
if [ "$REDIS_STATUS" = "PONG" ]; then
|
|
log_success "Redis: 연결 가능"
|
|
|
|
# Redis 메모리 사용량
|
|
REDIS_MEMORY=$(docker-compose -f "$COMPOSE_FILE" exec -T redis redis-cli info memory | grep "used_memory_human" | cut -d: -f2 | tr -d '\r')
|
|
echo -e " 메모리 사용량: ${CYAN}${REDIS_MEMORY}${NC}"
|
|
else
|
|
log_error "Redis: 연결 실패"
|
|
fi
|
|
else
|
|
log_error "Redis 컨테이너가 실행 중이지 않습니다"
|
|
fi
|
|
|
|
echo ""
|
|
|
|
# 8. 백업 상태 확인
|
|
log_info "💾 백업 상태 확인"
|
|
|
|
BACKUP_DIR="/volume2/document-storage/backups"
|
|
if [ -d "$BACKUP_DIR" ]; then
|
|
BACKUP_COUNT=$(find "$BACKUP_DIR" -name "*.sql" -mtime -1 | wc -l)
|
|
LATEST_BACKUP=$(find "$BACKUP_DIR" -name "*.sql" -type f -printf '%T@ %p\n' 2>/dev/null | sort -n | tail -1 | cut -d' ' -f2- | xargs basename 2>/dev/null || echo "없음")
|
|
|
|
echo -e " 백업 디렉토리: ${CYAN}${BACKUP_DIR}${NC}"
|
|
echo -e " 최근 24시간 백업: ${CYAN}${BACKUP_COUNT}개${NC}"
|
|
echo -e " 최신 백업: ${CYAN}${LATEST_BACKUP}${NC}"
|
|
|
|
if [ "$BACKUP_COUNT" -eq 0 ]; then
|
|
log_warning "최근 24시간 내 백업이 없습니다"
|
|
fi
|
|
else
|
|
log_error "백업 디렉토리가 존재하지 않습니다: $BACKUP_DIR"
|
|
fi
|
|
|
|
echo ""
|
|
|
|
# 9. 권장 사항
|
|
log_info "💡 권장 사항"
|
|
|
|
# 메모리 사용률이 높은 경우
|
|
if [ "${MEM_PERCENT%.*}" -gt 80 ]; then
|
|
log_warning "메모리 사용률이 높습니다 (${MEM_PERCENT}%). 모니터링이 필요합니다."
|
|
fi
|
|
|
|
# 디스크 사용률 확인
|
|
HIGH_DISK_USAGE=$(df /volume1 /volume2 | awk 'NR>1 {gsub(/%/, "", $5); if ($5 > 85) print $6 " (" $5 "%)"}')
|
|
if [ -n "$HIGH_DISK_USAGE" ]; then
|
|
log_warning "디스크 사용률이 높은 볼륨: $HIGH_DISK_USAGE"
|
|
fi
|
|
|
|
echo ""
|
|
echo "=== 모니터링 완료 ==="
|
|
echo "다음 명령어로 실시간 모니터링 가능:"
|
|
echo " watch -n 5 '$0'"
|
|
echo " docker-compose -f $COMPOSE_FILE logs -f"
|
|
echo " docker stats"
|