代码文件 dump.sh
#!/usr/bin/env bash### use demo ###
# 1)upload dump.sh
# 2)dos2unix dump.sh;chmod +x dump.sh
# 3)usage:
# 1. /data/sh/java/dump.sh /tmp/dump /usr/local/java/jdk1.8.0_05 23554
# 2. /data/sh/java/dump.sh /tmp/dump /usr/local/java/jdk1.8.0_05 23554 -F### parameter description ###
# 1 ./tmp/dump is save dump file dir.
# 2 /usr/local/java/jdk1.8.0_05 is java_home.
# 3 23554 is java-pid.
# 4 -F force jvm dum, optional.declare SNAPSHOT_BASE_DIRECTORY=$1
declare JAVA_HOME=$2
declare PID=$3
declare JVM_FORCE_OPTS=$4# remove the last '/' char
JAVA_HOME=${JAVA_HOME/%\//}
SNAPSHOT_BASE_DIRECTORY=${SNAPSHOT_BASE_DIRECTORY/%\//}declare FULL_TIME_FORMAT="+%Y-%m-%d_%H_%M_%S_%N"
declare SHORT_TIME_FORMAT="+%H-%M-%S-%N"
declare TIMESTAMP=`date ""${FULL_TIME_FORMAT}"" `
declare RESULT_DIRECTORY=${SNAPSHOT_BASE_DIRECTORY}/${PID}/${TIMESTAMP}
declare RUN_LOG_PATH="${RESULT_DIRECTORY}/run.log"run_log(){declare log_msg="$(date ""${FULL_TIME_FORMAT}""): $1"echo ${log_msg}echo ${log_msg} >>${RUN_LOG_PATH}
}is_no_null(){if [ -z $1 ];thenreturn 0;elsereturn 1;fi
}is_valid_number(){is_no_null $1if [ $? -eq 0 ];thenreturn 0;fiif [ $1 -gt 0 ] 2>/dev/null ;thenreturn 1;elsereturn 0;fi
}echo_blank_line(){echo
}valid_param(){if [ ! -d ${RESULT_DIRECTORY} ]; thenmkdir -p ${RESULT_DIRECTORY}run_log "tip: Create RESULT_DIRECTORY=${RESULT_DIRECTORY}"firun_log "tip: RESULT_DIRECTORY=${RESULT_DIRECTORY}"is_no_null ${SNAPSHOT_BASE_DIRECTORY}if [ $? -eq 0 ];thenrun_log "Param 1 SNAPSHOT_BASE_DIRECTORY is no exist and exit ,such as /tmp/dump"exit 1;elserun_log "tip: SNAPSHOT_BASE_DIRECTORY=${SNAPSHOT_BASE_DIRECTORY}"fiif [ -d "${JAVA_HOME}" ];thenrun_log "tip: JAVA HOME: ${JAVA_HOME}"elserun_log "Param2 JAVA_HOME is no exist and exit ,such as /usr/local/java/jdk1.8.0_05"exit 2;fiis_valid_number ${PID}if [ $? -eq 0 ];thenrun_log "Param3 PID is invalid and exit"exit 3;fi
}
valid_param
run_log "RESULT_DIRECTORY=${RESULT_DIRECTORY}"machine_dump(){declare filename=$1;type $1 >/dev/null 2>&1 && {run_log "Start $1 $2 dump"declare timestamp=$(date ""${SHORT_TIME_FORMAT}"");run_log "Execute $1 $2 >> ${RESULT_DIRECTORY}/machine_${filename}_${timestamp}.dump"$1 $2 >> ${RESULT_DIRECTORY}/machine_${filename}_${timestamp}.dumprun_log "End $1 $2 dump"echo_blank_line}
}machine_dump_pipeline(){declare filename=$1;type $2 >/dev/null 2>&1 && {run_log "Start $2 $3 | $4 dump"declare timestamp=$(date ""${SHORT_TIME_FORMAT}"");run_log "Execute $2 $3 | $4 >> ${RESULT_DIRECTORY}/machine_${filename}_${timestamp}.dump"$2 $3 | $4 >> ${RESULT_DIRECTORY}/machine_${filename}_${timestamp}.dumprun_log "End $2 $3 | $4 dump"echo_blank_line}
}# 3 times interval 1s
declare machine_static_frequency="1 3"# machine real time statistics information
echo_blank_line
machine_dump_pipeline "top-50-process" top "-b" "head -n 50"
machine_dump free -glt
machine_dump vmstat "-t ${machine_static_frequency}"
machine_dump mpstat "-A ${machine_static_frequency}"
machine_dump iostat "${machine_static_frequency}"
machine_dump iotop "-o -b -n 3"
machine_dump netstat "-an"
machine_dump lsof "-p ${PID}"
# machine history statistics information
machine_dump sar -Aget_pid_user(){user_tip=`ps u -p $1 | tail -n 1 | awk '{print $1}'`is_valid_number ${user_tip}if [ $? -eq 0 ];thenecho ${user_tip}elseecho `cat /etc/passwd |grep x:${user_tip} | awk -F ':' '{print $1}'`fi
}PID_USER=`get_pid_user ${PID}`jvm_dump(){declare filename;if [ ! -z $3 ];thenfilename=$3elsefilename=$1firun_log "Start $1 $2 dump"declare timestamp=$(date ""${SHORT_TIME_FORMAT}"");run_log "su -l ${PID_USER} -s /bin/bash -c \"${JAVA_HOME}/bin/$1 $2 \" >> ${RESULT_DIRECTORY}/jvm_${filename}_${timestamp}.dump"su -l ${PID_USER} -s /bin/bash -c "${JAVA_HOME}/bin/$1 $2 " >> ${RESULT_DIRECTORY}/jvm_${filename}_${timestamp}.dumprun_log "End $1 $2 dump"echo_blank_line
}# 8 times interval 1s
declare jvm_static_frequency="1000 8"
# jvm real time statistics information
jvm_dump jinfo "${PID}"
jvm_dump jstat "-gcutil ${PID} ${jvm_static_frequency}" "jstat-gcutil"machine_dump_pipeline "top-100-high-thread" top "-H -b -n 1 -p ${PID}" "head -n 100"
chown ${PID_USER}:${PID_USER} ${RESULT_DIRECTORY}
# topH have must together with jstack
jvm_dump jstack "${JVM_FORCE_OPTS} ${PID}"# dump
jvm_head_dump(){run_log "Start jmap $1 dump"declare timestamp=$(date ""${SHORT_TIME_FORMAT}"");run_log "su -l ${PID_USER} -s /bin/bash -c \"${JAVA_HOME}/bin/jmap ${JVM_FORCE_OPTS} -dump:format=b,file=${RESULT_DIRECTORY}/jvm_jmap_${timestamp}.hprof $1\""su -l ${PID_USER} -s /bin/bash -c "${JAVA_HOME}/bin/jmap ${JVM_FORCE_OPTS} -dump:format=b,file=${RESULT_DIRECTORY}/jvm_jmap_${timestamp}.hprof $1" run_log "End jmap $1 dump"echo_blank_line
}
jvm_head_dump ${PID}# statistics all kinds of tcp status
cat ${RESULT_DIRECTORY}/machine_netstat*.dump | awk '/^tcp/ {++S[$NF]} END {for(a in S) print a, S[a]}' > ${RESULT_DIRECTORY}/machine_netstat_status_statistics.dump
调用示例:
./dump.sh /home/cmcc/temp/dump $JAVA_HOME PID