Skip to content

Commit

Permalink
WIP
Browse files Browse the repository at this point in the history
  • Loading branch information
oldratlee committed Sep 1, 2023
1 parent 30cbe74 commit bf548ba
Showing 1 changed file with 46 additions and 42 deletions.
88 changes: 46 additions & 42 deletions bin/show-busy-java-threads
Original file line number Diff line number Diff line change
Expand Up @@ -53,59 +53,63 @@ readonly ec=$'\033' # escape char
readonly eend=$'\033[0m' # escape end
readonly nl=$'\n' # new line

colorEcho() {
colorPrint() {
local color=$1
shift

# if stdout is console, turn on color output.
[ -t 1 ] && echo "${ec}[1;${color}m$*$eend" || echo "$@"
if [ -t 1 ]; then
printf "\033[1;${color}m%s\033[0m\n" "$*"
else
printf '%s\n' "$*"
fi
}

colorPrint() {
colorOutput() {
local color=$1
shift

colorEcho "$color" "$@"
[[ -n "$append_file" && -w "$append_file" ]] && echo "$@" >>"$append_file"
[[ -n "$store_dir" && -w "$store_dir" ]] && echo "$@" >>"${store_file_prefix}$PROG"
colorPrint "$color" "$@"
[[ -n "$append_file" && -w "$append_file" ]] && printf '%s\n' "$*" >>"$append_file"
[[ -n "$store_dir" && -w "$store_dir" ]] && printf '%s\n' "$*" >>"${store_file_prefix}$PROG"
}

# shellcheck disable=SC2120
normalPrint() {
echo "$@"
[[ -n "$append_file" && -w "$append_file" ]] && echo "$@" >>"$append_file"
[[ -n "$store_dir" && -w "$store_dir" ]] && echo "$@" >>"${store_file_prefix}$PROG"
normalOutput() {
printf '%s\n' "$*"
[[ -n "$append_file" && -w "$append_file" ]] && printf '%s\n' "$*" >>"$append_file"
[[ -n "$store_dir" && -w "$store_dir" ]] && printf '%s\n' "$*" >>"${store_file_prefix}$PROG"
}

redPrint() {
colorPrint 31 "$@"
redOutput() {
colorOutput 31 "$@"
}

greenPrint() {
colorPrint 32 "$@"
greenOutput() {
colorOutput 32 "$@"
}

yellowPrint() {
colorPrint 33 "$@"
yellowOutput() {
colorOutput 33 "$@"
}

bluePrint() {
colorPrint 36 "$@"
blueOutput() {
colorOutput 36 "$@"
}

die() {
redPrint "Error: $*" 1>&2
redOutput "Error: $*" 1>&2
exit 1
}

logAndRun() {
echo "$@"
printf '%s\n' "$*"
echo
"$@"
}

logAndCat() {
echo "$@"
printf '%s\n' "$*"
echo
cat
}
Expand Down Expand Up @@ -147,7 +151,7 @@ usage() {
# shellcheck disable=SC2015
[ "$exit_code" != 0 ] && local -r out=/dev/stderr || local -r out=/dev/stdout

(($# > 0)) && colorEcho 31 "$*$nl" >$out
(($# > 0)) && colorPrint 31 "$*$nl" >$out

cat >$out <<EOF
Usage: ${PROG} [OPTION]... [delay [count]]
Expand Down Expand Up @@ -202,7 +206,7 @@ EOF
}

progVersion() {
echo "$PROG $PROG_VERSION"
printf '%s\n' "$PROG $PROG_VERSION"
exit
}

Expand Down Expand Up @@ -386,9 +390,9 @@ cleanupWhenExit() {
trap cleanupWhenExit EXIT

headInfo() {
colorEcho "0;34;42" ================================================================================
echo "$(date "+%Y-%m-%d %H:%M:%S.%N") [$((update_round_num + 1))/$update_count]: $(printCallingCommandLine)"
colorEcho "0;34;42" ================================================================================
colorPrint "0;34;42" ================================================================================
printf '%s\n' "$(date "+%Y-%m-%d %H:%M:%S.%N") [$((update_round_num + 1))/$update_count]: $(printCallingCommandLine)"
colorPrint "0;34;42" ================================================================================
echo
}

Expand Down Expand Up @@ -434,13 +438,13 @@ findBusyJavaThreadsByPs() {
[ -n "$ps_out" ] || __die_when_no_java_process_found

if [ -n "$store_dir" ]; then
echo "$ps_out" | logAndCat "${ps_cmd_line[*]} | sort -k3,3nr" >"${store_file_prefix}$((update_round_num + 1))_ps"
printf '%s\n' "$ps_out" | logAndCat "${ps_cmd_line[*]} | sort -k3,3nr" >"${store_file_prefix}$((update_round_num + 1))_ps"
fi

if ((count > 0)); then
echo "$ps_out" | head -n "${count}"
printf '%s\n' "$ps_out" | head -n "${count}"
else
echo "$ps_out"
printf '%s\n' "$ps_out"
fi
}

Expand Down Expand Up @@ -473,13 +477,13 @@ __top_threadId_cpu() {
local top_out
top_out=$(HOME="$tmp_store_dir" "${top_cmd_line[@]}")
if [ -n "$store_dir" ]; then
echo "$top_out" | logAndCat "${top_cmd_line[@]}" >"${store_file_prefix}$((update_round_num + 1))_top"
printf '%s\n' "$top_out" | logAndCat "${top_cmd_line[@]}" >"${store_file_prefix}$((update_round_num + 1))_top"
fi

# DO NOT combine var result_threads_top_info declaration and assignment in ONE line!
local result_threads_top_info
result_threads_top_info=$(
echo "$top_out" | awk '{
printf '%s\n' "$top_out" | awk '{
# from text line to empty line, increase block index
if (previousLine && !$0) blockIndex++
# only print 4th text block(blockIndex == 3), aka. process info of second top update
Expand All @@ -490,7 +494,7 @@ __top_threadId_cpu() {
)
[ -n "$result_threads_top_info" ] || __die_when_no_java_process_found

echo "$result_threads_top_info" | sort -k2,2nr
printf '%s\n' "$result_threads_top_info" | sort -k2,2nr
}

__complete_pid_user_by_ps() {
Expand All @@ -501,21 +505,21 @@ __complete_pid_user_by_ps() {
local ps_out
ps_out="$("${ps_cmd_line[@]}")"
if [ -n "$store_dir" ]; then
echo "$ps_out" | logAndCat "${ps_cmd_line[@]}" >"${store_file_prefix}$((update_round_num + 1))_ps"
printf '%s\n' "$ps_out" | logAndCat "${ps_cmd_line[@]}" >"${store_file_prefix}$((update_round_num + 1))_ps"
fi

local idx=0 threadId pcpu output_fields
while read -r threadId pcpu; do
((count <= 0 || idx < count)) || break

# output field: pid, threadId, pcpu, user
output_fields="$(echo "$ps_out" |
output_fields="$(printf '%s\n' "$ps_out" |
awk -v "threadId=$threadId" -v "pcpu=$pcpu" '$2==threadId {
print $1, threadId, pcpu, $3; exit
}')"
if [ -n "$output_fields" ]; then
((idx++))
echo "$output_fields"
printf '%s\n' "$output_fields"
fi
done
}
Expand Down Expand Up @@ -543,20 +547,20 @@ printStackOfThreads() {
logAndRun sudo -u "${user}" "${jstack_cmd_line[@]}" >"${jstackFile}"
else
# current user is not root user, so can not run with sudo; print error message and rerun suggestion
redPrint "[$idx] Fail to jstack busy(${pcpu}%) thread(${threadId}/${threadId0x}) stack of java process(${pid}) under user(${user})."
redPrint "User of java process($user) is not current user($USER), need sudo to rerun:"
yellowPrint " sudo $(printCallingCommandLine)"
normalPrint
redOutput "[$idx] Fail to jstack busy(${pcpu}%) thread(${threadId}/${threadId0x}) stack of java process(${pid}) under user(${user})."
redOutput "User of java process($user) is not current user($USER), need sudo to rerun:"
yellowOutput " sudo $(printCallingCommandLine)"
normalOutput
continue
fi || {
redPrint "[$idx] Fail to jstack busy(${pcpu}%) thread(${threadId}/${threadId0x}) stack of java process(${pid}) under user(${user})."
normalPrint
redOutput "[$idx] Fail to jstack busy(${pcpu}%) thread(${threadId}/${threadId0x}) stack of java process(${pid}) under user(${user})."
normalOutput
rm "${jstackFile}" &>/dev/null
continue
}
}

bluePrint "[$idx] Busy(${pcpu}%) thread(${threadId}/${threadId0x}) stack of java process(${pid}) under user(${user}):"
blueOutput "[$idx] Busy(${pcpu}%) thread(${threadId}/${threadId0x}) stack of java process(${pid}) under user(${user}):"

if [ -n "$mix_native_frames" ]; then
local sed_script="/--------------- $threadId ---------------/,/^---------------/ {
Expand Down

0 comments on commit bf548ba

Please sign in to comment.