Created
May 11, 2017 17:43
-
-
Save weldpua2008/44e6884ac2bc6d0c129ddf03a9336656 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/bin/bash | |
| ################################################################################# | |
| # This tool can sample backtraces for memory allocations based on glibc's builtins | |
| # (malloc, calloc, realloc) that have not been freed (via free) in the sampling time period. | |
| ################################################################################# | |
| # Author Valeriy Soloviov <weldpua2008@gmail.com> | |
| ZABBIX_SCHED_PERIOD=600 | |
| PROFILE_FILENAME=/tlvmedia/code/www/sample-bt-leaks_current.svg | |
| PROFILE_FILENAME_HOURLY=/tlvmedia/code/www/sample-bt-leaks_hourly.svg | |
| PROFILE_FILENAME_DAYLY=/tlvmedia/code/www/sample-bt-leaks_dayly.svg | |
| PROFILE_FILENAME_WEEKLY=/tlvmedia/code/www/sample-bt-leaks_weekly.svg | |
| PROFILE_FILENAME_HTML=/tlvmedia/code/www/sample-bt-leaks.html | |
| PROFILE_FILENAME_HTML_BCK=/tlvmedia/code/www/sample-bt-leaks.html.back | |
| TMP_PROFILE_FILENAME=/tmp/sample-bt-leaks_current.svg | |
| TMP_PROFILE_FILENAME_RAW=/tmp/sample-bt-leaks_result.cbt | |
| TMP_FILES_BT=/tmp/sample-bt-leaks_result-fix1.bt | |
| TMP_FILES_CDB=/tmp/sample-bt-leaks.cbt | |
| IMG_HOSTNAME=$(hostname) | |
| MOVEBACK_HTML="no" | |
| ps -o pid= -C $(basename "$0")|grep -v $$|tr -d ' '| grep -E '[[:digit:]]' | |
| if [ $? -eq 0 ];then | |
| echo "Job is already running" | |
| exit 1 | |
| fi | |
| set -oe pipefail | |
| if [ ! -e "/tlvmedia/code/www/" ];then | |
| echo "/tlvmedia/code/www is not exist" | |
| exit 1 | |
| fi | |
| function on_exit() | |
| { | |
| local _exit_code=${1:-1} | |
| if [[ $_exit_code -eq 0 ]]; then | |
| echo "SUCCESSFULLY" | |
| # [ -e "$LOCK_ERROR" ] && $SUDO rm -f $LOCK_ERROR &> /dev/null | |
| else | |
| echo "FAILED" | |
| if [ "${MOVEBACK_HTML:-no}" = "yes" ];then | |
| echo "moved back $PROFILE_FILENAME_HTML_BCK -> $PROFILE_FILENAME_HTML" | |
| if [ -e "$PROFILE_FILENAME_HTML_BCK" ];then | |
| [ -e "$PROFILE_FILENAME_HTML" ] && $SUDO rm -f "$PROFILE_FILENAME_HTML" | |
| $SUDO mv "$PROFILE_FILENAME_HTML_BCK" "$PROFILE_FILENAME_HTML" || true | |
| fi | |
| fi | |
| fi | |
| exit $_exit_code | |
| } | |
| trap 'on_exit $?' EXIT HUP TERM INT | |
| [ "$(id -u)" != "0" ] && SUDO=$(which sudo 2> /dev/null||echo "sudo")|| SUDO="" | |
| # Zabbix checks | |
| if [[ "$1" = "debug" ]]; then | |
| set -x | |
| elif [ "$1" = "zabbix" ];then | |
| if [ -e "${PROFILE_FILENAME}" ];then | |
| if [ $(($(date +%s) - $(stat -c %Y "${PROFILE_FILENAME}" || echo 0) )) -lt ${ZABBIX_SCHED_PERIOD:-3600} ];then | |
| echo "No need updates" | |
| exit 0; | |
| fi | |
| fi | |
| fi | |
| # getting pid of nginx/openresty | |
| nginx_pid=$($SUDO ps -o pid,ppid= --no-headers --sort=-pcpu -C nginx|awk '$2!=1 {print $1;exit}') | |
| [[ "${nginx_pid:-}" = "" ]] && exit 1 | |
| # checking if somebody is running the strapxx | |
| $SUDO ps -Af|grep -E 'stap|lj-lua-stacks|lj-vm-states'|grep -v grep -q && sleep 5 || true | |
| OUTPUT=$( { $SUDO /usr/src/stapxx/stap++ /usr/src/stapxx/samples/sample-bt-leaks.sxx -x ${nginx_pid:-} --arg time=5 -D STP_NO_OVERLOAD -D MAXMAPENTRIES=10000 > ${TMP_FILES_BT} ;} 2>&1 ) | |
| n=$( wc -l < $TMP_FILES_BT ) | |
| if [ $n -lt 1 ];then | |
| sleep 6 | |
| OUTPUT=$( { $SUDO /usr/src/stapxx/stap++ /usr/src/stapxx/samples/sample-bt-leaks.sxx -x ${nginx_pid:-} --arg time=5 -D STP_NO_OVERLOAD -D MAXMAPENTRIES=10000 > ${TMP_FILES_BT} ;} 2>&1 ) | |
| n=$( wc -l < $TMP_FILES_BT ) | |
| if [ $n -lt 1 ];then | |
| echo "Error stap++: ${OUTPUT}" | |
| exit 1 | |
| fi | |
| fi | |
| $SUDO /usr/src/FlameGraph/stackcollapse-stap.pl $TMP_FILES_BT > $TMP_FILES_CDB | |
| $SUDO /usr/src/FlameGraph/flamegraph.pl --countname=bytes --title="Memory Leak Flame Graph for (${IMG_HOSTNAME}) at `date`" $TMP_PROFILE_FILENAME_RAW $TMP_FILES_CDB| $SUDO tee ${TMP_PROFILE_FILENAME} > /dev/null | |
| $SUDO /bin/cp $TMP_PROFILE_FILENAME ${PROFILE_FILENAME} | |
| function html_header(){ | |
| local htmlfile=${1:-} | |
| [ "$htmlfile" = "" ] && exit 1 | |
| cat <<EOF | $SUDO tee $htmlfile > /dev/null | |
| <!DOCTYPE html> | |
| <html> | |
| <head> | |
| <style> | |
| ul { | |
| list-style-type: none; | |
| margin: 0; | |
| padding: 0; | |
| overflow: hidden; | |
| background-color: #333; | |
| } | |
| li { | |
| float: left; | |
| } | |
| li a { | |
| display: block; | |
| color: white; | |
| text-align: center; | |
| padding: 14px 16px; | |
| text-decoration: none; | |
| } | |
| li a:hover:not(.active) { | |
| background-color: #111; | |
| } | |
| .active { | |
| background-color: #4CAF50; | |
| } | |
| </style> | |
| </head> | |
| <body> | |
| <ul> | |
| EOF | |
| } | |
| # adds a file to a html report | |
| function html_add_file(){ | |
| local htmlfile=${1:-} | |
| local filepath=${2:-current.svg} | |
| local class_active="${4:-no}" | |
| local li_class="" | |
| [ "$class_active" = "yes" ] && li_class='class="active"' | |
| [ "$htmlfile" = "" ] && exit 1 | |
| local descr="Current" | |
| local filename=$(basename ${filepath:-current.svg}) | |
| case $filename in | |
| hour*) descr="An hour ago";; | |
| day*) descr="An day ago";; | |
| week*) descr="An week ago";; | |
| month*) descr="An month ago";; | |
| esac | |
| local description=${3:-$descr} | |
| cat <<EOF | $SUDO tee -a $htmlfile > /dev/null | |
| <li><a $li_class onclick="document.getElementById('graph').data='/${filename}'">$description</a></li> | |
| EOF | |
| } | |
| # adds footer for html report | |
| function html_footer(){ | |
| local htmlfile=${1:-} | |
| local result_filename=$(basename "${PROFILE_FILENAME}") | |
| [ "$htmlfile" = "" ] && exit 1 | |
| cat <<EOF | $SUDO tee -a $htmlfile > /dev/null | |
| </ul> | |
| <object id="graph" data="/${result_filename:-current.svg}" style="width:100%"></object> | |
| </body> | |
| </html> | |
| EOF | |
| } | |
| # updates file and adds it to html report | |
| function replace_file(){ | |
| local src_file=${1:-} | |
| local dest_file=${2:-} | |
| local time_differense=${3:-3600} | |
| local html_file=${4:-$PROFILE_FILENAME_HTML} | |
| if [ -e "$src_file" ];then | |
| if [ $(($(date +%s) - $(stat -c %Y "$dest_file" || echo 0) )) -gt ${time_differense:-1} ];then | |
| $SUDO /bin/cp $src_file $dest_file | |
| fi | |
| fi | |
| if [ -e "$dest_file" ];then | |
| html_add_file "${html_file}" "${dest_file}" | |
| fi | |
| } | |
| ############################# execution | |
| # backup changes | |
| if [ -e "$PROFILE_FILENAME_HTML" ];then | |
| $SUDO mv "$PROFILE_FILENAME_HTML" "$PROFILE_FILENAME_HTML_BCK" || true | |
| MOVEBACK_HTML="yes" | |
| fi | |
| # adding html report header | |
| html_header "$PROFILE_FILENAME_HTML" | |
| # adding current(last) image | |
| html_add_file "$PROFILE_FILENAME_HTML" "${PROFILE_FILENAME}" "Current" "yes" | |
| # update hourly,dayly and weekly graphs | |
| replace_file "$TMP_PROFILE_FILENAME" "$PROFILE_FILENAME_HOURLY" 3600 "$PROFILE_FILENAME_HTML" | |
| replace_file "$TMP_PROFILE_FILENAME" "$PROFILE_FILENAME_DAYLY" 86400 "$PROFILE_FILENAME_HTML" | |
| replace_file "$TMP_PROFILE_FILENAME" "$PROFILE_FILENAME_WEEKLY" 604800 "$PROFILE_FILENAME_HTML" | |
| # adding html report footer | |
| html_footer "$PROFILE_FILENAME_HTML" | |
| exit 0 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment