실무에서 자주 사용되는 쉘 스크립트  #5
           (트래픽 점검(측정) 유틸리티)



  지난강좌(#4)는 ping을 이용하여 여러 서버를 점검하는 스크립트를 만들어 보았다.
금번 강좌에서는 서버의 트래픽을 간단하게 확인 할 수 있는 트래픽 측정 유틸리티를 만들어 보도록 하겠다. 우리가 흔히 얘기하는 트래픽은 초당 얼마나 많은 데이터들이 소통되는지를 의미한다. 트래픽의 단위는 대부분 Bit/Sec로 표현한다. 원하는 목표를 달성해 보자^^

항상 그렇듯 차근 차근 문제를 풀어 보도록 하자 ...



1) 트래픽 정보를 어디에서 구할 수 있을까?
  트래픽을 측정하기 위해서는 어디에서 정보를 구해와야 한다.
트래픽.... 그렇다면 네트웍 장치와 관련이 있을 것이며, 그 정보를 /proc 에서 찾을 수 있었다.
물론 .. ifconfig 명령어를 입력하면 찾을 수 도 있다.


  (1) /proc의 트래픽 관련 정보 수집
    cat /proc/net/dev

    결과 :
Inter-|   Receive                                                |  Transmit
 face |bytes    packets errs drop fifo frame compressed multicast|bytes    packets errs drop fifo colls carrier compressed
    lo:85543370 1148565    0    0    0     0          0         0 85543370 1148565    0    0    0     0       0          0
  eth0:1829471133618 19299120632    0    0    0     0          0   1498386 14446844326628 21830048151    0    0    0     0       0          0
  eth1:       0       0    0    0    0     0          0         0        0       0    0    0    0     0       0          0
  sit0:       0       0    0    0    0     0          0         0        0       0    0    0    0     0       0          0

  위 정보가 복잡해 보이지만, 많은 정보를 내포하고 있다.
네트웍 장치가 여러개 보이지만, eth0, eth1 이 주요 측정 대상이 되며, 숫자가 많이 적힌 eth0이 주 인터페이스인 것을 확인 할 수 있다.



  (2) 위 정보에서 eth1에 대한 정보만 수집하자.
    grep eth0 /proc/net/dev

    결과 :
  eth0:1829520748902 19299665416    0    0    0     0          0   1498445 14446945435248 21830514044    0    0    0     0       0          0

  원하는 정보를 추출 하였다. 각 값들은 여러가지 의미를 내포하지만, 우리에게 필요한 것은 인터페이스를 통해 전달된(송/수신)데이터 양이다.  1번째숫자(수신)와, 9번째 숫자(송신)만 필요하다.


  (3) 원하는 값만 뽑아 내자 (awk)
    grep eth0 /proc/net/dev | awk '{print $1}'

    결과 :
eth0:1829578744769

   첫번째 값을 뽑아 내었다. 이 값은 인터페이스가 수신한 데이터 양이다.
여기서 사용한 awk 명령어는 아주 아주 유용한 명령어이다. ㅤㅅㅞㅂ 스크립트를 작성하는데 꼭! 꼭! 필요한 명령이며 아주 많은 기능을 가지고 있다. 위 예제에서 사용한 것은 표준 입력값을 받아서 첫번째($1) 단어만 추출한 것이다. 물론 공백을 기준으로 단어를 나누게 된다.
  그런데! 앞에 장치명(eth0)이 붙은  것을 확인할 수 있다.. 제거해야 하는데..


  (4) "eth0:"를 제거해 보자 (sed)
    grep eth0 /proc/net/dev | awk '{print $1}' | sed 's/.*://'

    결과 :

