#!/bin/bash # 인페인팅 서버 상태 확인 스크립트 # Usage: ./status.sh [options] 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' # No Color # 로그 함수들 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" } # 기본 설정 - 동적 경로 처리 SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" PROJECT_ROOT="$(dirname "$SCRIPT_DIR")" LOG_DIR="$PROJECT_ROOT/logs" MAIN_PORT=8008 MONITORING_PORT=8888 # 옵션 파싱 DETAILED=false JSON_OUTPUT=false WATCH_MODE=false while [[ $# -gt 0 ]]; do case $1 in -d|--detailed) DETAILED=true shift ;; -j|--json) JSON_OUTPUT=true shift ;; -w|--watch) WATCH_MODE=true shift ;; -h|--help) echo "Usage: $0 [options]" echo "Options:" echo " -d, --detailed 자세한 상태 정보 표시" echo " -j, --json JSON 형식으로 출력" echo " -w, --watch 실시간 모니터링 모드" echo " -h, --help 이 도움말 표시" exit 0 ;; *) log_error "알 수 없는 옵션: $1" exit 1 ;; esac done # 시스템 감지 detect_system() { if [ "$(uname -m)" = "aarch64" ] && uname -a | grep -q "tegra"; then SYSTEM_TYPE="jetson" log_info "🚁 Jetson Xavier (ARM64) 모드로 상태 확인합니다" elif [ "$(uname -m)" = "x86_64" ]; then SYSTEM_TYPE="x86" log_info "💻 x86_64 모드로 상태 확인합니다" else SYSTEM_TYPE="unknown" log_warning "알 수 없는 시스템 아키텍처: $(uname -m)" fi } # GPU 상태 확인 check_gpu_status() { if [ "$SYSTEM_TYPE" = "jetson" ]; then log_info "Jetson Xavier GPU 상태 확인 중..." # Jetson 전용 확인 방법들 jetson_gpu_available=false # 1. tegrastats 확인 if command -v tegrastats &> /dev/null; then jetson_gpu_available=true log_info "tegrastats 사용 가능" # Jetson 시스템 정보 표시 log_info "Jetson 시스템 정보:" tegrastats -1 | head -10 else log_warning "tegrastats를 찾을 수 없습니다" fi # 2. nvpmodel 확인 if command -v nvpmodel &> /dev/null; then jetson_gpu_available=true log_info "nvpmodel 사용 가능" # 전력 모드 정보 표시 log_info "Jetson 전력 모드:" nvpmodel -q else log_warning "nvpmodel을 찾을 수 없습니다" fi # 3. GPU 디바이스 확인 if [ -e "/sys/kernel/debug/gpu" ] || [ -d "/dev/nvidia*" ]; then jetson_gpu_available=true log_info "GPU 디바이스 감지됨" # GPU 메모리 정보 (가능한 경우) if [ -e "/sys/kernel/debug/gpu/memory" ]; then log_info "GPU 메모리 정보:" cat /sys/kernel/debug/gpu/memory | head -5 fi else log_warning "GPU 디바이스를 찾을 수 없습니다" fi # 4. 온도 정보 확인 if [ -d "/sys/devices/virtual/thermal" ]; then log_info "Jetson 온도 정보:" for zone in /sys/devices/virtual/thermal/thermal_zone*; do if [ -f "$zone/temp" ]; then temp=$(cat "$zone/temp") temp_c=$((temp / 1000)) zone_name=$(basename "$zone") echo " $zone_name: ${temp_c}°C" fi done fi if [ "$jetson_gpu_available" = true ]; then log_success "Jetson Xavier GPU 상태 확인 완료" else log_warning "Jetson Xavier GPU 상태 확인 실패" fi return 0 elif ! command -v nvidia-smi &> /dev/null; then log_warning "nvidia-smi를 찾을 수 없습니다" return 1 fi # x86 시스템용 기존 확인 방법 local gpu_info=$(nvidia-smi --query-gpu=name,memory.total,memory.used,memory.free,utilization.gpu --format=csv,noheader,nounits 2>/dev/null) if [ -z "$gpu_info" ]; then log_error "GPU 정보를 가져올 수 없습니다" return 1 fi if [ "$JSON_OUTPUT" = true ]; then echo -n "\"gpu\": {" echo -n "\"available\": true," IFS=',' read -r name total used free util <<< "$gpu_info" echo -n "\"name\": \"$(echo $name | xargs)\"," echo -n "\"memory_total\": $(echo $total | xargs)," echo -n "\"memory_used\": $(echo $used | xargs)," echo -n "\"memory_free\": $(echo $free | xargs)," echo -n "\"utilization\": $(echo $util | xargs)" echo -n "}" else echo -e "${CYAN}GPU 상태:${NC}" IFS=',' read -r name total used free util <<< "$gpu_info" printf " GPU: %s\n" "$(echo $name | xargs)" printf " 메모리: %s/%s MB 사용 (%.1f%%)\n" "$(echo $used | xargs)" "$(echo $total | xargs)" $(echo "scale=1; $(echo $used | xargs) * 100 / $(echo $total | xargs)" | bc -l 2>/dev/null || echo "0") printf " 사용률: %s%%\n" "$(echo $util | xargs)" fi } # 시스템 리소스 확인 check_system_resources() { local memory_info=$(free -m | awk 'NR==2{printf "%.1f/%.1f MB (%.1f%%)", $3,$2,$3*100/$2}') local cpu_usage=$(top -bn1 | grep "Cpu(s)" | awk '{print $2}' | sed 's/%us,//') local disk_usage=$(df -h / | awk 'NR==2{print $5}') local load_avg=$(uptime | awk -F'load average:' '{print $2}' | xargs) if [ "$JSON_OUTPUT" = true ]; then echo -n "\"system\": {" echo -n "\"memory\": \"$memory_info\"," echo -n "\"cpu_usage\": \"$cpu_usage\"," echo -n "\"disk_usage\": \"$disk_usage\"," echo -n "\"load_average\": \"$load_avg\"" echo -n "}" else echo -e "${CYAN}시스템 리소스:${NC}" printf " 메모리: %s\n" "$memory_info" printf " CPU 사용률: %s%%\n" "$cpu_usage" printf " 디스크 사용률: %s\n" "$disk_usage" printf " 로드 평균: %s\n" "$load_avg" fi } # API 엔드포인트 상태 확인 check_api_endpoints() { if [ "$JSON_OUTPUT" = true ]; then echo -n "\"api_endpoints\": {" else echo -e "${CYAN}API 엔드포인트 상태:${NC}" fi local endpoints=( "health:http://localhost:$MAIN_PORT/health" "status:http://localhost:$MAIN_PORT/status" "docs:http://localhost:$MAIN_PORT/docs" ) local first=true for endpoint_info in "${endpoints[@]}"; do IFS=':' read -r name url <<< "$endpoint_info" local response_code=$(curl -s -o /dev/null -w "%{http_code}" "$url" --connect-timeout 3 2>/dev/null || echo "000") local status="FAILED" if [ "$response_code" = "200" ]; then status="OK" elif [ "$response_code" = "000" ]; then status="UNREACHABLE" fi if [ "$JSON_OUTPUT" = true ]; then [ "$first" = false ] && echo -n "," echo -n "\"$name\": {\"status\": \"$status\", \"code\": \"$response_code\", \"url\": \"$url\"}" first=false else local status_color case $status in "OK") status_color=$GREEN ;; "UNREACHABLE") status_color=$RED ;; *) status_color=$YELLOW ;; esac printf " %-10s: ${status_color}%-12s${NC} (%s)\n" "$name" "$status" "$response_code" fi done if [ "$JSON_OUTPUT" = true ]; then echo -n "}" fi } # 로그 파일 상태 확인 check_log_files() { if [ "$JSON_OUTPUT" = true ]; then echo -n "\"logs\": {" else echo -e "${CYAN}로그 파일 상태:${NC}" fi local log_files=( "main_server.log" "monitoring.log" "error.log" "access.log" ) local first=true for log_file in "${log_files[@]}"; do local log_path="$LOG_DIR/$log_file" local size="N/A" local last_modified="N/A" local exists=false if [ -f "$log_path" ]; then exists=true size=$(du -h "$log_path" 2>/dev/null | cut -f1) last_modified=$(stat -c %y "$log_path" 2>/dev/null | cut -d' ' -f1,2 | cut -d'.' -f1) fi if [ "$JSON_OUTPUT" = true ]; then [ "$first" = false ] && echo -n "," echo -n "\"$log_file\": {\"exists\": $exists, \"size\": \"$size\", \"last_modified\": \"$last_modified\"}" first=false else if [ "$exists" = true ]; then printf " %-20s: ${GREEN}EXISTS${NC} (크기: %s, 수정: %s)\n" "$log_file" "$size" "$last_modified" else printf " %-20s: ${RED}NOT FOUND${NC}\n" "$log_file" fi fi done if [ "$JSON_OUTPUT" = true ]; then echo -n "}" fi } # 프로세스 트리 표시 (상세 모드) show_process_tree() { if [ "$DETAILED" = true ] && [ "$JSON_OUTPUT" = false ]; then echo -e "${CYAN}프로세스 트리:${NC}" local main_pid=$(lsof -ti:$MAIN_PORT 2>/dev/null | head -1) local monitoring_pid=$(lsof -ti:$MONITORING_PORT 2>/dev/null | head -1) if [ -n "$main_pid" ]; then echo " 메인 서버 프로세스:" pstree -p "$main_pid" 2>/dev/null | sed 's/^/ /' || ps -f --pid "$main_pid" fi if [ -n "$monitoring_pid" ]; then echo " 모니터링 서버 프로세스:" pstree -p "$monitoring_pid" 2>/dev/null | sed 's/^/ /' || ps -f --pid "$monitoring_pid" fi fi } # 네트워크 연결 상태 확인 (상세 모드) check_network_connections() { if [ "$DETAILED" = true ]; then if [ "$JSON_OUTPUT" = true ]; then echo -n "\"network_connections\": [" else echo -e "${CYAN}네트워크 연결:${NC}" fi local connections=$(netstat -tulpn 2>/dev/null | grep -E ":($MAIN_PORT|$MONITORING_PORT) " || true) if [ "$JSON_OUTPUT" = true ]; then local first=true while IFS= read -r line; do if [ -n "$line" ]; then [ "$first" = false ] && echo -n "," echo -n "\"$line\"" first=false fi done <<< "$connections" echo -n "]" else if [ -n "$connections" ]; then echo "$connections" | sed 's/^/ /' else echo " 연결된 포트가 없습니다" fi fi fi } # 실시간 모니터링 watch_status() { while true; do clear echo "==========================================" echo "🔍 인페인팅 서버 실시간 모니터링" echo "==========================================" echo "업데이트 시간: $(date)" echo "" show_status echo "" echo "Ctrl+C로 종료" sleep 5 done } # 서버 상태 확인 함수 check_server_status() { local port=$1 local service_name=$2 if lsof -Pi :$port -sTCP:LISTEN -t >/dev/null 2>&1; then local pid=$(lsof -Pi :$port -sTCP:LISTEN -t | head -1) local process_info=$(ps -p $pid -o pid,cmd,etime --no-headers 2>/dev/null || echo "Unknown") echo -e " ✅ $service_name (포트 $port): 실행 중 (PID: $pid)" echo -e " 프로세스: $process_info" else echo -e " ❌ $service_name (포트 $port): 중지됨" fi } # 메인 상태 표시 함수 show_status() { if [ "$JSON_OUTPUT" = true ]; then echo "{" check_server_status $MAIN_PORT "main_server" echo "," check_server_status $MONITORING_PORT "monitoring_server" echo "," check_gpu_status echo "," check_system_resources echo "," check_api_endpoints echo "," check_log_files check_network_connections echo "}" else echo "==========================================" echo "🖼️ 인페인팅 서버 상태" echo "==========================================" echo "" echo -e "${CYAN}서비스 상태:${NC}" check_server_status $MAIN_PORT "메인 서버" check_server_status $MONITORING_PORT "모니터링 서버" echo "" check_gpu_status echo "" check_system_resources echo "" check_api_endpoints echo "" check_log_files echo "" show_process_tree check_network_connections echo "==========================================" echo "💡 유용한 명령어:" echo " 서버 시작: ./scripts/start_server.sh" echo " 서버 중지: ./scripts/stop_server.sh" echo " 실시간 모니터링: ./scripts/status.sh -w" echo " 상세 정보: ./scripts/status.sh -d" if lsof -Pi :$MONITORING_PORT -sTCP:LISTEN -t >/dev/null 2>&1; then echo " 웹 모니터링: http://localhost:$MONITORING_PORT" fi echo "==========================================" fi } # 메인 실행 main() { # 로그 디렉토리 확인 if [ ! -d "$LOG_DIR" ]; then mkdir -p "$LOG_DIR" fi # 시스템 감지 detect_system if [ "$WATCH_MODE" = true ]; then watch_status else show_status fi } # 스크립트 실행 main "$@"