#!/bin/bash # Show RAM usage for containers # 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")" source $BASEPATH/.env NODE_PATH="$1" # 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 "$num" fi } # 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 } # Function to get RAM for a compose file by matching service names get_compose_ram() { local compose_file="$1" local total=0 # Get service names defined in this compose file services=$(cat "$compose_file" | yaml2json - 2>/dev/null | jq -r '.services | keys[]' 2>/dev/null) [ -z "$services" ] && echo "0" && return for service in $services; do # Find container by service label cid=$(docker ps -q --filter "label=com.docker.compose.service=$service" 2>/dev/null) [ -z "$cid" ] && continue mem_usage=$(docker stats --no-stream --format "{{.MemUsage}}" "$cid" 2>/dev/null | awk -F'/' '{print $1}') [ -z "$mem_usage" ] && continue mem_mib=$(to_mib "$mem_usage") total=$(echo "$total + $mem_mib" | bc) done echo "$total" } # Blacklist - skip infrastructure compose files blacklist=("drpc.yml" "drpc-free.yml" "drpc-home.yml" "base.yml" "rpc.yml" "monitoring.yml" "ftp.yml" "backup-http.yml") is_blacklisted() { local part="$1" for word in "${blacklist[@]}"; do if echo "$part" | grep -qE "$word"; then return 0 fi done return 1 } if [ -z "$NODE_PATH" ]; then # No argument: show RAM per node using COMPOSE_FILE from .env echo "RAM usage per node:" echo "========================================" IFS=':' read -ra parts <<< "$COMPOSE_FILE" declare -A node_ram total_mib=0 for part in "${parts[@]}"; do # Skip blacklisted files is_blacklisted "$part" && continue compose_file="${BASEPATH}/${part}" [ ! -f "$compose_file" ] && continue # Get node path (remove .yml extension) node_path="${part%.yml}" # Get RAM usage ram_mib=$(get_compose_ram "$compose_file") [ "$ram_mib" = "0" ] && continue node_ram["$node_path"]="$ram_mib" total_mib=$(echo "$total_mib + $ram_mib" | bc) done if [ ${#node_ram[@]} -eq 0 ]; then echo "No running nodes found" exit 0 fi # Sort by RAM usage and display for node_path in "${!node_ram[@]}"; do echo "${node_ram[$node_path]} $node_path" done | sort -rn | while read mib name; do printf "%-55s %s\n" "$name" "$(format_size $mib)" done echo "========================================" 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 - path maps directly to compose file COMPOSE_FILE_PATH="${BASEPATH}/${NODE_PATH}.yml" if [ ! -f "$COMPOSE_FILE_PATH" ]; then echo "Error: Compose file not found: $COMPOSE_FILE_PATH" exit 1 fi # Get service names from compose file services=$(cat "$COMPOSE_FILE_PATH" | yaml2json - 2>/dev/null | jq -r '.services | keys[]' 2>/dev/null) if [ -z "$services" ]; then echo "No services found in $NODE_PATH" exit 0 fi echo "RAM usage for $NODE_PATH:" echo "----------------------------------------" total_mib=0 for service in $services; do cid=$(docker ps -q --filter "label=com.docker.compose.service=$service" 2>/dev/null) [ -z "$cid" ] && continue mem_info=$(docker stats --no-stream --format "{{.MemUsage}}\t{{.MemPerc}}" "$cid" 2>/dev/null) mem_usage=$(echo "$mem_info" | awk -F'\t' '{print $1}' | awk -F'/' '{print $1}') mem_perc=$(echo "$mem_info" | awk -F'\t' '{print $2}') printf "%-40s %s\t%s\n" "$service" "$mem_usage" "$mem_perc" mem_mib=$(to_mib "$mem_usage") total_mib=$(echo "$total_mib + $mem_mib" | bc) done echo "----------------------------------------" echo "Total: $(format_size $total_mib)" fi