2008. 11. 26. 10:26
제 목 : 여러 서버의 load를 터미널에서 실시간 모니터링
작성자 : 좋은진호(truefeel, http://coffeenix.net/ )
작성일 : 2008.2.13(수)~15(금)
'리눅스 터미널(CLI모드)에서 보는 실시간 시계' ( http://coffeenix.net/bbs/viewtopic.php?t=2836 )에 대해 소개한 적이 있다. 이 시계 스크립트는 터미널의 오른쪽 상단에 실시간으로 시간을 표시한다.
[ 터미널에서 시계 ] (1초단위로 시간이 바뀌면서 표시된다.)
1. 한화면 실시간 load 모니터링 개요
시계 스크립트를 응용하여, 여러 서버의 load를 한화면에서 볼 수 있도록 구현하였다. 스크립트는 다음과 같은 역할을 한다.
1) tput 명령과 ANSI코드를 이용하여 원하는 위치에 load를 표시한다.
2) 1~9초간격으로 새로운 데이터를 표시한다.
3) '로그 모니터링시 특정 문자를 highlight하기' ( http://coffeenix.net/board_view.php?bd_code=1562 , 글 좋은진호)에서 소개한 방법을 이용하여 load별로 다른 색을 표시한다.
------- --------
load 색깔
------- --------
0.0 하얀색
0.1~0.39 녹 색
0.4~0.79 파란색
0.8~이상 빨간색
------- --------
4) 숫자 1~9까지 누르면 시간 간격을 변경할 수 있다. (단, foreground로 실행시)
5) q를 누르면 종료한다. (단, foreground 실행시)
참고로 서버는 10여대 정도만 샘플로 표시하였으며, 이미지상의 서버명은 실제 사용하지 않는 임의의 서버명이다.
[ load 모니터링 샘플 화면 ]
2. 미리 준비되어 있어야할 사항
통합 로그 서버와 각 서버에서 load를 보내주도록 처리해야 한다. 구축 방법에 대해서는 간략히 얘기하고, 시간이 될 때 추가 문서를 통해 설명하겠다.
1) 각 서버에서는 logger를 활용하여 서버의 load를 syslogd로 보내준다.
syslogd 는 load부분에 대한 로그를 통합로그로 보내지도록 설정해야 한다. 이 때 서버의 load는 5~10초 간격, 또는 더 긴 간격으로 체크하여 syslogd로 보내주면 된다.
2) 통합 로그 서버에서는 각 서버의 syslog 결과를 받을 수 있도록 설정한다. 통합서버는 FreeBSD를 권장하지만, 리눅스 서버를 사용할 경우 syslog-ng를 통해서 로그 서버 구축한다. 각 서버에서 오는 load정보는 서버별로 별도 파일에 저장하도록 하는 것이 중요하다. 예를 들어 cnx10.log, cnx22.log, cnx25.log, ... 처럼. 통합로그 서버의 서버별 로그 파일에는 다음과 같이 형태로 로그가 저장된다.
FreeBSD에서 실행할 때는 다음 2가지 사항을 체크해야 한다.
FreeBSD의 tput은 cursor 이동을 지원하지 않으므로 OpenBSD의 소스(ftp://ftp.openbsd.org/pub/OpenBSD/src/usr.bin/tput )를 가져다가 사용해야 한다. 또한 스크립트에서 사용한 read 옵션 -n, -s는 bash에 의존적으로 동작한다. /usr/ports/shells/bash ports 디렉토리에서 설치한다.
3. load 모니터링 스크립트
* load_mon.sh 내려받기
foreground로 스크립트를 실행할 것이면 fg=0으로 하고, background로 실행할 때는 1로 해줘야 스크립트의 기능을 제대로 사용할 수 있다. sleep=2 는 실시간으로 조회할 데이터를 몇 초 간격으로 볼 것인가를 지정한다.
LOGDIR= : 서버 load가 저장되어 있는 로그 파일의 경로
TPUT= : tput 명령의 경로. 기본 경로는 /usr/bin/tput
상단 부분의 'szCol' 로 시작하는 변수는 색깔을 정의한 ANSI 코드이다. ^[ 문자는 ESC키를 의미한다. 쉘에서 입력할 때 Ctrl+V를 누른 후 ESC키를 누르면 입력할 수 있다.
4. 스크립트 부분별 이해
keyinput() 함수는 foreground로 실행할 때 키입력을 받아들이는 부분이다.
read 의 -t 옵션은 입력 대기 시간이다. -t 5라면 5초동안 입력 대기를 하게 되는데, 결국 sleep 5 를 한 것과 같은 효과를 볼 수 있다. -n 1 은 1자만 입력 받는 것이고, -s는 입력한 키를 화면에 출력하지 말라는 뜻이다. 키 입력이 생기면 바로 그 다음줄이 실행되며, 입력되지 않더라도 대기시간이 지나면 넘어가게 된다. 결국 keyinput()함수는 프로그램의 실행에 방해를 주지 않으면서 원하는 키입력을 받아들이는 역할을 하게 된다.
1~9까지 입력(즉, 1~9초에 해당)하면 delay time을 변경하고, 화면 변경됐음을 보여준다. q를 누르면, 적당한 곳으로 커서를 옮기고 종료한다.
원하는 데이터 값을 가져오는 부분이다.
$cmd_local : 스크립트를 실행중인 서버의 load가 저장된다. '0.03|0.01|0.00'
$cmd : load가 저장된 각 서버별 로그파일의 맨 마지막 줄(가장 최근 load)를 읽어서 변수에 저장한다.
'cnx10|1.00,|1.00,|0.95 cnx22|0.39,|0.38,|0.35 cnx25|0.31,|0.24,|0.18 ... 생략...'
'서버명|1분load|5분load|15분load' 형태이며, 서버간의 구분은 반드시 1개 이상의 공백으로 해야 한다.
data를 표시할 위치를 오른쪽 상단, 오른쪽에서 $cols 번째칸으로 한다. 그런 후 서버마다 한줄에 한칸씩 보여준다. 화면에 표시될 때 커서는 안보이게 했다가(civis), 데이터가 다 뿌려지면 다시 보이도록 했다(cnorm).
다음은 실제 모니터링하는 화면이다. 3개의 화면을 연속으로 캡쳐한 것이다. 3초 간격, 3초 간격, 그리고 숫자 '5'를 누른 후 5초간격으로 보여주겠다는 화면이다.
highlight 처리 부분에 대한 설명은 참고문서로 대신한다. 그리고, 재미난 시계 스크립트를 소개한 'Sergio Gonzalez Duran'씨에게 감사드린다.
5. 참고자료
* CLI Magic: Use ANSI escape sequences to display a clock in your terminal
http://www.linux.com/feature/124918
* 로그 모니터링시 특정 문자를 highlight하기 (글 좋은진호, 2008.1)
http://coffeenix.net/board_view.php?bd_code=1562
* bash 맨페이지 중에 'read' 부분
* tput: Portable Terminal Control
http://www.gnu.org/software/termutils/manual/termutils-2.0/html_chapter/tput_1.html
작성자 : 좋은진호(truefeel, http://coffeenix.net/ )
작성일 : 2008.2.13(수)~15(금)
'리눅스 터미널(CLI모드)에서 보는 실시간 시계' ( http://coffeenix.net/bbs/viewtopic.php?t=2836 )에 대해 소개한 적이 있다. 이 시계 스크립트는 터미널의 오른쪽 상단에 실시간으로 시간을 표시한다.
[ 터미널에서 시계 ] (1초단위로 시간이 바뀌면서 표시된다.)
1. 한화면 실시간 load 모니터링 개요
시계 스크립트를 응용하여, 여러 서버의 load를 한화면에서 볼 수 있도록 구현하였다. 스크립트는 다음과 같은 역할을 한다.
1) tput 명령과 ANSI코드를 이용하여 원하는 위치에 load를 표시한다.
2) 1~9초간격으로 새로운 데이터를 표시한다.
3) '로그 모니터링시 특정 문자를 highlight하기' ( http://coffeenix.net/board_view.php?bd_code=1562 , 글 좋은진호)에서 소개한 방법을 이용하여 load별로 다른 색을 표시한다.
------- --------
load 색깔
------- --------
0.0 하얀색
0.1~0.39 녹 색
0.4~0.79 파란색
0.8~이상 빨간색
------- --------
4) 숫자 1~9까지 누르면 시간 간격을 변경할 수 있다. (단, foreground로 실행시)
5) q를 누르면 종료한다. (단, foreground 실행시)
참고로 서버는 10여대 정도만 샘플로 표시하였으며, 이미지상의 서버명은 실제 사용하지 않는 임의의 서버명이다.
[ load 모니터링 샘플 화면 ]
2. 미리 준비되어 있어야할 사항
통합 로그 서버와 각 서버에서 load를 보내주도록 처리해야 한다. 구축 방법에 대해서는 간략히 얘기하고, 시간이 될 때 추가 문서를 통해 설명하겠다.
1) 각 서버에서는 logger를 활용하여 서버의 load를 syslogd로 보내준다.
LOAD="`uptime|awk -F': '{print $2}'`" logger -p 로그의레빌 -t LOAD "호스트명 -> 현재시간 load $LOAD" |
syslogd 는 load부분에 대한 로그를 통합로그로 보내지도록 설정해야 한다. 이 때 서버의 load는 5~10초 간격, 또는 더 긴 간격으로 체크하여 syslogd로 보내주면 된다.
2) 통합 로그 서버에서는 각 서버의 syslog 결과를 받을 수 있도록 설정한다. 통합서버는 FreeBSD를 권장하지만, 리눅스 서버를 사용할 경우 syslog-ng를 통해서 로그 서버 구축한다. 각 서버에서 오는 load정보는 서버별로 별도 파일에 저장하도록 하는 것이 중요하다. 예를 들어 cnx10.log, cnx22.log, cnx25.log, ... 처럼. 통합로그 서버의 서버별 로그 파일에는 다음과 같이 형태로 로그가 저장된다.
Jan 6 00:00:04 192.168.123.140 LOAD: cnx10 -> 00:00:04 load 0.07, 0.03, 0.00 |
FreeBSD에서 실행할 때는 다음 2가지 사항을 체크해야 한다.
FreeBSD의 tput은 cursor 이동을 지원하지 않으므로 OpenBSD의 소스(ftp://ftp.openbsd.org/pub/OpenBSD/src/usr.bin/tput )를 가져다가 사용해야 한다. 또한 스크립트에서 사용한 read 옵션 -n, -s는 bash에 의존적으로 동작한다. /usr/ports/shells/bash ports 디렉토리에서 설치한다.
3. load 모니터링 스크립트
* load_mon.sh 내려받기
#!/bin/bash # # system load를 실시간으로 모니터링 # # by 좋은진호(truefeel, http://coffeenix.net/ ) # 2008.2.12~ # foreground로 실행할 때는 0으로, background로 할 때는 1로 fg=0 # 데이터를 실시간으로 보여줄 간격 (초단위) sleep=2 # 오른쪽에서 몇번째 칸에 표시할 것인지 설정 cols=22 # LOGDIR="/var/log/load" TPUT="/usr/bin/tput" # color szColBk="^[[;30m"; szColBk1="^[[1;30m" # black szColRe="^[[;31m"; szColRe1="^[[1;31m" # red szColGr="^[[;32m"; szColGr1="^[[1;32m" # green szColYe="^[[;33m"; szColYe1="^[[1;33m" # yellow szColBl="^[[;34m"; szColBl1="^[[1;34m" # blue szColPu="^[[;35m"; szColPu1="^[[1;35m" # magenta(purple) szColCy="^[[;36m"; szColCy1="^[[1;36m" # cyan szColGy="^[[;37m"; szColWh="^[[1;37m" # white szInverse="^[[7m" szInvOff="^[[27m" szNormal="^[[;m" # szColLev1=$szColYe szColLev2=$szColBl szColLev3=$szColRe1 # ------------------------------------------------ # keyinput () { stty -icanon read -t $sleep -n 1 -s time stty icanon case $time in [1-9]) sleep=$time C=$((`$TPUT cols` - $cols)) $TPUT cup $row $C echo "${szInverse} Delay time : $time sec $szNormal" ;; [qQ]) echo -n "^[[u" exit 0 ;; esac } # ------------------------------------------------ # 실시간 처리 시작 # ------------------------------------------------ # foreground면 화면 clear if [ $fg -eq 0 ]; then clear fi cd $LOGDIR while : do # ------------------------------------------------ # 결과값 추출 # ------------------------------------------------ cmd_local=`uptime | awk -F': ' '{print $2}'|awk -F', ' '{print $1 "|" $2 "|" $3 " "}'` cmd=`tail -1 *.log | grep : | awk '{print $6 "|" $10 "|" $11 "|" $12 " "}'` result="LOC_|$cmd_local $cmd" # highlight result_color=`echo "$result" \ | sed \ -e "s/,//g" \ -e "s/\(0\.0\)/${szColGy}\\1/g" \ -e "s/\(0\.[1-3]\)/${szColGr}\\1/g" \ -e "s/\(0\.[4-7]\)/${szColBl1}\\1/g" \ -e "s/\(0\.[8-9]\)/${szColLev3}\\1/g" \ -e "s/\([1-9]\.\)/${szColLev3}\\1/g"` # ------------------------------------------------ # cursor 위치 저장 echo -n "^[[s" $TPUT el # cleans from position to end of line # ------------------------------------------------ # 결과값을 출력 # ------------------------------------------------ col_width=`$TPUT cols` # column 길이 #지정한 cols보다 좁으면 종료 if [ $col_width -lt $cols ]; then echo "터미널의 폭이 너무 좁습니다." exit fi C=$(($col_width - $cols)) # data를 표시할 column 위치 계산 row=0 $TPUT civis # cursor 숨김 for line in $result_color do $TPUT cup $row $C # cursor 이동 row=`expr $row + 1 ` # row 증가 echo -n "$szColYe$szInverse$line$szNormal" done $TPUT cnorm # cursor 다시 표시 # ------------------------------------------------ if [ $fg -eq 0 ]; then keyinput else # cursor 위치를 원래대로 echo -n "^[[u" sleep $sleep fi done |
foreground로 스크립트를 실행할 것이면 fg=0으로 하고, background로 실행할 때는 1로 해줘야 스크립트의 기능을 제대로 사용할 수 있다. sleep=2 는 실시간으로 조회할 데이터를 몇 초 간격으로 볼 것인가를 지정한다.
LOGDIR= : 서버 load가 저장되어 있는 로그 파일의 경로
TPUT= : tput 명령의 경로. 기본 경로는 /usr/bin/tput
상단 부분의 'szCol' 로 시작하는 변수는 색깔을 정의한 ANSI 코드이다. ^[ 문자는 ESC키를 의미한다. 쉘에서 입력할 때 Ctrl+V를 누른 후 ESC키를 누르면 입력할 수 있다.
4. 스크립트 부분별 이해
keyinput () { stty -icanon read -t $sleep -n 1 -s time stty icanon case $time in [1-9]) sleep=$time C=$((`$TPUT cols` - $cols)) $TPUT cup $row $C echo "${szInverse} Delay time : $time sec $szNormal" ;; [qQ]) echo -n "^[[u" exit 0 ;; esac } |
keyinput() 함수는 foreground로 실행할 때 키입력을 받아들이는 부분이다.
read 의 -t 옵션은 입력 대기 시간이다. -t 5라면 5초동안 입력 대기를 하게 되는데, 결국 sleep 5 를 한 것과 같은 효과를 볼 수 있다. -n 1 은 1자만 입력 받는 것이고, -s는 입력한 키를 화면에 출력하지 말라는 뜻이다. 키 입력이 생기면 바로 그 다음줄이 실행되며, 입력되지 않더라도 대기시간이 지나면 넘어가게 된다. 결국 keyinput()함수는 프로그램의 실행에 방해를 주지 않으면서 원하는 키입력을 받아들이는 역할을 하게 된다.
1~9까지 입력(즉, 1~9초에 해당)하면 delay time을 변경하고, 화면 변경됐음을 보여준다. q를 누르면, 적당한 곳으로 커서를 옮기고 종료한다.
cmd_local=`uptime | awk -F': ' '{print $2}'|awk -F', ' '{print $1 "|" $2 "|" $3 " "}'` cmd=`tail -1 *.log | grep : | awk '{print $6 "|" $10 "|" $11 "|" $12 " "}'` |
원하는 데이터 값을 가져오는 부분이다.
$cmd_local : 스크립트를 실행중인 서버의 load가 저장된다. '0.03|0.01|0.00'
$cmd : load가 저장된 각 서버별 로그파일의 맨 마지막 줄(가장 최근 load)를 읽어서 변수에 저장한다.
'cnx10|1.00,|1.00,|0.95 cnx22|0.39,|0.38,|0.35 cnx25|0.31,|0.24,|0.18 ... 생략...'
'서버명|1분load|5분load|15분load' 형태이며, 서버간의 구분은 반드시 1개 이상의 공백으로 해야 한다.
C=$(($col_width - $cols)) # data를 표시할 column 위치 계산 row=0 $TPUT civis # cursor 숨김 for line in $result_color do $TPUT cup $row $C # cursor 이동 row=`expr $row + 1 ` # row 증가 echo -n "$szColYe$szInverse$line$szNormal" done $TPUT cnorm # cursor 다시 표시 |
data를 표시할 위치를 오른쪽 상단, 오른쪽에서 $cols 번째칸으로 한다. 그런 후 서버마다 한줄에 한칸씩 보여준다. 화면에 표시될 때 커서는 안보이게 했다가(civis), 데이터가 다 뿌려지면 다시 보이도록 했다(cnorm).
다음은 실제 모니터링하는 화면이다. 3개의 화면을 연속으로 캡쳐한 것이다. 3초 간격, 3초 간격, 그리고 숫자 '5'를 누른 후 5초간격으로 보여주겠다는 화면이다.
highlight 처리 부분에 대한 설명은 참고문서로 대신한다. 그리고, 재미난 시계 스크립트를 소개한 'Sergio Gonzalez Duran'씨에게 감사드린다.
5. 참고자료
* CLI Magic: Use ANSI escape sequences to display a clock in your terminal
http://www.linux.com/feature/124918
* 로그 모니터링시 특정 문자를 highlight하기 (글 좋은진호, 2008.1)
http://coffeenix.net/board_view.php?bd_code=1562
* bash 맨페이지 중에 'read' 부분
* tput: Portable Terminal Control
http://www.gnu.org/software/termutils/manual/termutils-2.0/html_chapter/tput_1.html