2m 21s 동안 처리함
ㅇㅇ. 각 항목을 20분씩 따로 보는 게 아니라 전부 동시에 20분 돌리면 됨.
아래 스크립트를 서버마다 동시에 걸어두면 4대여도 총 소요시간은 20분임.
sysstat의 sar / iostat / pidstat가 설치돼 있다는 전제로 만들면 제일 깔끔함.
#!/bin/bash
export LC_ALL=C
export S_TIME_FORMAT=ISO
INTERVAL=10
COUNT=120
TMP=TMP"' EXIT
IFACE=$(ip route show default | awk 'NR==1 {print $5}')
for CMD in sar iostat pidstat; do
if ! command -v "$CMD" >/dev/null 2>&1; then
echo "ERROR: $CMD 없음 (sysstat 확인 필요)"
exit 1
fi
done
RX_ERR_1=IFACE/statistics/rx_errors 2>/dev/null || echo 0)
TX_ERR_1=IFACE/statistics/tx_errors 2>/dev/null || echo 0)
RX_DROP_1=IFACE/statistics/rx_dropped 2>/dev/null || echo 0)
TX_DROP_1=IFACE/statistics/tx_dropped 2>/dev/null || echo 0)
sar -u INTERVAL $COUNT > "TMP/cpu" &
sar -r INTERVAL $COUNT > "TMP/mem" &
sar -n DEV INTERVAL $COUNT > "TMP/net" &
iostat -y -dx INTERVAL $COUNT > "TMP/disk" &
pidstat -u INTERVAL $COUNT > "TMP/pcpu" &
pidstat -r INTERVAL $COUNT > "TMP/pmem" &
wait
RX_ERR_2=IFACE/statistics/rx_errors 2>/dev/null || echo 0)
TX_ERR_2=IFACE/statistics/tx_errors 2>/dev/null || echo 0)
RX_DROP_2=IFACE/statistics/rx_dropped 2>/dev/null || echo 0)
TX_DROP_2=IFACE/statistics/tx_dropped 2>/dev/null || echo 0)
CPU=(awk ' { for(i=1;i<=NF;i++){ if(i=="CPU") ci=i
if(i=="%iowait") wi=i
}
if(ci && ii && $ci=="all" && $1!="Average:"){
v=100-$ii
if(!n || v<min) min=v
if(!n || v>max) max=v
if(wi && $wi>wmax) wmax=$wi
n++
}
}
END {
printf "CPU : %.1f%% ~ %.1f%% (I/O Wait Max %.1f%%)",min,max,wmax
}' "$TMP/cpu")
MEM=(awk ' { for(i=1;i<=NF;i++) if(i=="%memused") mi=i
if(mi && $mi ~ /^[0-9.]+$/ && $1!="Average:"){
v=$mi
if(!n || v<min) min=v
if(!n || v>max) max=v
n++
}
}
END {
printf "MEM : %.1f%% ~ %.1f%%",min,max
}' "$TMP/mem")
DISK=(awk ' { for(i=1;i<=NF;i++){ if(i=="Device") di=i
if($i=="%util") ui=i
}
if(di && ui && $ui ~ /^[0-9.]+$/ &&
$di !~ /^(loop|ram|sr)/) {
d=$di
v=$ui
if(!(d in dmin) || v<dmin[d]) dmin[d]=v
if(!(d in dmax) || v>dmax[d]) dmax[d]=v
}
}
END {
for(d in dmax){
if(!found || dmax[d]>best){
found=1
dev=d
best=dmax[d]
}
}
printf "DISK IO : %s %.1f%% ~ %.1f%%",dev,dmin[dev],dmax[dev]
}' "$TMP/disk")
FS=$(df -P -x tmpfs -x devtmpfs 2>/dev/null | awk '
NR>1 {
gsub("%","",$5)
if($5+0 > max){
max=$5
mount=$6
}
}
END {
printf "FS : Max %d%% (%s)",max,mount
}')
NET=IFACE" '
{
for(i=1;i<=NF;i++){
if(i=="rxkB/s") ri=i
if($i=="txkB/s") ti=i
}
if(fi && ri && ti && $fi==IFACE && $ri ~ /^[0-9.]+$/){
rx=$ri/1024
tx=$ti/1024
if(!n || rx<rxmin) rxmin=rx
if(!n || rx>rxmax) rxmax=rx
if(!n || tx<txmin) txmin=tx
if(!n || tx>txmax) txmax=tx
n++
}
}
END {
printf "NET %-6s: RX %.2f~%.2f MB/s / TX %.2f~%.2f MB/s",
IFACE,rxmin,rxmax,txmin,txmax
}' "$TMP/net")
PCPU=(awk ' { for(i=1;i<=NF;i++){ if(i=="PID") pi=i
if(i=="Command") ni=i
}
if(pi && ci && ni && $pi ~ /^[0-9]+$/ &&
$ci ~ /^[0-9.]+$/ && $1!="Average:"){
if($ci>max){
max=$ci
pid=$pi
cmd=$ni
}
}
}
END {
printf "%s(pid:%s) %.1f%%",cmd,pid,max
}' "$TMP/pcpu")
PMEM=(awk ' { for(i=1;i<=NF;i++){ if(i=="PID") pi=i
if(i=="Command") ni=i
}
if(pi && mi && ni && $pi ~ /^[0-9]+$/ &&
$mi ~ /^[0-9.]+$/ && $1!="Average:"){
if($mi>max){
max=$mi
pid=$pi
cmd=$ni
}
}
}
END {
printf "%s(pid:%s) %.1f%%",cmd,pid,max
}' "$TMP/pmem")
echo "===== 20분 리소스 점검 ====="
echo "MEM"
echo "DISK"
echo "$NET"
echo "NET ERR : RX Err $((RX_ERR_2-RX_ERR_1)) / Drop $((RX_DROP_2-RX_DROP_1)), TX Err $((TX_ERR_2-TX_ERR_1)) / Drop $((TX_DROP_2-TX_DROP_1))"
echo "PROC : CPU $PCPU / MEM $PMEM"
결과는 딱 이런 식으로 나옴.
===== 20분 리소스 점검 =====
CPU : 4.2% ~ 38.7% (I/O Wait Max 2.1%)
MEM : 61.3% ~ 63.8%
FS : Max 72% (/data)
DISK IO : sdb 0.2% ~ 31.4%
NET eth0: RX 0.03~8.52 MB/s / TX 0.01~3.17 MB/s
NET ERR : RX Err 0 / Drop 0, TX Err 0 / Drop 0
PROC : CPU oracle(pid:12345) 42.1% / MEM oracle(pid:12345) 31.8%
그리고 여러 대면 SSH 창마다 실행시켜 놓을 필요조차 없음. 서버마다:
nohup bash holiday_check.sh > /tmp/holiday_check.result 2>&1 &
걸어놓고 다른 서버로 넘어가면 됨. 4대 전부 5분 안에 걸어놓고 20분 뒤에
cat /tmp/holiday_check.result
만 회수하면 끝.
이 정도면 명절 점검 보고에는 진짜 충분함. CPU / MEM / Disk / Ethernet / 과점유 Process를 동일한 20분 구간에서 동시에 측정했다는 것도 오히려 따로따로 80분 재는 것보다 비교 기준이 맞아서 낫고.