diff --git a/show-ram.sh b/show-ram.sh index c4b2b632..4f688fab 100755 --- a/show-ram.sh +++ b/show-ram.sh @@ -1,63 +1,94 @@ #!/bin/bash # Show RAM usage for containers -# Usage: ./show-ram.sh [compose-file-name] -# Without argument: shows all containers and total server RAM +# Usage: ./show-ram.sh [node-path] +# Without argument: shows RAM per node and total server RAM # With argument: shows containers for specific node BASEPATH="$(dirname "$0")" -COMPOSE_NAME="$1" +NODE_PATH="$1" -# Function to calculate and print total from container IDs -calc_total() { - local container_ids="$1" - local total_mib=$(docker stats --no-stream --format "{{.MemUsage}}" $container_ids | \ - awk -F'/' '{ - val=$1; - gsub(/[^0-9.]/,"",val); - if($1 ~ /GiB/) val*=1024; - sum+=val - } END {printf "%.0f", sum}') - - if [ "$total_mib" -ge 1024 ] 2>/dev/null; then - local total_gib=$(echo "scale=2; $total_mib / 1024" | bc) - echo "${total_gib} GiB" +# Function to convert memory string to MiB +to_mib() { + local val="$1" + local num=$(echo "$val" | sed 's/[^0-9.]//g') + if echo "$val" | grep -qi "GiB"; then + echo "$num * 1024" | bc + elif echo "$val" | grep -qi "MiB"; then + echo "$num" + elif echo "$val" | grep -qi "KiB"; then + echo "$num / 1024" | bc else - echo "${total_mib} MiB" + echo "$num" fi } -if [ -z "$COMPOSE_NAME" ]; then - # No argument: show all containers grouped by compose project - echo "RAM usage for all nodes:" +# Function to format MiB to human readable +format_size() { + local mib="$1" + if [ "${mib%.*}" -ge 1024 ] 2>/dev/null; then + echo "scale=2; $mib / 1024" | bc | xargs printf "%.2f GiB" + else + printf "%.0f MiB" "$mib" + fi +} + +if [ -z "$NODE_PATH" ]; then + # No argument: show RAM per node (compose project) + echo "RAM usage per node:" echo "========================================" - # Get all running containers - ALL_CONTAINERS=$(docker ps -q 2>/dev/null) + # Find all compose files that have running containers + declare -A node_ram - if [ -z "$ALL_CONTAINERS" ]; then + # Get all running containers with their compose project + while IFS= read -r line; do + container_id=$(echo "$line" | awk '{print $1}') + [ -z "$container_id" ] && continue + + # Get compose project label + project=$(docker inspect "$container_id" --format '{{index .Config.Labels "com.docker.compose.project"}}' 2>/dev/null) + [ -z "$project" ] && continue + + # Get memory usage + mem_usage=$(docker stats --no-stream --format "{{.MemUsage}}" "$container_id" 2>/dev/null | awk -F'/' '{print $1}') + [ -z "$mem_usage" ] && continue + + mem_mib=$(to_mib "$mem_usage") + + # Add to node total + if [ -z "${node_ram[$project]}" ]; then + node_ram[$project]="$mem_mib" + else + node_ram[$project]=$(echo "${node_ram[$project]} + $mem_mib" | bc) + fi + done < <(docker ps --format "{{.ID}}") + + if [ ${#node_ram[@]} -eq 0 ]; then echo "No running containers found" exit 0 fi - # Show stats for all containers, sorted by memory usage (descending) - docker stats --no-stream --format "table {{.Name}}\t{{.MemUsage}}\t{{.MemPerc}}" $ALL_CONTAINERS | \ - head -1 - docker stats --no-stream --format "{{.Name}}\t{{.MemUsage}}\t{{.MemPerc}}" $ALL_CONTAINERS | \ - sort -t$'\t' -k2 -h -r + # Sort by RAM usage and display + total_mib=0 + for project in "${!node_ram[@]}"; do + echo "${node_ram[$project]} $project" + total_mib=$(echo "$total_mib + ${node_ram[$project]}" | bc) + done | sort -rn | while read mib name; do + printf "%-50s %s\n" "$name" "$(format_size $mib)" + done echo "========================================" - - # Calculate total - echo -n "Total container RAM: " - calc_total "$ALL_CONTAINERS" + echo "Total container RAM: $(format_size $total_mib)" # Show server total RAM total_server_ram=$(free -h | awk '/^Mem:/ {print $2}') used_server_ram=$(free -h | awk '/^Mem:/ {print $3}') echo "Server RAM: ${used_server_ram} / ${total_server_ram}" else - # Specific node + # Specific node - extract compose name from path + # Handle both "ethereum-mainnet-geth-archive" and "ethereum/geth/ethereum-mainnet-geth-archive" + COMPOSE_NAME=$(basename "$NODE_PATH") COMPOSE_FILE="${BASEPATH}/${COMPOSE_NAME}.yml" if [ ! -f "$COMPOSE_FILE" ]; then @@ -80,6 +111,14 @@ else docker stats --no-stream --format "{{.Name}}\t{{.MemUsage}}\t{{.MemPerc}}" $CONTAINER_IDS echo "----------------------------------------" - echo -n "Total: " - calc_total "$CONTAINER_IDS" + + # Calculate total + total_mib=0 + for cid in $CONTAINER_IDS; do + mem_usage=$(docker stats --no-stream --format "{{.MemUsage}}" "$cid" 2>/dev/null | awk -F'/' '{print $1}') + mem_mib=$(to_mib "$mem_usage") + total_mib=$(echo "$total_mib + $mem_mib" | bc) + done + + echo "Total: $(format_size $total_mib)" fi