inpaintServer/scripts/status.sh

467 lines
14 KiB
Bash
Executable File

#!/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 "$@"