안녕하세요. 오늘은 여러 대의 애플리케이션 서버(AP)에 분산되어 쌓이는 로그를 매번 접속하지 않고, 한 번의 명령으로 취합하여 분석할 수 있는 유용한 셸 스크립트(analLog.sh)를 공유합니다.
이 스크립트는 특히 다수의 서버에서 특정 BPEL 프로세스의 완료 로그를 찾아 실행 시간 통계(최소, 최대, 평균 시간)를 빠르게 확인해야 할 때 매우 유용합니다.
스크립트의 주요 기능
analLog.sh 스크립트는 4대의 지정된 원격 서버(AP1~AP4)에 ssh로 자동 접속하여 다음 작업을 수행합니다.
- 로그 필터링: 사용자가 지정한 디렉터리(
-f)에서 특정 메시지명(-m)을 포함하는BPEL COMPLETED로그를 검색합니다. - 시간대 지정: 지정된 날짜(
-d)와 시간(-t) 패턴에 일치하는 로그만 추출합니다. - 성능 데이터 추출: 로그에 기록된
Elapsed time = [숫자] miliseconds패턴을 찾아 실행 시간(숫자) 값만 파싱합니다. - 통계 집계:
awk를 사용하여 각 서버별 및 전체 서버의 **총 로그 건수(Count), 최소 시간(Min), 최대 시간(Max), 평균 시간(Avg)**을 밀리초(ms) 단위로 계산합니다. - (선택) 분당/초당 처리량:
-l [분]옵션을 제공하면, 지정한 시간(분)을 기준으로 분당 및 초당 평균 처리 건수를 함께 계산해 줍니다.
사용 방법 (Usage)
스크립트는 getopts를 사용하여 표준 옵션 인자를 받습니다.
Bash
Usage: analLog.sh -m [MESSAGE] -d [DATE] -t [TIME] -f [DIRECTORY]
Try 'analLog.sh -help' for more information.
옵션 상세:
-m: 검색할 메시지 이름 (예:AlarmReport.bpel)-d: 검색할 날짜 (예:20/07/02)-t: 검색할 시간 (예:01:17:또는01:[0-9][0-9]:)-f: 검색할 원격 서버의 로그 디렉터리 경로 (예:/mesap_log/EEXsvr/20200702)-l(선택 사항): 분석 대상 시간(분). (예:60)
실행 예시:
Bash
./analLog.sh -m AlarmReport.bpel -d 25/10/21 -t 08:15: -f /mesap_log/EEXsvr/20251021
전체 스크립트 코드
Bash
#!/bin/bash
### Created by Ho Seop Lee of Aim System.
### Initialization
usageMsg="Usage: analLog.sh -m [MESSAGE] -d [DATE] -t [TIME] -f [DIRECTORY]
Try 'analLog.sh -help' for more information."
helpMsg='
\t-m\t\tMessage Name\t(ex: -m AlarmReport.bpel)
\t-d\t\tDate\t\t(ex: -d 20/07/02)
\t-t\t\tTime\t\t(ex: -t 01:17: or -t 01:[0-9][0-9]:)
\t-f\t\tDirectory Path\t(ex: -f /mesap_log/EEXsvr/ or -f /mesap_log/EEXsvr/20200702)
\t-l (Optional)\tMinutes should be analyzed\t(ex: -l 60)
\t-h, -help, -?\tShow Help Info
'
cols=`tput cols`
for((i=0; i<$cols; i++));
do
line=$line'=';
done
function printLine()
{
echo $line
}
usage()
{
echo -e "$usageMsg"
printLine
exit 0
}
help()
{
echo -e "$helpMsg"
printLine
exit 0
}
printLine
### Declaration Option Argument
if [[ ! $@ =~ ^\-.+ ]]
then
usage;
fi
while getopts m:d:t:f:l:h? OPT
do
case $OPT in
m) msg=$OPTARG;;
d) date=$OPTARG;;
t) time=$OPTARG;;
f) dir=$OPTARG;; # [FIXED] 원본의 'd)'를 'f)'로 수정
l) howMinute=$OPTARG;;
h) help;;
?) help;;
esac
done
echo "Arg msg: $msg"
echo "Arg date: $date"
echo "Arg time: $time"
echo "Arg directory: $dir"
echo "Arg howMinute: $howMinute"
### Analyze log from each AP by remote ssh
# [FIXED] AP1의 grep에 '-s' 옵션을 추가하여 다른 AP와 일관성 유지
# echo 'AP1 p7mesfab@172.25.4.17';
ap_summary=`ssh p7mesfab@172.25.4.17 grep "-sE '***** BPEL COMPLETED :: "${msg}"' "${dir}/*"" | grep -P "${date} ${time}" | grep -Po '(?<=Elapsed time = )\w+(?= miliseconds)' | awk 'BEGIN {min=999999;max=1} {if($1>max) {max=$1}; if($1<min) {min=$1}; total+=$1; count+=1} END {if(count>0) {print "AP1 count: "count" min: "min" max: "max" avg: "total/count}}'`
# echo 'AP1 p7mesfab@172.25.4.18';
ap_summary=$ap_summary"\n"`ssh p7mesfab@172.25.4.18 grep "-sE '***** BPEL COMPLETED :: "${msg}"' "${dir}/*"" | grep -P "${date} ${time}" | grep -Po '(?<=Elapsed time = )\w+(?= miliseconds)' | awk 'BEGIN {min=999999;max=1} {if($1>max) {max=$1}; if($1<min) {min=$1}; total+=$1; count+=1} END {if(count>0) {print "AP2 count: "count" min: "min" max: "max" avg: "total/count}}'`
# echo 'AP1 p7mesfab@172.25.4.19';
ap_summary=$ap_summary"\n"`ssh p7mesfab@172.25.4.19 grep "-sE '***** BPEL COMPLETED :: "${msg}"' "${dir}/*"" | grep -P "${date} ${time}" | grep -Po '(?<=Elapsed time = )\w+(?= miliseconds)' | awk 'BEGIN {min=999999;max=1} {if($1>max) {max=$1}; if($1<min) {min=$1}; total+=$1; count+=1} END {if(count>0) {print "AP3 count: "count" min: "min" max: "max" avg: "total/count}}'`
# echo 'AP1 p7mesfab@172.25.4.34';
ap_summary=$ap_summary"\n"`ssh p7mesfab@172.25.4.34 grep "-sE '***** BPEL COMPLETED :: "${msg}"' "${dir}/*"" | grep -P "${date} ${time}" | grep -Po '(?<=Elapsed time = )\w+(?= miliseconds)' | awk 'BEGIN {min=999999;max=1} {if($1>max) {max=$1}; if($1<min) {min=$1}; total+=$1; count+=1} END {if(count>0) {print "AP4 count: "count" min: "min" max: "max" avg: "total/count}}'`
ap_summar=`echo -e $ap_summary | grep "AP"`
### Show Analysis
echo
echo -e "$ap_summar" # [FIXED] 줄바꿈이 적용된 '$ap_summar' 변수로 수정
echo
if [ -z $howMinute ]; then
# [FIXED] "Total Count: " 중복 오타 수정
echo -e "$ap_summar" | awk 'BEGIN {min=99999;max=0} length($0) > 0 {total+=$3; if($5<min) {min=$5}; if($7>max) {max=$7}; count+=1; avg_sum+=$9} END {print "Total Count: "total", Min(ms): "min", Max(ms): "max", Avg(ms): "avg_sum/count}'
elif [ $howMinute -gt 0 ]; then
echo -e "$ap_summar" | awk -v howMinute=$howMinute 'BEGIN {min=99999;max=0} length($0) > 0 {total+=$3; if($5<min) {min=$5}; if($7>max) {max=$7}; count+=1; avg_sum+=$9} END {print "Total Count: "total", Count/m: "total/howMinute", Count/s: "total/howMinute/60", Min(ms): "min", Max(ms): "max", Avg(ms): "avg_sum/count", Avg(s): "avg_sum/count/1000}'
fi
printLine
exit 0
사용 방법 예시

시간 Option에 정규식 입력 시, Back Slash를 사용하려면 Back Slash를 두 번 써야 하는 불편함이 있습니다.
마무리
이 스크립트를 활용하면 여러 서버의 로그를 확인하기 위해 반복적으로 접속하고 grep 명령을 실행하는 수고를 덜 수 있습니다. IP 주소나 grep 패턴을 환경에 맞게 수정하여 다양하게 활용해 보시기 바랍니다.
