diff --git a/build.gradle b/build.gradle index b5740fd..e3e16d5 100644 --- a/build.gradle +++ b/build.gradle @@ -13,6 +13,12 @@ java { } } +bootJar { + archivesBaseName = 'Runimo' + archiveFileName = 'Runimo.jar' + archiveVersion = '0.0.1' +} + repositories { mavenCentral() } diff --git a/shell/clean-logs.sh b/shell/clean-logs.sh new file mode 100755 index 0000000..68658c7 --- /dev/null +++ b/shell/clean-logs.sh @@ -0,0 +1,14 @@ +#!/bin/bash + +LOG_DIR="../logs" +DAYS_TO_KEEP=14 + +echo "로그 정리 시작... (보존 기간: $DAYS_TO_KEEP일)" + +# 1. 롤링된 로그 파일 중 보존 기간 초과한 로그 삭제 +find "$LOG_DIR" -type f -name "app.*.log" -mtime +$DAYS_TO_KEEP -print -exec rm -f {} \; + +# 2. 빈 로그 파일 삭제 +find "$LOG_DIR" -type f -name "*.log" -size 0 -print -exec rm -f {} \; + +echo "로그 정리 완료" diff --git a/shell/docker-start.sh b/shell/docker-start.sh new file mode 100755 index 0000000..ee199dd --- /dev/null +++ b/shell/docker-start.sh @@ -0,0 +1,104 @@ +#!/bin/bash + +# 기본 변수 설정 +APP_NAME="runimo" +CONTAINER_NAME="${APP_NAME}" +DOCKER_USERNAME="ekgns33" # Docker Hub 사용자명으로 변경 필요 +IMAGE_NAME="${DOCKER_USERNAME}/${APP_NAME}" # 소문자로 변환 +TAG="latest" +PORT="8080" +HOST_PORT="8080" + +# 함수: Docker 이미지 가져오기 +pull_image() { + echo "Docker 이미지 가져오기: ${IMAGE_NAME}:${TAG}" + docker pull "${IMAGE_NAME}:${TAG}" + + if [ $? -ne 0 ]; then + echo "이미지 가져오기 실패: ${IMAGE_NAME}:${TAG}" + exit 1 + fi + + echo "이미지 가져오기 성공" +} + +# 함수: 기존 컨테이너 중지 및 삭제 +stop_and_remove_container() { + if [ "$(docker ps -a -q -f name=${CONTAINER_NAME})" ]; then + echo "기존 컨테이너 중지 및 삭제: ${CONTAINER_NAME}" + docker stop ${CONTAINER_NAME} || true + docker rm ${CONTAINER_NAME} || true + fi +} + +# 함수: Docker 컨테이너 실행 +run_container() { + local profile=$1 + + if [ -z "$profile" ]; then + profile="dev" + fi + + echo "프로필 ${profile}로 Docker 컨테이너 실행..." + + docker run -d \ + --name ${CONTAINER_NAME} \ + -p ${HOST_PORT}:${PORT} \ + -v "$PWD/logs:/app/logs" \ + --env-file .env.dev \ + -e SPRING_PROFILES_ACTIVE=${profile} \ + -e JAVA_OPTS="-Xms512m -Xmx512m" \ + --restart unless-stopped \ + ${IMAGE_NAME}:${TAG} + + if [ $? -ne 0 ]; then + echo "컨테이너 실행 실패" + exit 1 + fi + + echo "컨테이너 실행 성공: ${CONTAINER_NAME}" + echo "컨테이너 ID: $(docker ps -q -f name=${CONTAINER_NAME})" +} + +# 함수: 컨테이너 로그 확인 +show_logs() { + if [ "$(docker ps -q -f name=${CONTAINER_NAME})" ]; then + echo "컨테이너 로그 출력: ${CONTAINER_NAME}" + docker logs -f ${CONTAINER_NAME} + else + echo "실행 중인 컨테이너가 없습니다: ${CONTAINER_NAME}" + fi +} + +# 메인 로직 +case "$1" in + pull) + pull_image + ;; + start) + stop_and_remove_container + pull_image + run_container "$2" + ;; + restart) + stop_and_remove_container + run_container "$2" + ;; + stop) + stop_and_remove_container + ;; + logs) + show_logs + ;; + *) + echo "사용법: $0 {pull|start|restart|stop|logs} [profile]" + echo " pull: Docker 이미지 가져오기" + echo " start [profile]: 컨테이너 시작 (기본값: dev)" + echo " restart [profile]: 컨테이너 재시작" + echo " stop: 컨테이너 중지 및 삭제" + echo " logs: 컨테이너 로그 출력" + exit 1 + ;; +esac + +exit 0 \ No newline at end of file diff --git a/shell/start-server.sh b/shell/start-server.sh new file mode 100644 index 0000000..5822bbd --- /dev/null +++ b/shell/start-server.sh @@ -0,0 +1,60 @@ +#!/bin/bash + +# 기본 변수 설정 +APP_NAME="Runimo" +JAR_FILE="build/libs/$APP_NAME.jar" +LOG_DIR="logs" + +# 로그 디렉토리 생성 +mkdir -p "$LOG_DIR" + +# 함수: 애플리케이션 빌드 +build_app() { + echo "애플리케이션 빌드 시작..." + ./gradlew clean bootJar + + if [ $? -eq 0 ]; then + echo "빌드 성공: $JAR_FILE" + else + echo "빌드 실패" + exit 1 + fi +} + +# 함수: 애플리케이션 실행 +run_app() { + local profile=$1 + + if [ -z "$profile" ]; then + profile="dev" + fi + + echo "프로필 $profile 로 애플리케이션 실행..." + nohup java -Xms512m -Xmx512m \ + -jar -Dspring.profiles.active=$profile $JAR_FILE > "$LOG_DIR/$APP_NAME-$(date +%Y%m%d).log" 2>&1 & + echo "애플리케이션 PID: $!" + echo "$!" > "$APP_NAME.pid" +} + +# 메인 로직 +case "$1" in + build) + build_app + ;; + start) + run_app "$2" + ;; + build-start) + build_app + run_app "$2" + ;; + *) + echo "사용법: $0 {build|start|build-start} [profile]" + echo " build: 애플리케이션 빌드" + echo " start [profile]: 특정 프로필로 애플리케이션 실행 (기본값: local)" + echo " build-start [profile]: 애플리케이션 빌드 후 실행" + exit 1 + ;; +esac + +exit 0 \ No newline at end of file diff --git a/shell/stop-server.sh b/shell/stop-server.sh new file mode 100644 index 0000000..6d4e327 --- /dev/null +++ b/shell/stop-server.sh @@ -0,0 +1,11 @@ +#!/bin/bash + +SERVICE_NAME="Runimo" +pid=`ps -elf | grep org.runimo.$SERVICE_NAME.jar` + +if [ -z "$pid"]; then + echo "$SERVICE_NAME killed" +else + kill -9 $pid + echo "$SERVICE_NAME $pid closing..." process exit +fi \ No newline at end of file diff --git a/shell/system-resource.sh b/shell/system-resource.sh new file mode 100755 index 0000000..2f43a5f --- /dev/null +++ b/shell/system-resource.sh @@ -0,0 +1,171 @@ +#!/usr/bin/env bash + +# 색상 정의 +RED='\033[0;31m'; GREEN='\033[0;32m'; YELLOW='\033[0;33m'; BLUE='\033[0;34m'; NC='\033[0m' + +OS_TYPE="$(uname)" + +print_date() { + echo -e "${BLUE}==== 시스템 리소스 상태 조회 - $(date '+%Y-%m-%d %H:%M:%S') ====${NC}\n" +} + +print_system_info() { + echo -e "${BLUE}=== 시스템 정보 ===${NC}" + echo -e "호스트명: $(hostname)" + echo -n -e "운영체제: " + if [[ "$OS_TYPE" == "Linux" ]]; then + grep PRETTY_NAME /etc/os-release | cut -d= -f2 | tr -d '"' + echo -e "가동 시간: $(uptime -p)" + else # Darwin Mac + echo "$(sw_vers -productName) $(sw_vers -productVersion)" + uptime | awk -F'( up |,)' '{print "가동 시간: " $2}' + fi + echo +} + +print_cpu_info() { + echo -e "${BLUE}=== CPU 정보 ===${NC}" + if [[ "$OS_TYPE" == "Linux" ]]; then + CORES=$(nproc) + MODEL=$(grep 'model name' /proc/cpuinfo | head -1 | cut -d: -f2- | xargs) + IDLE=$(top -bn1 | awk '/Cpu\(s\)/{print $8}' | sed 's/,//') + else + CORES=$(sysctl -n hw.ncpu) + MODEL=$(sysctl -n machdep.cpu.brand_string) + IDLE=$(top -l 1 | awk -F',' '/CPU usage/ {gsub(/%/,"",$3); print $3}') + fi + USAGE=$(printf "%.1f" "$(echo "100 - $IDLE" | bc)") + echo -e "CPU 코어 수: $CORES" + echo -e "CPU 모델: $MODEL" + echo -n "CPU 사용량: " + if (( $(echo "$USAGE > 80" | bc -l) )); then + echo -e "${RED}${USAGE}% (높음)${NC}" + elif (( $(echo "$USAGE > 50" | bc -l) )); then + echo -e "${YELLOW}${USAGE}% (중간)${NC}" + else + echo -e "${GREEN}${USAGE}% (낮음)${NC}" + fi + echo +} + +print_memory_info() { + echo -e "${BLUE}=== 메모리 정보 ===${NC}" + if [[ "$OS_TYPE" == "Linux" ]]; then + read total used free shared buff cache available < <(free -m | awk 'NR==2{print $2, $3, $4, $5, $6, $7, $7}') + usage_pct=$(printf "%.1f" "$(echo "$used/$total*100" | bc -l)") + else # mac + total_bytes=$(sysctl -n hw.memsize) + total=$(( total_bytes/1024/1024 )) # MB + pagesize=$(vm_stat | awk '/page size of/{print $8}') + free_pages=$(vm_stat | awk '/Pages free/{print $3}' | tr -d '.') + inactive_pages=$(vm_stat | awk '/Pages inactive/{print $3}' | tr -d '.') + free=$(( (free_pages + inactive_pages) * pagesize / 1024 / 1024 )) + used=$(( total - free )) + usage_pct=$(printf "%.1f" "$(echo "$used/$total*100" | bc -l)") + fi + + echo -e "총 메모리: ${total} MB" + echo -n -e "메모리 사용량: ${used} MB (${usage_pct}%) - " + if (( $(echo "$usage_pct > 80" | bc -l) )); then + echo -e "${RED}높음${NC}" + elif (( $(echo "$usage_pct > 60" | bc -l) )); then + echo -e "${YELLOW}중간${NC}" + else + echo -e "${GREEN}낮음${NC}" + fi + echo -e "사용 가능한 메모리: ${free} MB\n" +} + +print_disk_info() { + echo -e "${BLUE}=== 디스크 사용량 ===${NC}" + df -h | awk 'NR==1 || /^\/dev/' | while read fs size used avail usep mount; do + printf "%-20s %6s %6s %6s " "$fs" "$size" "$used" "$avail" + pct=${usep%\%} + if (( pct > 90 )); then + printf "${RED}%4s%%${NC} " "$pct" + elif (( pct > 70 )); then + printf "${YELLOW}%4s%%${NC} " "$pct" + else + printf "${GREEN}%4s%%${NC} " "$pct" + fi + echo " $mount" + done + echo +} + +print_top_cpu_processes() { + echo -e "${BLUE}=== 상위 CPU 사용 프로세스 (Top 5) ===${NC}" + if [[ "$OS_TYPE" == "Linux" ]]; then + ps -eo user,pid,%cpu,comm --sort=-%cpu | head -n 6 + else # macOS + ps -A -o user,pid,%cpu,comm | sort -k3 -nr | head -n 6 + fi + echo +} + +print_top_memory_processes() { + echo -e "${BLUE}=== 상위 메모리 사용 프로세스 (Top 5) ===${NC}" + if [[ "$OS_TYPE" == "Linux" ]]; then + ps -eo user,pid,%mem,comm --sort=-%mem | head -n 6 + else # macOS + ps -A -o user,pid,%mem,comm | sort -k3 -nr | head -n 6 + fi + echo +} + + +print_network_info() { + echo -e "${BLUE}=== 네트워크 연결 상태 ===${NC}" + echo -e "활성화된 ESTABLISHED 연결 수: $(netstat -an | grep ESTABLISHED | wc -l)" + echo -e "LISTEN 포트:" + netstat -an | grep LISTEN + echo +} + +check_spring_app() { + echo -e "${BLUE}=== Runimo 애플리케이션 상태 ===${NC}" + PID=$(pgrep -f "Runimo.jar" | head -1) + if [[ -n "$PID" ]]; then + echo -e "Runimo 상태: ${GREEN}실행 중 (PID: $PID)${NC}" + else + echo -e "Runimo 상태: ${RED}미실행${NC}" + fi + echo +} + +check_docker_containers() { + echo -e "${BLUE}=== Docker 컨테이너 상태 ===${NC}" + if command -v docker &> /dev/null; then + COUNT=$(docker ps -q | wc -l) + echo -e "실행 중인 컨테이너 수: ${GREEN}$COUNT${NC}" + docker ps --format "table {{.Names}}\t{{.Image}}\t{{.Status}}\t{{.Ports}}" + else + echo -e "${YELLOW}Docker가 설치되어 있지 않습니다.${NC}" + fi + echo +} + +# 전체 출력 +print_all() { + clear + print_date + print_system_info + print_cpu_info + print_memory_info + print_disk_info + print_top_cpu_processes + print_top_memory_processes + check_spring_app + check_docker_containers +} + +case "$1" in + cpu) print_date; print_cpu_info; print_top_cpu_processes ;; + memory) print_date; print_memory_info; print_top_memory_processes ;; + disk) print_date; print_disk_info ;; + app) print_date; check_spring_app ;; + docker) print_date; check_docker_containers ;; + *) print_all ;; +esac + +exit 0