Threaddump를 생성하는 스크립트


#!/bin/bash

source /home/shell/env.sh

#JAVA_WHERE="/usr/bin"
#JavaNames_gc=("대상 프로세스 이름")

for JavaName in "${JavaNames_gc[@]}"
do

# 검색되는 프로세스들의 PID를 추출
pid=$(ps aux | grep $JavaName | grep -v grep | awk '{print $2}')

# PID가 없을 경우 1 출력 후 종료
if [ -z "$pid" ]; then
    echo 1
    exit 0
fi

  • PID가 없을 경우 1을 출력하고 스크립트를 종료


FILENAME="$MY_HOME/dump/threaddump.$pid.$JavaName.$(date +%Y%m%d_%H%M%S).txt"

  • 쓰레드 덤프 파일 이름을 정의
  • 해당 파일은 $MY_HOME 디렉토리 아래 dump 폴더에 저장되며, 파일 이름에는 프로세스의 PID와 이름, 그리고 생성 시간이 포함


echo "$pid thread dump가 생성중...."
"$JAVA_WHERE"/jstack $pid > $FILENAME
echo "$FILENAME thread dump 생성 완료!!"

  • $JAVA_WHERE 디렉토리 아래의 jstack을 사용하여 쓰레드 덤프를 생성

done


더보기

#!/bin/bash

source /home/shell/env.sh

#JAVA_WHERE="/usr/bin"
#JavaNames_gc=("대상 프로세스 이름")

for JavaName in "${JavaNames_gc[@]}"
do

# 검색되는 프로세스들의 PID를 추출
pid=$(ps aux | grep $JavaName | grep -v grep | awk '{print $2}')

# PID가 없을 경우 1 출력 후 종료
if [ -z "$pid" ]; then
    echo 1
    exit 0
fi

FILENAME="$MY_HOME/dump/threaddump.$pid.$JavaName.$(date +%Y%m%d_%H%M%S).txt"

echo "$pid thread dump가 생성중...."
"$JAVA_WHERE"/jstack $pid > $FILENAME
echo "$FILENAME thread dump 생성 완료!!"

done

Heapdump를 생성하는 스크립트


#!/bin/bash

source /home/shell/env.sh

#JAVA_WHERE="/usr/bin"
#JavaNames_gc=("대상 프로세스 이름")

for JavaName in "${JavaNames_gc[@]}"
do

# 검색되는 프로세스 들의 pid를 추출
pid=$(ps aux | grep $JavaName | grep -v grep | awk '{print $2}')

# pid가 없을 경우 1 출력 후 종료
if [ -z "$pid" ]; then
    echo 1
    exit 0
fi

FILENAME="$MY_HOME/dump/heapdump.$pid.$JavaName.$(date +%Y%m%d_%H%M%S).hprof"

  • 힙 덤프 파일 이름을 정의
  • 해당 파일은 MY_HOME 디렉토리 아래 dump 폴더에 저장되며, 파일 이름에는 프로세스의 PID와 이름, 그리고 생성 시간이 포함됩니다.


echo "$pid heap dump가 생성중...."
"$JAVA_WHERE"/jmap -dump:format=b,file=$FILENAME $pid
echo "$FILENAME heap dump가 생성 완료!!"

  • jmap을 사용하여 힙 덤프를 생성


done


더보기

#!/bin/bash

source /home/shell/env.sh

#JAVA_WHERE="/usr/bin"
#JavaNames_gc=("대상 프로세스 이름")

for JavaName in "${JavaNames_gc[@]}"
do

# 검색되는 프로세스 들의 pid를 추출
pid=$(ps aux | grep $JavaName | grep -v grep | awk '{print $2}')

# pid가 없을 경우 1 출력 후 종료
if [ -z "$pid" ]; then
    echo 1
    exit 0
fi

FILENAME="$MY_HOME/dump/heapdump.$pid.$JavaName.$(date +%Y%m%d_%H%M%S).hprof"

echo "$pid heap dump가 생성중...."
"$JAVA_WHERE"/jmap -dump:format=b,file=$FILENAME $pid
echo "$FILENAME heap dump가 생성 완료!!"

done

모니터링하고자 하는 프로세스의 Uptime을 체크하는 스크립트

 


#!/bin/bash

source /home/shell/env.sh

# 모니터링하고자 하는 프로세스 패턴 문구
#CpuProcessName=("모니터링할 프로세스 이름")

for ProcessName in "${CpuProcessNames[@]}"
do

# 검색되는 프로세스들의 PID를 추출
pids=$(ps aux | grep $ProcessName | grep -v grep | awk '{print $2}')

  • ps 명령어로 해당 프로세스 이름을 가진 프로세스를 찾고, grep을 사용하여 필터링
  • 마지막으로 awk를 사용하여 PID를 추출


# PID가 없을 경우 101 출력 후 종료
if [ -z "$pids" ]; then
    echo 101
    exit 0
fi

  • 프로세스가 없을 경우 101을 출력하고 스크립트를 종료



# Uptime 체크 후 1년 이상인 것이 하나라도 있을 경우 1 출력
    for pid in $pids; do
        uptime=$(ps -p $pid -o etimes=)
        if [ "$uptime" -ge "$cpu_time_limit" ]; then
            echo 1
            exit 0
        fi
    done

  • 모든 PID에 대해 해당 PID의 Uptime을 확인하고, 설정된 임계치 cpu_time_limit보다 크거나 같을 경우 1을 출력하고 스크립트를 종료


done

# 모든 프로세스의 Uptimedl 1년 미만일 경우 0 출력
echo 0


더보기

#!/bin/bash

source /home/shell/env.sh

# 모니터링하고자 하는 프로세스 패턴 문구
#CpuProcessName=("모니터링할 프로세스 이름")

for ProcessName in "${CpuProcessNames[@]}"
do

# 검색되는 프로세스들의 PID를 추출
pids=$(ps aux | grep $ProcessName | grep -v grep | awk '{print $2}')

# PID가 없을 경우 101 출력 후 종료
if [ -z "$pids" ]; then
    echo 101
    exit 0
fi

# Uptime 체크 후 1년 이상인 것이 하나라도 있을 경우 1 출력
    for pid in $pids; do
        uptime=$(ps -p $pid -o etimes=)
        if [ "$uptime" -ge "$cpu_time_limit" ]; then
            echo 1
            exit 0
        fi
    done

done

# 모든 프로세스의 Uptimedl 1년 미만일 경우 0 출력
echo 0

로그 파일에서 숫자 데이터를 분석하여 특정 조건을 만족하는지 확인하는 작업을 수행

 


#!/bin/bash

source /home/shell/env.sh

#MY_HOME="/home/shell"
#traffic=3

pattern="log_increase*"
LOG_FILES=($MY_HOME_LOG/$pattern)

  • pattern 변수에 log_increase* 패턴을 설정하고, 해당 패턴에 맞는 로그 파일들을 LOG_FILES 배열에 저장


# echo $LOG_FILES
result=0
for LOG_FILE in "${LOG_FILES[@]}"
do

# 마지막 GET_NUM 줄 가져오기
GET_LINES=$(tail -n $GET_NUM $LOG_FILE)
GET_TWO_LINES=$(tail -n 2 $LOG_FILE)

# 가져온 라인 수 출력
LINE_NUM=$(echo "$GET_LINES" | wc -l )

# 가져온 라인 중 최대값 출력
MAX_NUM=$(tail -n $GET_NUM $LOG_FILE | awk 'BEGIN{max=0} {if ($1>max) max=$1} END{print max}')

GET_LAST_NUM=$(echo "$GET_LINES" | tail -n 1 | grep -o '[0-9]\+')
GET_FIRST_NUM=$(echo "$GET_LINES" | head -n 1 | grep -o '[0-9]\+')
GET_SECOND_LAST_NUM=$(echo "$GET_TWO_LINES" | head -n 1 | grep -o '[0-9]\+')

  • 마지막 줄, 첫 번째 줄, 두 번째 마지막 줄에서 숫자만 추출


if [ "$GET_LAST_NUM" -lt " $GET_FIRST_NUM" ]; then
    GET_AVG_NUM=$( (MAX_NUM-GET_FIRST_NUM_+GET_LAST_NUM) )
else
    GET_AVG_NUM$( (GET_LAST_NUM-GET_FIRST_NUM) )
fi

  • 마지막 숫자가 첫 번째 숫자보다 작으면 순환형 로그로 간주하고 평균 증가 값을 계산
  • 그렇지 않으면 단순히 증가 값을 계산


GET_INCREASE=$( ( $GET_LAST_NUM-$GET_SECOND_LAST_NUM) )


# 로그의 마지막 증가 크기가 평균적 증가 크기의 traffic 배수를 초과하면 알림
AVG_NUM_X =$( (GET_AVG_NUM * $traffic) )

# 최근 입력된 숫자가 평균값의 3배수 이상이면 1출력, 아니면 0 출력
if ( (GET_INCREASE > AVG_NUM_X) ); then
    result=1
fi

done

echo $result


더보기

#!/bin/bash

source /home/shell/env.sh

pattern="log_increase*"
LOG_FILES=($MY_HOME_LOG/$pattern)

result=0
for LOG_FILE in "${LOG_FILES[@]}"
do
    # 마지막 GET_NUM 줄 가져오기
    GET_LINES=$(tail -n $GET_NUM $LOG_FILE)
    GET_TWO_LINES=$(tail -n 2 $LOG_FILE)

    # 가져온 라인 수 출력
    LINE_NUM=$(echo "$GET_LINES" | wc -l)

    # 가져온 라인 중 최대값 출력
    MAX_NUM=$(echo "$GET_LINES" | awk 'BEGIN{max=0} {if ($1>max) max=$1} END{print max}')

    GET_LAST_NUM=$(echo "$GET_LINES" | tail -n 1 | grep -o '[0-9]\+')
    GET_FIRST_NUM=$(echo "$GET_LINES" | head -n 1 | grep -o '[0-9]\+')
    GET_SECOND_LAST_NUM=$(echo "$GET_TWO_LINES" | head -n 1 | grep -o '[0-9]\+')

    if [ "$GET_LAST_NUM" -lt "$GET_FIRST_NUM" ]; then
        GET_AVG_NUM=$((MAX_NUM - GET_FIRST_NUM + GET_LAST_NUM))
    else
        GET_AVG_NUM=$((GET_LAST_NUM - GET_FIRST_NUM))
    fi

    GET_INCREASE=$((GET_LAST_NUM - GET_SECOND_LAST_NUM))

    # 로그의 마지막 증가 크기가 평균적 증가 크기의 traffic 배수를 초과하면 알림
    AVG_NUM_X=$((GET_AVG_NUM * traffic))

    # 최근 입력된 숫자가 평균값의 3배수 이상이면 1출력, 아니면 0 출력
    if ((GET_INCREASE > AVG_NUM_X)); then
        result=1
    fi
done

echo $result

port 가 down 일 때 없을 경우 101 출력하는 스크립트


#!/bin/bash

source /home/shell/env.sh

#port_list=("80" "8080")

# port_list가 없을 경우 101 출력 후 종료
if [ -z "$port_list" ]; then
    echo 101
    exit 0
fi

  • port_list 변수가 비어있는지 확인합니다. 비어있다면 101을 출력하고 스크립트를 종료


# 포트 리스트를 순회하며 LISTEN 상태 확인
for port in "${port_list[@]};
do
    # 포트가 LISTEN 상태가 아닌 경우 해당 Port 출력
    if ! netstat - tnl | grep ":$port " > /dev/null; then
        echo $port
        exit 0
    fi

  • netstat 명령어를 사용하여 현재 시스템에서 LISTEN 상태인 포트를 확인
    • netstat -tnl 명령어는 현재 시스템에서 LISTEN 상태인 TCP 포트를 나열
    • grep ":$port " 명령어는 LISTEN 상태의 포트 리스트에서 현재 확인 중인 포트를 찾습니다.
    • 포트가 LISTEN 상태가 아닌 경우, 해당 포트 번호를 출력하고 스크립트를 종료


done

# 모든 포트가 LISTEN 상태인 경우 0 출력
echo 0


더보기

#!/bin/bash

source /home/shell/env.sh

#port_list=("80" "8080")

# port_list가 없을 경우 101 출력 후 종료
if [ -z "$port_list" ]; then
    echo 101
    exit 0
fi

# 포트 리스트를 순회하며 LISTEN 상태 확인
for port in "${port_list[@]};
do
    # 포트가 LISTEN 상태가 아닌 경우 해당 Port 출력
    if ! netstat - tnl | grep ":$port " > /dev/null; then
        echo $port
        exit 0
    fi

done

# 모든 포트가 LISTEN 상태인 경우 0 출력
echo 0

oome 란?

  • 프로그램이 메모리 할당을 시도할 때 사용할 수 있는 메모리가 부족할 때 발생
  • Java와 같은 언어에서는 이러한 상황이 발생하면 OOME 예외가 던져지고, 이를 적절히 처리하지 않으면 프로그램이 비정상적으로 종료

#!/bin/bash

source /home/shell/env.sh


#LOG_PATHS_OOME=("대상 프로세스 배열로 입력")
#DAYS=3

total=0

for LOG_PATH in "${LOG_PATHS_OOME[@]}"
do

count=$(find $LOG_PATH -name "*heapdump*" -type f -ctime -$DAYS | wc -l)

  • find 명령어를 사용하여 LOG_PATH 경로에서 이름에 "heapdump"가 포함된 파일을 찾습니다.
    • -type f: 파일 타입만 검색
    • -ctime -$DAYS: 최근 $DAYS 이내에 생성된 파일을 검색
    • -print0: 검색 결과를 NULL 문자로 구분하여 출력
    • | wc -l: 파이프를 사용하여 검색된 결과의 라인 수를 세어 count 변수에 저장


# 차이 출력
total=$(expr $total + $count)

done

echo $total


더보기

#!/bin/bash

source /home/shell/env.sh


#LOG_PATHS_OOME=("대상 프로세스 배열로 입력")
#DAYS=3

total=0

for LOG_PATH in "${LOG_PATHS_OOME[@]}"
do

# -type f : 파일 타입만 검색
# -ctime -$DAYS : 최근 $DAYS 이내 생성된 파일 검색
# -print0 : 검색 결과를 NULL(\0) 문자로 구분하여 출력
# | : 파이프를 사용하여 출력된 결과를 wc 명령어에 전달
# -l : 출력된 결과의 라인 수를 세어 출력
count=$(find $LOG_PATH -name "*heapdump*" -type f -ctime -$DAYS | wc -l)

# 차이 출력
total=$(expr $total + $count)

done

echo $total

heap 사용량 모니터링

 


#!/bin/bash

source /home/shell/env.sh

#JAVA_WHERE="/usr/bin"
#JavaNames_gc=("대상 프로세스 이름")

max_heap_usage=0
for JavaName in "${JavaNames_gc[@]}"
do

# 검색되는 프로세스들의 PID를 추출
pid=$(ps aux | grep $JavaName | grep -v grep | awk '{print $2}')

  • ps aux 명령어를 사용하여 JavaName과 일치하는 프로세스를 찾고, 해당 프로세스의 PID를 추출


# PID가 없을 경우 1 출력 후 종료
if [ -z "$pid" ]; then
    echo 101
    exit 0
fi

  • PID가 비어 있는지 확인하고, 비어 있으면 101을 출력한 후 스크립트를 종료


# 각 PID의 CPU 사용량 중 최대값을 추출
        result=$("$JAVA_WHERE"/jstat -gc "$pid" | tail -n 1 | awk '{print ($3+$4+$6+$8)/($7+$5+$1)*100}')

  • jstat -gc 명령어를 사용하여 가비지 컬렉션(GC) 정보를 가져오고, 특정 필드의 값을 계산하여 result 변수에 저장

        HEAP_MEMORY_USAGE=$(printf "%.of" "$result")

  • result 값을 정수로 포맷팅하여 HEAP_MEMORY_USAGE 변수에 저장


        # echo $pid $HEAP_MEMORY_USAGE $result
        if [ $HEAP_MEMORY_USAGE -gt $max_heap_usage ]

        then
            max_heap_usage=$HEAP_MEMORY_USAGE
        fi

  • 현재 힙 사용량이 최대 힙 사용량보다 큰 경우, max_heap_usage 변수를 갱신


