#!/bin/bash
#When the CPU is more than fifty percent,Record the highest occupancy resources class
#More than sixty percent when memory, records the highest consumption parts
#date:2016-09-05
TERM=linux ###top設定自動執行任務時得指定終端
export TERM
pre_dir="/data/scripts/mem_leakage"
Process=`ps aux |grep tomcat |grep -v grep | awk '{print $2}'`java
#thread=`top -Hp 18641 |grep java |head -n 5 |awk '{print $1}'`linux
Date=`date +"%Y%m%d"`tomcat
detail_date=`date +"%Y%m%d%H%M"`bash
Date_detail=`date +"%Y-%m-%d %H%M%S"`服務器
log_dir="/data/log/ques_class"ui
logdir=$log_dir #日誌路徑
log=$logdir/log.log #日誌文件
is_font=1 #終端是否打印日誌: 1打印 0不打印
is_log=1 #是否記錄日誌: 1記錄 0不記錄線程
datef(){
date "+%Y-%m-%d %H:%M:%S"
}
print_log(){
if [[ $is_log -eq 1 ]];then
[[ -d $logdir ]] || mkdir -p $logdir
echo -e "[ $(datef) ] $1" >> $log
fi
if [[ $is_font -eq 1 ]];then
echo -e "[ $(datef) ] $1"
fi
}日誌
[ -d $log_dir ]|| mkdir -p $log_dirorm
[ -d $pre_dir ]|| mkdir -p $pre_dir進程
source /etc/profile
#判斷單個進程cpu是否超過50%
process_get () {
cpu_num=`cat /proc/cpuinfo |grep cores|wc -l`
for process_id in $Process
do
cpu_consume=`top -b -n 1 | grep $process_id | awk '{print $9}'|tail -1|cut -d"." -f1`
print_log "cpu消耗語句 top -b -n 2 | grep $process_id | awk '{print \$9}'|tail -1|cut -d"." -f1 \n值: $cpu_consume"
if [[ $cpu_consume -gt ${cpu_num}*50 ]]
then
print_log "進程ID:$process_id 服務目前異常"
need_id=$process_id
else
print_log "進程ID:$process_id 服務目前正常"
fi
done
}
#消耗CPU最高的類或者方法以下
ques_class () {
#need_id='12502'
if [[ -z $need_id ]]
then
return 0
fi
echo "need_id: $need_id"
#thread_id=`top -Hp $need_id |grep java |head -n 5 |awk '{print $1}'` ###取消耗cpu資源最高的前五線程
top -Hp $need_id -bn 1 |grep java |head -n 5 |awk '{print $1}' > /tmp/java.txt ###取消耗cpu資源最高的前五線程
while read ques_thread
do
ques_thread=$(echo "$ques_thread" |awk -F'm' '{print $NF}')
key=$(printf '%x\n' $ques_thread) ###十六進制轉換
#key=`echo "ibase=10;obase=16;$ques_thread"|bc` ###十六進制轉換
echo "線程ID:$ques_thread ,轉換後的十六進制: $key"
java_comm=`ps aux |grep $need_id|awk '{print $11}' |grep -v grep`
#exit
java_path=${java_comm%/*} ###獲取進程JDK路徑
echo "$java_path" > ${pre_dir}/jre.txt
jre_judge=$(grep 'jre/bin' ${pre_dir}/jre.txt |wc -l)
echo "$jre_judge"
if [[ $jre_judge == 1 ]];then
java_path=$(sed 's/jre\///' ${pre_dir}/jre.txt)
else
echo "$java_path 不變"
fi
ques_content=`$java_path/jstack $need_id |grep $key`
echo "${Date_detail} 有問題消耗cpu高的類和方法以下 $ques_content" >> $log_dir/${detail_date}cpu.log
print_log "${Date_detail} 有問題消耗cpu高的類和方法以下 $ques_content"
done < /tmp/java.txt
}
###獲取堆的使用分佈以及超過百分之八十五時,獲取內存消耗的詳細分佈
heap_analy () {
max_dump_mem_set=46
max_per_mem_set=40
mem_process=`top -b -n 1 |grep java |awk '{print $10,$1}' |sort -rn |head -n 1` ###獲取內存佔比最高的進程內存比
mem_value=`echo $mem_process|cut -d" " -f1|cut -d"." -f1` ###獲取內存比值
process_id=`echo $mem_process|cut -d" " -f2`
java_comm=`ps aux |grep $process_id|awk '{print $11}'|grep -v grep`
java_path=${java_comm%/*} ###獲取進程JDK路徑
echo "$java_path" > ${pre_dir}/jre.txt
jre_judge=$(grep 'jre/bin' ${pre_dir}/jre.txt |wc -l)
if [[ $jre_judge == 1 ]];then
java_path=$(sed 's/jre\///' ${pre_dir}/jre.txt)
else
echo "$java_path 不變"
fi
timer=`cat $pre_dir/timer` ###計時器,大於3時先中止,等待半個小時
first_time=`cat $pre_dir/first_time`
termination_time=`cat $pre_dir/termination_time`
max_py_mem=$(cat /proc/meminfo |grep MemTotal |awk '{print $2}')
max_py_mem=$(expr $max_py_mem / 1024 )
if [[ $mem_value -gt 85 ]] ;then
print_log "內存使用超過了$mem_value%,當前服務器最大內存:${max_py_mem}M"
$java_path/jmap -heap $process_id >> $log_dir/heap${Date}
#timer=$(($timer+1))
if [[ $timer -gt 3 ]]; then
if [[ $termination_time -eq 0 ]];then
pre_time=`date +"%s"`
echo "$pre_time" > $pre_dir/termination_time
else
pre_time=`date +"%s"`
interval_time=$(($pre_time-$termination_time))
if [[ $interval_time -gt 1800 ]];then
echo "0" > $pre_dir/termination_time
else
echo "停留時間沒到半小時,繼續等到"
fi
fi
else
if [[ $first_time -eq 0 ]]; then
first_time=`date +"%s"`
echo $first_time > $pre_dir/first_time
timer=$(($timer+1))
echo "$timer" > $pre_dir/timer
print_log "開始捕獲內存的線程狀態: $java_path/jmap -dump:format=b,file=$log_dir/${detail_date}_mem.dump $need_id"
$java_path/jmap -dump:format=b,file=$log_dir/${detail_date}_mem.dump $need_id
else
pre_time=`date +"%s"`
interval_time=`expr $pre_time - $first_time`
if [[ $interval_time -gt 1800 ]];then
echo "0" > $pre_dir/timer
echo "0" > $pre_dir/first_time
else
timer=$(($timer+1))
echo "$timer" > $pre_dir/timer
print_log "開始捕獲內存的線程狀態: $java_path/jmap -dump:format=b,file=$log_dir/${detail_date}_mem.dump" $need_id
$java_path/jmap -dump:format=b,file=$log_dir/${detail_date}_mem.dump $need_id
fi
fi
fi
elif [[ $mem_value -gt 60 ]];then
mem_info=$($java_path/jmap -heap $process_id |tee $log_dir/heap${Date}.log)
print_log "輸出內存概要分析:$mem_info"
#$java_path/jmap -heap $process_id >> $log_dir/heap${Date}.log
else
print_log "目前系統內存正常"
fi
print_log "結束內存捕獲."
}
process_get
ques_class
heap_analy
cd $log_dir find ./ -mmin +120 -exec rm -f {} \;