使用Perf工具生成CPU火焰图自动化脚本
Perf工具生成CPU火焰图
Perf工具抓取函数调用,flamechart工具用来画火焰图。
将该脚本在服务器上执行后自动出火焰图。
cpu_flamechart.sh install #安装perf工具和下载flamechart
cpu_flamechart.sh capture #抓perf.data和生成火焰图
#!/usr/bin/env bash
#===============================================================================
#
# FILE: cpu_flamechart.sh
#
# USAGE: ./cpu_flamechart.sh
#
# DESCRIPTION: To capture the specified process CPU flame for performance debugging
#
# OPTIONS: ---
# REQUIREMENTS: To capture the specified process CPU flame for performance debugging
# BUGS: ---
# NOTES: ---
# AUTHOR: 无知是恶
# ORGANIZATION: 无知是恶,博客园
# CREATED: 11/13/20 03:07:01
# REVISION: v1
#===============================================================================
set -o nounset # Treat unset variables as an error
#set env default vaule
export url_flame=${url_flame:-"https://github.com/brendangregg/FlameGraph/archive/master.zip"}
export path_flame=${path_flame:-"/var/tmp"}
export tool=${tool:-"perf"}
export process=${process:-"tcpproxy"}
#For perf command
export time=${time:-"10"}
export frequence=${frequence:-"99"}
export ifForce=${ifForce:-"yes"}
export svgFile=${svgFile:-"ksoftirqd.svg"}
function usage() {
echo -e "usage: $0 install|capture|clean"
echo -e " $0 install, install tool perf;"
echo -e " $0 capture, capture perf record and generate flame graph;"
echo -e " $0 clean, clean the perf data and flame svg file"
exit 2
}
function log(){
echo $(date +'[%F %T]') $@
}
function checkResult() {
RET=$1
message=$2
if [ $RET -ne 0 ];then
log ${message}
exit 2
fi
}
function checkUser() {
if [ $UID -ne 0 ];then
echo "Non root user, please run as root"
exit 2
fi
}
function addRepo(){
# add zypper repo
log "add zypper repo"
#说明:SUSE的官方源貌似不能安装,需要找其他的源
zypper addrepo --check --refresh --name "openSUSE:Factory l" http://download.opensuse.org/tumbleweed/repo/oss/ "openSUSE:Factory -repo" > /dev/null
log "list zypper repo"
zypper lr --url
}
function downloadFlame(){
log "download the FlameGrah from github"
/usr/bin/wget -q $url_flame -O $path_flame/FlameGraph.zip
cd $path_flame
log "unzip FlameGraph to path $path_flame"
unzip FlameGraph.zip > /dev/null
}
function checkToolsIfInstalled(){
log "check tool $tool installed"
which $tool > /dev/null 2>&1
checkResult $? "perf is not found on server"
}
function installPerf(){
log "install $tool"
zypper install -y -f $tool
zypper info $tool
checkResult $? "Error: install tool perf failed,exit the script"
checkToolsIfInstalled
}
function getThePerfData() {
cd /root
pid=$(ps -ef|grep $process |grep -v grep | awk '{print $2}')
log "The pid of process $process is $pid"
log "generate perf.data, please wait $time seconds"
log "/usr/bin/perf record -F $frequence -p ${pid} -g -- sleep $time"
/usr/bin/perf record -F $frequence -p ${pid} -g -- sleep $time
checkResult $? "Error: perf record failed"
log "generate CPU flamegraph now"
cd $path_flame
/usr/bin/perf script -i /root/perf.data | $path_flame/FlameGraph-master/stackcollapse-perf.pl --all | $path_flame/FlameGraph-master/flamegraph.pl > $path_flame/$svgFile
file_flame=$(ls -l $path_flame/ksoftirqd.svg | awk '{print $9}')
if [ $? -ne 0 ];then
log "Error: no flame $svgFile found"
exit 2
else
log "Please get flame chart file \"$svgFile\" from $file_flame"
exit 0
fi
}
function cleanData() {
log "clean data before capture by force=$ifForce"
if [ "$ifForce" == "yes" ];then
rm -f /root/perf.data
rm -f $path_flame/$svgFile
else
rm -i /root/perf.data
rm -i $path_flame/$svgFile
fi
}
#===================================================================
# Main Function
#
#===================================================================
checkUser
action=$1
case "$action" in
"install")
addRepo
downloadFlame
installPerf
;;
"capture")
getThePerfData
;;
"clean")
cleanData
;;
*)
echo -e "Error: non-support input!"
usage
;;
esac