Skip to content

Instantly share code, notes, and snippets.

@jazzl0ver
Created April 21, 2025 15:47
Show Gist options
  • Save jazzl0ver/708967ee8580fcaf50ca39ce58aee20a to your computer and use it in GitHub Desktop.
Save jazzl0ver/708967ee8580fcaf50ca39ce58aee20a to your computer and use it in GitHub Desktop.
Opensearch/Elasticsearch CPU load per node ascii chart
#!/bin/bash
ENDPOINTS=(
"https://wi-node-1:9200"
"https://wi-node-2:9200"
"https://wi-node-3:9200"
)
INTERVAL=1
MIN_PANEL_HEIGHT=10
LOG_FILE="/tmp/opensearch_cpu_log.txt"
username=admin
read -s -p "Password: " password
echo
AUTH="-u $username:$password"
declare -A cpu_data
declare -A cpu_history
declare -a all_nodes
declare -A scroll_offset
curl_elapsed_time=0
get_terminal_size() {
TERMINAL_HEIGHT=$(tput lines)
TERMINAL_WIDTH=$(tput cols)
CHART_HEIGHT=$MIN_PANEL_HEIGHT
CHART_WIDTH=$((TERMINAL_WIDTH - 10))
MAX_HISTORY=$(( 2*CHART_WIDTH ))
}
trap ctrl_c INT
ctrl_c() {
tput cnorm
echo -e "\n[INFO] Interrupted..."
exit 0
}
fetch_cpu_usage() {
local json
random_endpoint=$(echo "${ENDPOINTS[@]}" | tr ' ' '\n' | shuf -n 1)
json=$(curl -ks $AUTH "$random_endpoint/_nodes/stats/os")
echo "$json" | jq -r '.nodes | to_entries[] | "\(.value.name) \(.value.os.cpu.percent)"'
}
update_data() {
local nodes=()
while IFS=' ' read -r node usage; do
usage=${usage:-0}
cpu_data["$node"]="$usage"
nodes+=("$node")
# Update history
local old="${cpu_history[$node]}"
cpu_history[$node]="$old $usage"
# Limit history
local words
words=$(echo "${cpu_history[$node]}" | wc -w)
if (( words > MAX_HISTORY )); then
cpu_history[$node]=$(echo "${cpu_history[$node]}" | awk -v max=$MAX_HISTORY '{
start = (NF > max) ? NF - max + 1 : 1;
for (i=start; i<=NF; i++) printf $i " ";
print ""
}') #'
fi
# Update scrolling offset, in case history is longer than the panel
history_length=$(echo "${cpu_history[$node]}" | wc -w)
if (( history_length > CHART_WIDTH )); then
scroll_offset[$node]=$((scroll_offset[$node] + 1))
else
scroll_offset[$node]=0
fi
# Log
# echo "$(date +'%Y-%m-%d %H:%M:%S') $node CPU: $usage%; words: $words; length: $history_length" >> "$LOG_FILE"
# echo "$(date +'%Y-%m-%d %H:%M:%S') $node ${cpu_history[$node]}" >> "$LOG_FILE.hist"
done < <(fetch_cpu_usage)
# Sorting nodes alphabetically
all_nodes=($(printf "%s\n" "${nodes[@]}" | sort))
}
simple_print() {
if (( scaled > row )); then
if (( val > 80 )); then
tput setaf 1; printf "█"; tput sgr0
elif (( val < 10 )); then
printf "▄"
else
printf "█"
fi
elif (( row == 0 && val > 0 && val < 10 )); then
printf "▄"
else
printf " "
fi
}
# Draw chart using history
draw_chart() {
local node="$1"
local history="${cpu_history[$node]}"
local -a values=($history)
local total=${#values[@]}
local offset=${scroll_offset[$node]:-0}
if (( offset + CHART_WIDTH > total )); then
offset=$(( total > CHART_WIDTH ? total - CHART_WIDTH : 0 ))
scroll_offset[$node]=$offset
fi
printf "\nNode: %s\n" "$node (${cpu_data[$node]}%)"
for ((row=CHART_HEIGHT; row>=0; row--)); do
level=$((row * 100 / CHART_HEIGHT))
printf "%3d │" "$level"
local count=0
local val
for ((col=0; col<CHART_WIDTH; col++)); do
idx=$((offset + col))
val=${values[$idx]:-0}
scaled=$(( val * CHART_HEIGHT / 100 ))
simple_print
done
echo
done
printf " └"
printf "─%.0s" $(seq 1 $CHART_WIDTH)
echo
}
get_terminal_size
tput clear
tput civis
# Main loop
while true; do
tput cup 0 0
update_data
for node in "${all_nodes[@]}"; do
draw_chart "$node"
done
sleep "$INTERVAL"
done
tput cnorm
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment