메뉴 건너뛰기

Korea Oracle User Group

OS

Linux top logging script

Talros 2020.01.17 14:43 조회 수 : 995

 

 OS : Red Hat Linux 7.2

 Shell : bash

 

# 리눅스에서 top 을 이용해 백그라운드로 로깅을 남기기 위한 스크립트 입니다.

 

1. 스크립트에서 사용 하는 프로그램 설명

 

  1.1  top

      

    -n   : 몇번 실행 할 것인지 동작 횟수를 지정 합니다.

    -d   : top 의 동작 인터벌을 지정 합니다. 

    -b   : batch-mode 로 동작을 합니다.

    ex) top -d 10 -n 100 -b

 

  1.2 grep

 

    -A : 몇번째 라인까지 출력 할것 인지를 지정

    -v : 지정한 단어가 포함된 라인을 제외하고 출력

    -e : 지정한 단어 패턴이 포함된 라인을 출력

    --line-buffered :   출력된 라인을 버퍼에 저장

    ex)  ps -ef|grep -e "top -d"|grep -v "grep"  ,  top -d 10 -n 100 -b |grep "load average" -A 15 --line-buffered

 

  1.3 wc

 

    -l :  총 라인 개수 출력

    ex) ps -ef|grep -e "top -d"|grep -v "grep"|wc -l

 

 

2. 스크립트 동작 설명

 

  2.1 스크립트 목적

     

      - top 프로그램을 백그라운드로 동작을 시키면서 하루 단위로 로그파일을 남기기 위한 스크립트

 

  2.2 스크립트 실행 방법

 

       - 터미널이 종료 되도 실행 할 수있게  nohup 과 & 백그라운드 명령으로 스크립트를 실행

       - loop_daily.sh [코드값] [interval val] [number_of_loops]

        ex)   nohup ./loop_daily.sh mon_cpu 10 9999999 &

 

  2.3 스크립트 로그 확인 방법

 

      



[orcl:oracle@testdb] /home/oracle/DBA/script/mon> ls -lrt
total 23168
-rwxr--r-- 1 oracle dba      298 Jan  9 16:25 mon_start.sh
-rwxr--r-- 1 oracle dba      248 Jan 14 12:02 nohup_loop_daily.sh
-rw-r--r-- 1 oracle dba        0 Jan 15 13:29 loop_daily.log
-rw-r--r-- 1 oracle dba  4426481 Jan 16 00:01 mon_cpu_20200115.out
-rw-r--r-- 1 oracle dba 10096160 Jan 17 00:03 mon_cpu_20200116.out
-rwxr--r-- 1 oracle dba     2354 Jan 17 14:19 loop_daily.sh
-rwxr--r-- 1 oracle dba      642 Jan 17 14:21 test.sh
-rw-r--r-- 1 oracle dba  6955712 Jan 17 16:37 mon_cpu_20200117.out
[orcl:oracle@testdb] /home/oracle/DBA/script/mon> tail -30f mon_cpu_20200117.out
KiB Mem : 65768084 total,  3140312 free, 56665912 used,  5961860 buff/cache
KiB Swap: 33554428 total, 33491668 free,    62760 used.  6724120 avail Mem 

  PID USER      PR  NI    VIRT    RES    SHR S  %CPU %MEM     TIME+ COMMAND
39172 oracle    -2   0 15.342g  15384  13000 S   1.4  0.0 326:53.18 ora_vktm_c+
44814 oracle    -2   0 33.342g  15388  13000 S   1.4  0.0 265:32.01 ora_vktm_c+
49022 oracle    20   0  635716  41700  16712 S   0.9  0.1 791:05.24 gipcd.bin
49288 root      20   0 2650560  88364  25824 S   0.9  0.1   1230:48 crsd.bin
49380 oracle    20   0 1864148  58076  20440 S   0.9  0.1   1041:23 oraagent.b+
48906 root      20   0 1588876  59720  20180 S   0.8  0.1 530:56.96 orarootage+
49170 root      20   0  819476  34020  15904 S   0.7  0.1 965:23.83 octssd.bin
44878 oracle    20   0 33.342g  16440  13984 S   0.6  0.0  44:42.26 ora_mmnl_c+
49083 oracle    rt   0 2375132 197012  90112 S   0.6  0.3 833:31.02 ocssd.bin
--
top - 16:37:36 up 136 days, 23:54,  4 users,  load average: 1.08, 1.18, 1.21
Tasks: 766 total,   1 running, 765 sleeping,   0 stopped,   0 zombie
%Cpu(s):  0.9 us,  0.6 sy,  0.0 ni, 98.3 id,  0.2 wa,  0.0 hi,  0.0 si,  0.0 st
KiB Mem : 65768084 total,  3138436 free, 56667824 used,  5961824 buff/cache
KiB Swap: 33554428 total, 33491668 free,    62760 used.  6722272 avail Mem 

  PID USER      PR  NI    VIRT    RES    SHR S  %CPU %MEM     TIME+ COMMAND
49272 root      rt   0 1084448 122484  81072 S   2.2  0.2   1676:36 osysmond.b+
44814 oracle    -2   0 33.342g  15388  13000 S   1.7  0.0 265:32.18 ora_vktm_c+
39172 oracle    -2   0 15.342g  15384  13000 S   1.6  0.0 326:53.34 ora_vktm_c+
49212 oracle    -2   0 1444824  15356  13164 S   1.1  0.0   1959:13 asm_vktm_++
48720 root      20   0 1884140  66064  19856 S   0.8  0.1   1310:17 ohasd.bin
49380 oracle    20   0 1864148  58076  20440 S   0.8  0.1   1041:23 oraagent.b+
48989 oracle    20   0  760336  35288  17024 S   0.7  0.1 927:40.69 evmd.bin
49288 root      20   0 2650560  88364  25824 S   0.7  0.1   1230:48 crsd.bin
49384 root      20   0  913932  31272  15096 S   0.7  0.0 888:09.65 orarootage+
^C
[orcl:oracle@testdb] /home/oracle/DBA/script/mon> 

 

 

 

 

# 전체 스크립트

   

 

#! /bin/bash

if [ $# -lt 1 ]; then
    echo "usage: $0 sql_script [interval [number_of_loops]]"
    echo " ex) nohup ./loop_daily.sh mon_cpu 10 9999999 &"
    exit 1
fi

sql_script=$1
interval=${2:-10}
n_loops=${3:-999999999}

#round() {
#    minor=${1#*.} # 소수자리만 남기고 지운다
#    prc=$(( 10 ** ${#minor})) # 자리수 개수만큼 10의 제곱으로 구한다
#    echo $( printf %.0f $( echo "scale=${#minor};(($prc*$1)+0.5)/$prc" | bc ))
#}

while true; do

        if [ $n_loops -eq 0 ]; then
            exit
        fi

        n_loops=`expr $n_loops - 1`

        if [ $sql_script = "mon_cpu" ]; then
            # 인터벌 시간 마다top 프로세스가 동작 중인지 확인
            TOP_CHECK=`ps -ef|grep -e "top -d"|grep -v "grep"|wc -l`

            # top 이 동작을 안하고 있으면 실행
            if [ "$TOP_CHECK" == "0" ];  then                
               
                # 로그 파일 이름을 위한 날짜 값 저장
                DATE=`date "+%Y%m%d"`
                
                # 현재시간을 시, 분, 초 로 분리 해서 저장
                HH24=`date "+%H"`
                MM=`date "+%M"`
                SS=`date "+%S"`
                
                # Calcurate Time
                # 변수의 수 값이 0 으로 시작 할 경우 8진 수로 인식 08 , 09 가 들어 오면 에러가 발생
                # ex) test.sh: line 15: 59-08: value too great for base (error token is "08")
                # 변수 앞에 10# 을 붙여 십진수로 인식 하게 함
                # 24시 까지 남은 시간을 각 시간 단위 별로 계산
                CH=$((23-10#$HH24))
                CM=$((59-10#$MM))
                CS=$((59-10#$SS))               
               
                # 위에서 나온 값을 초단위로 환산
                remain_sec=$(((((10#$CH*60)+10#$CM)*60)+10#$CS))
                
                # 24 hour repeat time, bash 숫자 연산은 정수로만 계산됨 소수점 계산을 위해선 awk , bc 를 이용
                # 24시 까지 몇번의 인터벌이 필요한지 계산
                repeat_time=$((($remain_sec/$interval)))
  

                echo '---------------------------------------------------------------' >> ${sql_script}_${DATE}.out

                echo ' ' >>  ${sql_script}_${DATE}.out
                top -d $interval -n $repeat_time -b |grep "load average" -A 15 --line-buffered >>  ${sql_script}_${DATE}.out

                sleep $interval
             
             else
                # top 이 실행 중이라면 인터벌 만큼 대기
                sleep $interval
             
             fi   

        else

              exit

        fi
done

 

 

위로