1829619555710

   eth0: 를 제거했다.
 그런데 sed 는 무엇이고 그 다음에 나오는 것은 무엇일까???
 sed는 스트림에디터 이다. 표준 입력으로 들어오는 내용을 편집 하는 것이다.
   "s/.*:// :"  s/표현1/표현2/ 를 의미하며 표현1을 표현2로 바꾸겠다는 것이다.
  ".*:"  "."은 아무 글자를 의미하고, "*"는 0개 이상을 의미한다.
 결론적으로 ":" 앞에 아무글자가 오는 것을 모두 지우라는 의미이다.
 그렇다면 생각해 보자.
   eth0:232312
 에서 eth0는 : 앞에 오는 0개 이상의 아무 글자이다 그래서 제거하면,
   232312 가 된다.^^
 

  (5) 뽑아낸 정보로 트래픽을 계산해 보자

    rx1=`grep eth0 /proc/net/dev | awk '{print $1}' | sed 's/.*://'`
    sleep 3
    rx2=`grep eth0 /proc/net/dev | awk '{print $1}' | sed 's/.*://'`
    rx3=$((rx2-rx1))
    echo "$rx3"

    결과 :
  352273
 
  rx1을 조사하고 3초간 기다린다.  기다리게 하기 위해 sleep 명령어를 사용하였다.
  3초후 rx2를 조사했다.  그런다음 rx2에서 rx1을 뺐다.
  bash 쉘에서 숫자 계산을 하기 위해서는 $((계산식)) 을 사용한다!! 계산식에 변수는 $를 붙이지 않는다.

  위 계산 결과는 3초 동안의 트래픽 변화양이다. 그리고 그 단위는 Byte 이다.


 
(6) KBit/Sec 단위로 변환해 보자
  rx3=$(( (rx2-rx1)/3*8/1024 ))

  위 계산식에서 3초간 조사했기에 3으로 나눴고,
  Byte를 Bit로 바꾸기 위해 8을 곱하고, Bit를 KBit로 바꾸기 위해서 1024로 나눴다.
  이미 계산할 수 있는 것은 계산하여 컴퓨터의 부하를 줄여보자.
   x*8/1024 = x*128   이 된다.
  그렇다면 계산식은

  rx3=$(( (rx2-rx1)/3*128 ))

 


2) 3초간 트래픽을 측정할 수 있는 프로그램 완성!!
 
  rx1=`grep eth0 /proc/net/dev | awk '{print $1}' | sed 's/.*://'`
  tx1=`grep eth0 /proc/net/dev | awk '{print $9}'`
  sleep 3
  rx2=`grep eth0 /proc/net/dev | awk '{print $1}' | sed 's/.*://'`
  tx2=`grep eth0 /proc/net/dev | awk '{print $9}'`

  rx3=$(((rx2-rx1)/128/3))
  tx3=$(((tx2-tx1)/128/3))

  echo "`date '+%k:%M:%S'` : $rx3 / $tx3"


  위 스크립트는 rx(수신), tx(송신) 용량을 조사하여 3초간 기다린 다음 계산하여 보여주게 만들었다.
  시간을 출력하기 위해 date 명령을 사용하였다.
 '
+%k:%M:%S' 는 시(24시) 분(60분) 초(60초)를 출력하기 위한 형식이다.



3) 계속 반복시키자
  위와같이 작성하면 1번 실행하고 끝난다. #1번 강좌에서 배웠던 while 문을 이용하여 반복시켜 보겠다.

echo "시간 : 수신(Kbit/Sec) / 송신(Kbit/Sec)"
while ( true ) ; do
  rx1=`grep eth0 /proc/net/dev | awk '{print $1}' | sed 's/.*://'`
  tx1=`grep eth0 /proc/net/dev | awk '{print $9}'`
  sleep 3
  rx2=`grep eth0 /proc/net/dev | awk '{print $1}' | sed 's/.*://'`
  tx2=`grep eth0 /proc/net/dev | awk '{print $9}'`

  rx3=$(((rx2-rx1)/128/3))
  tx3=$(((tx2-tx1)/128/3))

  echo "`date '+%k:%M:%S'` : $rx3 / $tx3"
done

while 문을 사용하여 무한 반복하였다.!!
자 이렇게 하면 eth0의 트래픽을 3초간 조사하여 평균을 보여주는 프로그램을 완성하였다.!!

But!. 네트웍 장치가 eth0가 아닌 다른것이며? 3초 단위가 아닌 10초 단위로 보고 싶다면,... 그럴 때 마다 쉘 스크립트를 수정하기엔 너무 번거롭다.!!! 명령어 처럼 인자로 받아서 처리하고 싶은데......



4) 다양한 장치, 다양한 delay 시간 제공 
  프로그램이 인자를 받아서 처리 하는 것은 아주 당연한 일이다.. 쉘 스크립트와 같이 소스를 수정할 수 있으면 좋겠지만, 수정하지 못하는 컴파일된 명령어는 아주 힘든 일이다.  그럼 다음과 같이 처리해 보자!