done

echo $max_heap_usage


더보기

#!/bin/bash

source /home/shell/env.sh

#JAVA_WHERE="/usr/bin"
#JavaNames_gc=("대상 프로세스 이름")

max_heap_usage=0
for JavaName in "${JavaNames_gc[@]}"
do

# 검색되는 프로세스들의 PID를 추출
pid=$(ps aux | grep $JavaName | grep -v grep | awk '{print $2}')

# PID가 없을 경우 1 출력 후 종료
if [ -z "$pid" ]; then
    echo 101
    exit 0
fi



# 각 PID의 CPU 사용량 중 최대값을 추출
        result=$("$JAVA_WHERE"/jstat -gc "$pid" | tail -n 1 | awk '{print ($3+$4+$6+$8)/($7+$5+$1)*100}')
        HEAP_MEMORY_USAGE=$(printf "%.of" "$result")

        # echo $pid $HEAP_MEMORY_USAGE $result
        if [ $HEAP_MEMORY_USAGE -gt $max_heap_usage ]
        then
            max_heap_usage=$HEAP_MEMORY_USAGE
        fi
done

echo $max_heap_usage

hang 이란? 

  • 프로그램이나 시스템이 중단된 상태
  • 이 상태에서는 프로그램이 입력에 응답하지 않거나 작업을 계속하지 못함.

#!/bin/bash

source /home/shell/env.sh

# hang=3

pattern="log_increase*"

  • 로그 파일의 패턴을 설정

LOG_FILES=($MY_HOME_LOG/$pattern)

  • 지정된 패턴에 맞는 로그 파일을 환경 변수 MY_HOME_LOG 경로에서 찾아 배열 LOG_FILES에 저장


result=0
for LOG_FILE in "${LOG_FILES[@]}"
do

# 마지막 1000줄 가져오기
GET_LINES=$(tail -n 1000 $LOG_FILE)

  • tail -n 1000 명령어로 로그 파일의 마지막 1000줄을 가져와 GET_LINE 변수에 저장


GET_LAST_NUM=$(echo "$GET_LINES" | tail -n 1 | grep -o '[0-9\+')

  • echo "$GET_LINES"로 마지막 1000줄을 출력하고, tail -n 1으로 마지막 줄을 가져온 후, grep -o '[0-9\+'로 숫자만 추출하여 GET_LAST_NUM 변수에 저장

GET_STUCK_NUM=$(echo "$GET_LINES" | grep $GET_LAST_NUM | wc -l)

  • echo "$GET_LINES"로 마지막 1000줄을 출력하고, grep $GET_LAST_NUM으로 GET_LAST_NUM과 일치하는 줄을 찾아 wc -l로 줄 수를 계산하여 GET_STUCK_NUM 변수에 저장


# 로그 파일이 변화 없는 시간이 HANGTIME을 초과하면 안 됨.
if ( (GET_STUCK_NUM > HANG_TIME) ); then
    result=1
fi

done

echo $result

 


더보기

#!/bin/bash

source /home/shell/env.sh

# hang=3

pattern="log_increase*"
LOG_FILES=($MY_HOEM_LOG/$pattern)

result=0
for LOG_FILE in "${LOG_FILES[@]}"
do

# 마지막 1000줄 가져오기
GET_LINES=$(tail -n 1000 $LOG_FILE)

GET_LAST_NUM=$(echo "$GET_LINES" | tail -n 1 | grep -o '[0-9\+')
GET_STUCK_NUM=$(echo "$GET_LINES" | grep $GET_LAST_NUM | wc -l)

# 로그 파일이 변화 없는 시간이 HANGTIME을 초과하면 안 됨.
if ( (GET_STUCK_NUM > HANG_TIME) ); then
    result=1
fi

done

echo $result

 

+ Recent posts