Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,12 @@ java {
}
}

bootJar {
archivesBaseName = 'Runimo'
archiveFileName = 'Runimo.jar'
archiveVersion = '0.0.1'
}

repositories {
mavenCentral()
}
Expand Down
14 changes: 14 additions & 0 deletions shell/clean-logs.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
#!/bin/bash

LOG_DIR="../logs"
Copy link

Copilot AI May 29, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[nitpick] Using a hardcoded relative path may lead to inconsistencies between scripts. Consider deriving the script's directory with dirname "$0" and constructing an absolute path to the logs folder for consistency.

Suggested change
LOG_DIR="../logs"
SCRIPT_DIR="$(dirname "$0")"
LOG_DIR="$(realpath "$SCRIPT_DIR/../logs")"

Copilot uses AI. Check for mistakes.
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 "로그 정리 완료"
104 changes: 104 additions & 0 deletions shell/docker-start.sh
Original file line number Diff line number Diff line change
@@ -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
60 changes: 60 additions & 0 deletions shell/start-server.sh
Original file line number Diff line number Diff line change
@@ -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 &
Copy link

Copilot AI May 29, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The -jar flag must be followed directly by the JAR file path; JVM options like -Dspring.profiles.active should precede -jar. For example:

java -Xms512m -Xmx512m -Dspring.profiles.active=$profile -jar $JAR_FILE
Suggested change
-jar -Dspring.profiles.active=$profile $JAR_FILE > "$LOG_DIR/$APP_NAME-$(date +%Y%m%d).log" 2>&1 &
-Dspring.profiles.active=$profile -jar $JAR_FILE > "$LOG_DIR/$APP_NAME-$(date +%Y%m%d).log" 2>&1 &

Copilot uses AI. Check for mistakes.
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)"
Copy link

Copilot AI May 29, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The usage message states the default profile is local, but the script actually defaults to dev. Align the help text with the code or vice versa.

Suggested change
echo " start [profile]: 특정 프로필로 애플리케이션 실행 (기본값: local)"
echo " start [profile]: 특정 프로필로 애플리케이션 실행 (기본값: dev)"

Copilot uses AI. Check for mistakes.
echo " build-start [profile]: 애플리케이션 빌드 후 실행"
exit 1
;;
esac

exit 0
11 changes: 11 additions & 0 deletions shell/stop-server.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
#!/bin/bash

SERVICE_NAME="Runimo"
pid=`ps -elf | grep org.runimo.$SERVICE_NAME.jar`

if [ -z "$pid"]; then
Comment on lines +4 to +6
Copy link

Copilot AI May 29, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[nitpick] Using grep on ps output can capture the grep process itself and returns full lines instead of just the PID. Consider using pgrep -f org.runimo.$SERVICE_NAME.jar to reliably retrieve the PID.

Suggested change
pid=`ps -elf | grep org.runimo.$SERVICE_NAME.jar`
if [ -z "$pid"]; then
pid=$(pgrep -f org.runimo.$SERVICE_NAME.jar)
if [ -z "$pid" ]; then

Copilot uses AI. Check for mistakes.
echo "$SERVICE_NAME killed"
else
kill -9 $pid
echo "$SERVICE_NAME $pid closing..." process exit
fi
171 changes: 171 additions & 0 deletions shell/system-resource.sh
Original file line number Diff line number Diff line change
@@ -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}')
Copy link

Copilot AI May 29, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The AWK command prints field 7 twice, assigning both cache and available to the same value, and the script later echoes free instead of available for available memory. Adjust the AWK fields and variable assignments to correctly capture and display available memory.

Suggested change
read total used free shared buff cache available < <(free -m | awk 'NR==2{print $2, $3, $4, $5, $6, $7, $7}')
read total used free shared buff cache available < <(free -m | awk 'NR==2{print $2, $3, $4, $5, $6, $7}')

Copilot uses AI. Check for mistakes.
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