echo "시간 : 수신(Kbit/Sec) / 송신(Kbit/Sec)"
while ( true ) ; do
  rx1=`grep $1 /proc/net/dev | awk '{print $1}' | sed 's/.*://'`
  tx1=`grep $1 /proc/net/dev | awk '{print $9}'`
  sleep $2
  rx2=`grep $1 /proc/net/dev | awk '{print $1}' | sed 's/.*://'`
  tx2=`grep $1 /proc/net/dev | awk '{print $9}'`

  # 1024/8 == 128
  rx3=$(((rx2-rx1)/128/$2))
  tx3=$(((tx2-tx1)/128/$2))

  echo "`date '+%k:%M:%S'` : $rx3 / $tx3"
done


a.sh 파일에 위와같이 입력하고 파일을 만든 다음.  실행권한을 주고 다음과 같이 실행한다.

./a.sh eth0 2

위와같이 입력하면, 인터페이스는 eth0를 사용하고 , delay 시간은 2초로 한 것이다.
위 쉘스크립트에서 첫번째 인자가 $1 (eth0) ,  두번째 인자가 $2 (2) 인것이다.!!



5) 다른 사람들도 쓰게 하자!
 '4)' 와 같이 작성하면, 명령어의 인자가 있다는 사실을 아는 사람은 작성한 사람 또는 쉘 스크립트를 본 사람만이 알 수 있다. 사람의 머리는 시간이 지나면 잊어 먹기 마련이다. 작성한 사람조차 뭘 넣어야 잘 작동할지 모른다.  다음과 같이 개선해 보자.


if [ "$1" == "" ] ; then
  echo "사용법 : $0 장치명 [delay]"
  echo "예) $0 eth0 3 "
  exit 1
fi
if [ "$2" == "" ] ; then delay=3 ; else delay=$2 ; fi

echo "시간 : 수신(Kbit/Sec) / 송신(Kbit/Sec)"
while ( true ) ; do
  rx1=`grep $1 /proc/net/dev | awk '{print $1}' | sed 's/.*://'`
  tx1=`grep $1 /proc/net/dev | awk '{print $9}'`
  sleep $delay
  rx2=`grep $1 /proc/net/dev | awk '{print $1}' | sed 's/.*://'`
  tx2=`grep $1 /proc/net/dev | awk '{print $9}'`

  # 1024/8 == 128
  rx3=$(((rx2-rx1)/128/delay))
  tx3=$(((tx2-tx1)/128/delay))

  echo "`date '+%k:%M:%S'` : $rx3 / $tx3"
done


처음에 2번째 인자($2)를 조사하여 아무것도 없으면, 즉 입력이 되지 않았다면, 메시지를 뿌려준다.
 $0는 실행한 프로그램 그 자체 파일명을 의미한다. exit 1는 리턴값 1을 반환하면서 종료하게 되는 것이다.

그리고 delay 시간은 있어도 되고 없어도 되게 하며, 기본값은 3으로 하였다.
3번째 인자($3)를 조사하여 없으면 $delay변수에 3을 넣고, 있으면 그 값을 넣어준다.



위 쉘스크립트를 이용하여 사용하고 서버의 트래픽을 점검 할 수 있다.


우리는 이것으로
 아주 쉽게 트래픽을 확인 할 수 잇는 프로그램을 만들었다. 위 스크립트를 작성하면서
awk, grep, sed, sleep명령어  및 숫자 계산 $(()), 아규먼트 $1 , while, if, exit 문을 알게 되었다.
  서버에 간단한 유틸리티를 깔아 놓음으로 트래픽을 바로 확인 할 수 있게 되었다. MRTG에서 그래프를 보려면 많이 기다려야 하는데.. 답답하지 않고 좋다^^ 넘넘 뿌듯하다^^..

'OS > LINUX' 카테고리의 다른 글

프로세스 - fork & exec  (0) 2011.05.14
쉘 스크립트 #6  (0) 2011.05.14
쉘스크립트 Ex4  (0) 2011.05.14
쉘스크립트 Example2  (0) 2011.05.14
쉘스크립트 example  (0) 2011.05.14

+ Recent posts