리눅스상에서 trace dump, logging, 기타 작업들을 손쉽게 해주는 툴을 제작 중에 있습니다.
아직 미완성이지만 일부만 올려봅니다. 나중에 완성되면 완성본을 올리겠습니다.
아래는 core menu 실행화면입니다. CUI 환경에서도 interactive 하게 동작되도록 whiptail을 이용하여 제작하였습니다.
<main menu>
<tracedump menu>
<KDUMP Warning>
<DropCache, Search data by Index, Find History>
<History Period Setup>
아래는 sysman 유틸리티의 core script 일부분입니다.
#!/bin/bash
# This script code is SysMan(SystemManager) core menu.
clear
###### Load config for sysman ######
if [ -f ./conf_sysman ]; then
. ./conf_sysman
else
. core/conf_sysman
fi
export SYSMANDIR=$SYSMANDIR
###### Load config for sysman ######
###### Functions Start ######
## Funtion of random number ##
randomcount () {
MAXCOUNT=10
count=1
while [ "$count" -le $MAXCOUNT ]
do
rannum=$RANDOM
let "count += 1"
done
RANGE=1024
FLOOR=0
rannum=0
while [ "$rannum" -le $FLOOR ]
do
rannum=$RANDOM
let "rannum %= $RANGE"
done
}
## Funtion of user check ##
is_root () {
if [ "$EUID" -eq 0 ]; then
return 0;
else
WHO=$(whoami)
return 1;
fi
}
## Funtion of define for window size ##
calc_wt_size() {
WT_HEIGHT=17
WT_WIDTH=$(tput cols)
if [ -z "$WT_WIDTH" ] || [ "$WT_WIDTH" -lt 60 ]; then
WT_WIDTH=80
fi
if [ "$WT_WIDTH" -gt 178 ]; then
WT_WIDTH=120
fi
WT_MENU_HEIGHT=$(($WT_HEIGHT-12))
}
## Funtion of progress bar ##
PROGSLEEP=0.5
PROGCOUNT=2
progress_bar() {
PER=$(bc <<< "100/$PROGCOUNT")
for ((i=$PER ; i<=100 ; i+=$PER))
do
echo $i
sleep $PROGSLEEP
MAX=$(bc <<< "100-$i")
if [ $PER -gt $MAX ]; then
if ! [ $MAX -eq 0 ]; then
echo 100
fi
fi
done
}
check_log_status () {
MAX=100
sleep 0.1
while true
do
if [ "$LOGCHK" = "0" ]; then
break;
fi
if [ $MAX -eq 0 ]; then
break;
fi
sleep 0.1
let MAX-=1
done
# {
# if [ $MAX -eq 0 ]; then
# echo ""
# fi
# } | whiptail --msgbox "* TIMEOVER" 10 60
}
running_check () {
MAXCHK=1
while [ 1 ]
do
if [ -n $LOGCHKDIR ]; then
grep _Running `eval echo $LOGCHKDIR` >& /dev/null
if [ $? = 0 ]; then
break;
fi
fi
if [ $MAXCHK -eq 100 ]; then
echo "카운트가 $MAXCHK 을 넘었습니다." >> $LOGCHKDIR
whiptail --msgbox "$LOGCHKDIR 체크 실패. $LOGCHKDIR 로그를 확인하세요." 12 100
break
fi
sleep 0.1
#let MAXCHK+=1
#let "MAXCHK += 1"
#(( MAXCHK ++ ))
MAXCHK=$[$MAXCHK +1]
done
}
## Funtion of do_monitor ##
function do_monitor {
CHOICE=$(whiptail --title "<<Log Manger>>" --menu "항목을 선택하세요" $WT_HEIGHT $WT_WIDTH $WT_MENU_HEIGHT \
"P PortMonitor" " - 정의된 네트워크 포트 모니터링 및 로깅 >>" \
"L LogMaker " " - 정의된 양식의 결과값 로깅 >>" \
3>&1 1>&2 2>&3)
RET=$?
if [ $RET = 1 ]; then
return 0
elif [ $RET = 0 ]; then
case "$CHOICE" in
P\ *) do_monitor_port ;;
L\ *) do_monitor_logmaker ;;
*) whiptail --msgbox "Programmer error: unrecognized option" 20 60 1 ;;
esac || whiptail --msgbox "There was an error running option $CHOICE" 20 60 1
fi
}
## Funtion of do_monitor_port ##
function do_monitor_port {
randomcount
CONFIGS=$(cat $SYSMANDIR/apps/portmonitor/portmonitor.conf | egrep -v '^#|^$')
whiptail --yesno "*지정된 client 포트를 모니터링합니다.\n\n*설정파일: $SYSMANDIR/apps/portmonitor/portmonitor.conf\n\n*설정현황:\n$CONFIGS\n\n\n 모니터링을 시작하시겠습니까?" 20 60 1
RET=$?
if [ $RET = 0 ]; then
{
{
$SYSMANDIR/apps/portmonitor/portmonitor.sh
} 1> $SYSMANDIR/apps/portmonitor/tmp_portmonitor$rannum 2>&1 &
PID=$!
sleep 0.2
PORTSS=$(grep PORTS $SYSMANDIR/apps/portmonitor/portmonitor.conf | grep -v ^#)
INT=$(grep Interval $SYSMANDIR/apps/portmonitor/tmp_portmonitor$rannum | awk -F ": " '{print $2}')
BTI=$(grep Break $SYSMANDIR/apps/portmonitor/tmp_portmonitor$rannum | awk -F ": " '{print $2}' | awk -F '' '{print $1$2$3$4"."$5$6"."$7$8". "$9$10}')
LOG=$(grep Log $SYSMANDIR/apps/portmonitor/tmp_portmonitor$rannum | awk -F ": " '{print $2}')
if [ -z "$INT" ]; then
RESULT="*포트모니터링 실행에 문제가 발생했습니다.\n문제점: `sed -r "s/\x1B\[([0-9]{1,2}(;[0-9]{1,2})?)?[m|K]//g" $SYSMANDIR/apps/portmonitor/tmp_portmonitor$rannum`"
else
RESULT="*포트모니터링이 시작되었습니다.\n\n*실행정보: PID '$PID'로 '$PORTSS'을 Interval '$INT'간격으로 '$BTI'시까지 수행됩니다.\n*로그위치: $LOG"
fi
rm -f $SYSMANDIR/apps/portmonitor/tmp_portmonitor$rannum
echo $RESULT > result_tmp"$rannum"
progress_bar
} | whiptail --gauge "Getting data ..." 6 60 0
read -r result_tmp`` < result_tmp"$rannum"
rm -f result_tmp"$rannum"
whiptail --msgbox "$result_tmp" 12 120
#result_tmp=""
else
return 0
fi
}
function do_monitor_logmaker {
randomcount
ls $SYSMANDIR/apps/logmaker/*.conf >& /dev/null
CONFSTATUS=$?
read -ra confs <<< $(ls $SYSMANDIR/apps/logmaker/*.conf | grep -n "" | awk '{print $NF}' | sed 's/\://g' | awk -F "/" '{print $NF; print "<"$1">"}')
OPTION=$(whiptail --title "<<<Log Maker>>>" --menu "항목을 선택하세요" $WT_HEIGHT $WT_WIDTH $WT_MENU_HEIGHT "${confs[@]}" 3>&1 1>&2 2>&3)
RET=$?
if [ $CONFSTATUS = 0 ]; then
if [ $RET = 0 ]; then
CONFIGS=$(cat $SYSMANDIR/apps/logmaker/$OPTION | egrep -v '^#|^$')
whiptail --yesno "*정의된 command로 로깅을 시작합니다.\n\n*설정파일: $SYSMANDIR/apps/logmaker/$OPTION\n\n*설정현황:\n$CONFIGS\n\n\n 로깅을 시작하시겠습니까?" 20 100 1
RET1=$?
if [ "$RET1" = 0 ]; then
{
{
$SYSMANDIR/apps/logmaker/logmaker.sh "--conf=$OPTION"
} 1> $SYSMANDIR/apps/logmaker/tmp_logmaker$rannum 2>&1 &
PID=$!
sleep 0.2
COMMAND=$(grep COMMAND $SYSMANDIR/apps/logmaker/"$OPTION" | grep -v ^#)
INT=$(grep Interval $SYSMANDIR/apps/logmaker/tmp_logmaker$rannum | awk -F ": " '{print $2}')
BTI=$(grep Finish $SYSMANDIR/apps/logmaker/tmp_logmaker$rannum | awk -F ": " '{print $2}')
LOG=$(grep Log $SYSMANDIR/apps/logmaker/tmp_logmaker$rannum | awk -F ": " '{print $2}')
if [ -z "$INT" ]; then
RESULT="*로깅 실행에 문제가 발생했습니다.\n문제점: `sed -r "s/\x1B\[([0-9]{1,2}(;[0-9]{1,2})?)?[m|K]//g" $SYSMANDIR/apps/logmaker/tmp_logmaker$rannum | head -2`"
else
RESULT="*로깅이 시작되었습니다.\n\n*실행정보: PID '$PID'로 '$COMMAND'을 '$INT'초 간격으로 '$BTI'시까지 수행됩니다.\n*로그위치: $LOG"
fi
rm -f $SYSMANDIR/apps/logmaker/tmp_logmaker$rannum
echo $RESULT > result_tmp"$rannum"
progress_bar
} | whiptail --gauge "Getting data ..." 6 60 0
read -r result_tmp`` < result_tmp"$rannum"
rm -f result_tmp"$rannum"
whiptail --msgbox "$result_tmp" 12 100
#whiptail --msgbox "$(cat "$SYSMANDIR/apps/logmaker/tmp_logmaker$rannum")" 12 120
#rm -f $SYSMANDIR/apps/logmaker/tmp_logmaker$rannum
else
do_monitor_logmaker
fi
else
return 0
fi
elif [ $CONFSTATUS = 2 ]; then
whiptail --msgbox "*config 파일이 없습니다.\n$SYSMANDIR/apps/logmaker 디렉토리로 이동 후 XX.conf를 생성하십시오." 12 100
else
return 0
fi
}
function do_etc {
CHOICE=$(whiptail --title "<<ETC Manager>>" --menu "항목을 선택하세요" $WT_HEIGHT $WT_WIDTH $WT_MENU_HEIGHT \
"D DROPCACHE " " - Buffers/Cached 메모리 정리 >>" \
"S SEARCH FILE" " - Index를 통한 파일/디렉토리 찾기 >>" \
"L SEARCH HISTORY" " - History를 통한 command 기록 찾기 >>" \
3>&1 1>&2 2>&3)
RET11=$?
if [ $RET11 = 1 ]; then
return 0
elif [ $RET11 = 0 ]; then
case "$CHOICE" in
D\ *) do_etc_dropcache ;;
S\ *) do_etc_find ;;
L\ *) do_etc_loginhist ;;
*) whiptail --msgbox "Programmer error: unrecognized option" 20 60 1 ;;
esac || whiptail --msgbox "There was an error running option $CHOICE" 20 60 1
fi
}
function do_etc_dropcache {
if is_root ; then
randomcount
whiptail --yesno "*System Buffer/Cached 메모리를 정리합니다.\n\n*주의: 시스템 I/O 사용량이 없을때 실행하십시오.\n\n\n 실행 하시겠습니까?" 15 60 1
RET=$?
if [ $RET = 0 ]; then
{
{
$SYSMANDIR/apps/dropcache/do_drop_cache.sh
} 1> $SYSMANDIR/apps/dropcache/tmp_do_drop_cache$rannum 2>&1 &
PID=$!
sleep 0.2
LOG=$(grep log $SYSMANDIR/apps/dropcache/tmp_do_drop_cache$rannum)
if [ -z $LOG ]; then
RESULT="*Drop Cache에 문제 발생.\n$LOG 로그파일을 확인하십시오."
else
RESULT="*Drop Cache가 잘 수행되었습니다.\n결과LOG파일 :"
fi
#rm -f $SYSMANDIR/apps/dropcache/tmp_do_drop_cache$rannum
PROGSLEEP=0.5
PROGCOUNT=10
progress_bar
MAXCOUNT=100
while true
do
if [ $MAXCOUNT -eq 1 ]; then
RESULT="Log 생성 시간이 초과되었습니다.\n $LOG 파일이 정상인지 확인 하십시오."
break
fi
grep END $LOG >& /dev/null
if [ $? = 0 ]; then
break
fi
sleep 0.2
let MAXCOUNT-=1
done
echo $RESULT > result_tmp"$rannum"
} | whiptail --gauge "Drop the Buffers/Cached of Memory 수행 중 ..." 6 50 0
read -r result_tmp`` < result_tmp"$rannum"
rm -f result_tmp"$rannum"
whiptail --msgbox "$result_tmp $(cat "$SYSMANDIR/apps/dropcache/tmp_do_drop_cache$rannum")" 25 80
rm -f $SYSMANDIR/apps/dropcache/tmp_do_drop_cache$rannum
else
return 0
fi
else
whiptail --msgbox "You are not root. You are $WHO\nCan be run only root." 20 60 1
fi
}
## Funtion of do_dump ##
function do_dump {
if is_root ; then
randomcount
APP="apps/dumpman"
ls $SYSMANDIR/$APP/*.conf >& /dev/null
CONFSTATUS=$?
read -ra confs <<< $(ls $SYSMANDIR/$APP/*.conf | grep -n "" | awk '{print $NF}' | sed 's/\://g' | awk -F "/" '{print "\""$NF"\""; print "\"<"$1">\""; print "OFF"}')
OPTION=$(whiptail --title "<<Dump Manger>>" --checklist "선택한 항목들에 대한 dump를 수집합니다." 15 60 6 "${confs[@]}" 3>&1 1>&2 2>&3)
RET=$?
if [ $CONFSTATUS = 0 ]; then
if [ $RET = 0 ]; then
if [ -z "$OPTION" ]; then
whiptail --msgbox "* No Selected. Select, please." 12 100
do_dump
fi
echo $OPTION | grep 'vmcore_kdump' >& /dev/null
if [ $? = 0 ]; then
LOGDIR=$(echo `grep ^LOGDIR $SYSMANDIR/$APP/dumpman.sh | head -1 | awk -F "=" '{print $2}'`)
if [ -d `eval echo "$LOGDIR"` ]; then
eval rm -f "$LOGDIR/dump_logcheck[1-9]*"
eval touch $LOGDIR/dump_logcheck$rannum
else
mkdir -p `eval echo "$LOGDIR"`
eval touch $LOGDIR/dump_logcheck$rannum
fi
sleep 0.1
export LOGCHKDIR="$LOGDIR/dump_logcheck$rannum"
while [ 1 ]
do
whiptail --inputbox "***주의**** vmcore_kdump를 선택하셨습니다.\n*아래에 $rannum 을 입력 후 진행하면 커널패닉이 발생됩니다." 8 70 --title "RUN KDUMP" 2>> $SYSMANDIR/core/tmp_kdump_$rannum
RET2=$?
if [ $RET2 = 0 ]; then
grep $rannum $SYSMANDIR/core/tmp_kdump_$rannum >& /dev/null
RET3=$?
if [ $RET3 = 1 ]; then
whiptail --msgbox "* 숫자를 잘 못 입력하셨습니다." 10 60
cat /dev/null > $SYSMANDIR/core/tmp_kdump_$rannum
rm -f $SYSMANDIR/core/tmp_kdump_$rannum
else
sed -i 's/^ENABLE.*/ENABLE="yes"/' $SYSMANDIR/$APP/vmcore_kdump.conf
break
fi
else
rm -f $SYSMANDIR/core/tmp_kdump_$rannum
do_dump
fi
done
rm -f $SYSMANDIR/core/tmp_kdump_$rannum
elif [ $? = 1 ]; then
LOGDIR=$(echo `grep ^LOGDIR $SYSMANDIR/$APP/dumpman.sh | head -1 | awk -F "=" '{print $2}'`)
if [ -d `eval echo "$LOGDIR"` ]; then
eval rm -f "$LOGDIR/dump_logcheck[1-9]*"
eval touch $LOGDIR/dump_logcheck$rannum
else
mkdir -p `eval echo "$LOGDIR"`
eval touch $LOGDIR/dump_logcheck$rannum
fi
sleep 0.1
export LOGCHKDIR="$LOGDIR/dump_logcheck$rannum"
fi
{
read -ra selectlist <<< $(echo $OPTION | sed 's/\"\"//g')
for i in "${selectlist[@]}"
do
{
# dumpman.sh runs independently of this script. (The line below)
nohup $SYSMANDIR/$APP/dumpman.sh --conf="$i"
# dumpman.sh runs dependently of this script. If this script is finished and dumpman.sh is over. (The line below)
# $SYSMANDIR/$APP/dumpman.sh --conf="$i" &
} 1>> $SYSMANDIR/$APP/tmp_dumpman$rannum 2>&1 &
PID=$!
sleep 0.1
running_check
done
echo $OPTION | grep "\ " >& /dev/null
if [ $? = 0 ]; then
MAXTIMEOUT=$(eval cat $SYSMANDIR/$APP/{`echo $OPTION|sed 's/\ /,/g'`} | grep TIMEOUT= | awk -F "\"" '{print $2}' | sort -nr | head -1)
elif [ $? = 1 ]; then
MAXTIMEOUT=$(eval cat $SYSMANDIR/$APP/`echo $OPTION` | grep TIMEOUT= | awk -F "\"" '{print $2}' | sort -nr | head -1)
fi
PROGCOUNT=$MAXTIMEOUT
PROGSLEEP=0.8
progress_bar
LOGCHK=$(lsof -t `echo $SYSMANDIR/$APP/tmp_dumpman$rannum` | wc -l)
check_log_status
INT=$(grep ^Dumping $SYSMANDIR/$APP/tmp_dumpman$rannum | awk -F ": " '{print $2}')
LOG=$(grep ^Log $SYSMANDIR/$APP/tmp_dumpman$rannum | awk -F ": " '{print $2}')
PROCLIST=$(echo $LOG | awk -F "-" '{print $2}')
echo $INT
if [ -z "$INT" ]; then
RESULT="*덤프 실행에 문제가 발생했습니다.\n문제점: `sed -r "s/\x1B\[([0-9]{1,2}(;[0-9]{1,2})?)?[m|K]//g" $SYSMANDIR/$APP/tmp_dumpman$rannum`"
else
RESULT="*덤프가 수행되었습니다.\n\n*실행정보: PID '$PID'로 '$INT'간 수행되었습니다.\n엔터를 누르면 상세 정보가 출력됩니다."
fi
echo $RESULT >> result_tmp"$rannum"
} | whiptail --gauge "Getting data ..." 6 60 0
read -r result_tmp`` < result_tmp"$rannum"
rm -f result_tmp"$rannum"
whiptail --msgbox "$result_tmp" 10 70
whiptail --msgbox --scrolltext "$(cat "$SYSMANDIR/$APP/tmp_dumpman$rannum")" 30 120
rm -f $SYSMANDIR/$APP/tmp_dumpman$rannum
return 0
#elif [ $RET = 1 ]; then
# return 0
# echo $RET
else
exit ####### RET 변수에 대한 처리. 바로 전단계 do_dump 로 가지 못해 exit 처리
fi
else
whiptail --msgbox "* Check config files. Check, please." 12 60
return 0
fi
else
whiptail --msgbox "You are not root. You are $WHO\nCan be run only root." 20 60 1
fi
}
## Funtion of do_loginhist ##
function do_etc_loginhist {
APP="apps/loginhist"
CURTIME=`date +%Y%m%d" "%H -d "+1 hours"`
PASTTIME=`date +%Y%m%d" "%H -d "-24 hours"`
INPUTPERI=$(whiptail --inputbox "$PASTTIME $CURTIME -> 예시\n<아래는 '현재 -24시간' ~ '현재 +1시간'을 반영한 디폴트 기간입니다>\n<필요시 원하는 기간으로 수정 또는 그냥 진행하면 디폴트 기간이 반영됨>" 12 78 "$PASTTIME $CURTIME" --title "Input Period" 3>&1 1>&2 2>&3)
RET6=$?
if [ $RET6 = 0 ]; then
IFS=' ' read -r -a array <<< "$INPUTPERI"
STARTDATE=$(echo "$INPUTPERI" | awk '{print $1}' | awk -F "" '{print $5$6"/"$7$8"/"$1$2$3$4}')
date -d "$STARTDATE" > /dev/null 2>&1
STARTDATE_VALID=$?
STARTTIME=$(echo "$INPUTPERI" | awk '{print $2}')
date "+%H" -d "$STARTTIME" > /dev/null 2>&1
STARTTIME_VALID=$?
ENDDATE=$(echo "$INPUTPERI" | awk '{print $3}' | awk -F "" '{print $5$6"/"$7$8"/"$1$2$3$4}')
date -d "$ENDDATE" > /dev/null 2>&1
ENDDATE_VALID=$?
ENDTIME=$(echo "$INPUTPERI" | awk '{print $4}')
date "+%H" -d "$ENDTIME" > /dev/null 2>&1
ENDTIME_VALID=$?
STIME=$(echo "$INPUTPERI" | awk '{print $1$2}')
ETIME=$(echo "$INPUTPERI" | awk '{print $3$4}')
if [ ! ${#array[@]} = 4 ]; then
whiptail --msgbox "* 요구되는 포맷에 맞지 않게 입력했습니다.\n아래와 같이 4개의 값을 입력하세요.\n$PASTTIME $CURTIME" 10 60
do_etc_loginhist
elif [ $STARTDATE_VALID = 1 ] || [ $STARTTIME_VALID = 1 ] || [ $ENDDATE_VALID = 1 ] || [ $ENDTIME_VALID = 1 ] ; then
whiptail --msgbox "* 정상 범위를 벗어난 시간을 입력했습니다.\n입력값: $INPUTPERI" 10 60
do_etc_loginhist
elif [ $STIME -gt $ETIME ]; then
whiptail --msgbox "* 기간이 잘 못 되었습니다. 끝 시간이 시작보다 과거임." 10 60
do_etc_loginhist
else
$SYSMANDIR/$APP/loginhist.sh $INPUTPERI &
{
progress_bar
LOGCHK=$(lsof -t `echo $SYSMANDIR/logs/loginhist_log/loginhist.result` | wc -l)
check_log_status
} | whiptail --gauge "Getting data ..." 6 60 0
whiptail --msgbox --scrolltext "로그: $SYSMANDIR/logs/loginhist_log/loginhist.result\n$(cat "$SYSMANDIR/logs/loginhist_log/loginhist.result")" 40 130
#whiptail --msgbox "* $INPUTPERI 기간의 history 로그를 기록하였습니다.\n로그파일: $SYSMANDIR/logs/loginhist_log/loginhist.result" 10 60
do_etc
fi
else
do_etc
fi
}
#do_monitor_logmaker () {
#while true
#do
# read -ra confs <<< $(ls $SYSMANDIR/apps/logmaker/*.conf | awk '{print $NF}' | awk -F "/" '{print $NF; print $NF}')
# OPTION=$(whiptail --title Networking --menu "Select a config." 16 78 5 "${confs[@]}" 3>&1 1>&2 2>&3)
# RET=$?
# if [ $RET = 0 ]; then
# #let OPTION=$OPTION-1
# randomcount
# echo "Running option:" $OPTION
# $SYSMANDIR/apps/logmaker/logmaker.sh "--conf=$OPTION"
# else
# exit
# fi
#done
#}
## Funtion of do_tor_logmakerdump_tcp ##
#function do_dump_tcp {
# {
# {
# $SYSMANDIR/apps/tcpdump/do_dump_tcp.sh
# } 1>/dev/null 2>&1
# source <(grep '^LOGFILE=' $SYSMANDIR/apps/tcpdump/do_dump_tcp.sh)
# RESULT="Create tcpdump log: $LOGFILE"
# echo $RESULT > result_tmp"$rannum"
# progress_bar
# } | whiptail --gauge "Getting data ..." 6 60 50
#}
###### Functions End ######
###### Interactive use loop Start ######
if [ "$INTERACTIVE" = True ]; then
calc_wt_size
while [ 1 ]
do
CHOICE=$(whiptail --title "<Systems Manager>" --menu "항목을 선택하세요" $WT_HEIGHT $WT_WIDTH $WT_MENU_HEIGHT \
"L" "Log - <<Log Manager>>" \
"D" "Dump - <<Dump Manager>>" \
"E" "ETC - <<ETC Manager>>" \
"Q" "QUIT - <<Quit Manager>>" \
3>&2 2>&1 1>&3)
RET=$?
if [ $RET -eq 1 ]; then
exit
elif [ $RET -eq 0 ]; then
case $CHOICE in
"L") do_monitor ;;
"D") do_dump ;;
"E") do_etc ;;
"Q") exit ;;
esac
else
exit 1
fi
done
fi
###### Interactive use loop End ######
SysMan(System Manager) script




