Created
September 13, 2024 19:58
-
-
Save veyalla/88da70c5c4fbdfbad10b5907f41aa388 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 | |
| # Created by OpenAI o1! | |
| # Default number of top pods to display | |
| TOP_N=10 | |
| # Function to display usage information | |
| usage() { | |
| echo "Usage: $0 [-n top_n] [namespace1 namespace2 ...]" | |
| echo " -n top_n Number of top pods to display (default: 10)" | |
| echo "If no namespaces are provided, all namespaces will be included." | |
| exit 1 | |
| } | |
| # Parse command-line options | |
| while getopts ":n:" opt; do | |
| case $opt in | |
| n) | |
| if [[ "$OPTARG" =~ ^[0-9]+$ ]]; then | |
| TOP_N="$OPTARG" | |
| else | |
| echo "Error: -n requires a numeric argument." | |
| usage | |
| fi | |
| ;; | |
| \?) | |
| echo "Invalid option: -$OPTARG" | |
| usage | |
| ;; | |
| :) | |
| echo "Option -$OPTARG requires an argument." | |
| usage | |
| ;; | |
| esac | |
| done | |
| shift $((OPTIND -1)) | |
| # If no namespaces are provided, use all namespaces | |
| if [ "$#" -eq 0 ]; then | |
| echo "No namespaces provided. Including all namespaces." | |
| read -r -a namespace_list <<< $(kubectl get namespaces -o jsonpath='{.items[*].metadata.name}') | |
| else | |
| namespace_list=("$@") | |
| fi | |
| # Arrays to hold pod data and namespace totals | |
| pods_data=() | |
| ns_list=() | |
| ns_pod_counts=() | |
| ns_cpu_totals=() | |
| ns_mem_totals=() | |
| # Loop over all namespaces and collect pod data | |
| for namespace in "${namespace_list[@]}"; do | |
| # Get CPU and Memory usage for all pods in this namespace | |
| pod_usage=$(kubectl top pod -n "$namespace" --no-headers 2>/dev/null) | |
| if [ $? -ne 0 ] || [ -z "$pod_usage" ]; then | |
| continue | |
| fi | |
| # Initialize totals for this namespace | |
| ns_list+=("$namespace") | |
| ns_pod_counts+=(0) | |
| ns_cpu_totals+=(0) | |
| ns_mem_totals+=(0) | |
| ns_index=$((${#ns_list[@]} - 1)) | |
| while read -r name cpu mem; do | |
| # Append the pod data with namespace to pods_data | |
| pods_data+=("$name|$cpu|$mem|$namespace") | |
| cpu_val=${cpu%m} # Remove 'm' | |
| mem_val=${mem%Mi} # Remove 'Mi' | |
| # Handle possible units like "Gi" in memory | |
| if [[ $mem == *Gi ]]; then | |
| mem_val_gi=${mem%Gi} | |
| mem_val=$(echo "$mem_val_gi * 1024" | bc) | |
| fi | |
| # Update counts and totals | |
| ns_pod_counts[$ns_index]=$((ns_pod_counts[$ns_index] + 1)) | |
| ns_cpu_totals[$ns_index]=$((ns_cpu_totals[$ns_index] + ${cpu_val:-0})) | |
| ns_mem_totals[$ns_index]=$((ns_mem_totals[$ns_index] + ${mem_val:-0})) | |
| done <<< "$pod_usage" | |
| done | |
| # Check if any pod data was collected | |
| if [ ${#pods_data[@]} -eq 0 ]; then | |
| echo "No pod data collected from the specified namespaces." | |
| exit 1 | |
| fi | |
| # Determine the maximum width of each column for alignment | |
| max_name_len=8 # Minimum width for "POD NAME" | |
| max_cpu_len=5 # Minimum width for "CPU" | |
| max_mem_len=9 # Minimum width for "MEMORY" | |
| max_ns_len=9 # Minimum width for "NAMESPACE" | |
| # Calculate maximum lengths based on pod data | |
| for entry in "${pods_data[@]}"; do | |
| IFS='|' read -r name cpu mem ns <<< "$entry" | |
| [ ${#name} -gt $max_name_len ] && max_name_len=${#name} | |
| [ ${#cpu} -gt $max_cpu_len ] && max_cpu_len=${#cpu} | |
| [ ${#mem} -gt $max_mem_len ] && max_mem_len=${#mem} | |
| [ ${#ns} -gt $max_ns_len ] && max_ns_len=${#ns} | |
| done | |
| # Add padding | |
| padding=2 | |
| max_name_len=$((max_name_len + padding)) | |
| max_cpu_len=$((max_cpu_len + padding)) | |
| max_mem_len=$((max_mem_len + padding)) | |
| max_ns_len=$((max_ns_len + padding)) | |
| # Set header names | |
| ns_header="NAMESPACE" | |
| pods_header="Pods" | |
| cpu_header="CPU(m)" | |
| mem_header="Memory(Mi)" | |
| # Collect namespace totals into an array of strings for sorting | |
| ns_totals=() | |
| for i in "${!ns_list[@]}"; do | |
| ns_totals+=("${ns_list[$i]}|${ns_pod_counts[$i]}|${ns_cpu_totals[$i]}|${ns_mem_totals[$i]}") | |
| done | |
| # Sort namespaces by Memory Used in descending order | |
| sorted_ns_totals=($(printf "%s\n" "${ns_totals[@]}" | sort -t"|" -k4 -nr)) | |
| # Determine maximum lengths for the Resource Usage per Namespace section | |
| max_ns_name_len=${#ns_header} | |
| max_ns_pods_len=${#pods_header} | |
| max_ns_cpu_len=${#cpu_header} | |
| max_ns_mem_len=${#mem_header} | |
| for entry in "${sorted_ns_totals[@]}"; do | |
| IFS='|' read -r ns pods cpu mem <<< "$entry" | |
| [ ${#ns} -gt $max_ns_name_len ] && max_ns_name_len=${#ns} | |
| [ ${#pods} -gt $max_ns_pods_len ] && max_ns_pods_len=${#pods} | |
| [ ${#cpu} -gt $max_ns_cpu_len ] && max_ns_cpu_len=${#cpu} | |
| [ ${#mem} -gt $max_ns_mem_len ] && max_ns_mem_len=${#mem} | |
| done | |
| # Add padding | |
| max_ns_name_len=$((max_ns_name_len + padding)) | |
| max_ns_pods_len=$((max_ns_pods_len + padding)) | |
| max_ns_cpu_len=$((max_ns_cpu_len + padding)) | |
| max_ns_mem_len=$((max_ns_mem_len + padding)) | |
| # Display the list of namespaces included | |
| echo "Namespaces included:" | |
| for ns in "${ns_list[@]}"; do | |
| echo " - $ns" | |
| done | |
| echo | |
| # Display resource usage per namespace, sorted by memory used | |
| echo "Resource Usage per Namespace (sorted by Memory Used):" | |
| printf "%-${max_ns_name_len}s %-${max_ns_pods_len}s %-${max_ns_cpu_len}s %-${max_ns_mem_len}s\n" "$ns_header" "$pods_header" "$cpu_header" "$mem_header" | |
| separator_len=$((max_ns_name_len + max_ns_pods_len + max_ns_cpu_len + max_ns_mem_len + 3)) | |
| printf "%0.s-" $(seq 1 $separator_len) | |
| echo | |
| total_cpu=0 | |
| total_mem=0 | |
| for entry in "${sorted_ns_totals[@]}"; do | |
| IFS='|' read -r ns pods cpu mem <<< "$entry" | |
| printf "%-${max_ns_name_len}s %-${max_ns_pods_len}s %-${max_ns_cpu_len}s %-${max_ns_mem_len}s\n" "$ns" "$pods" "$cpu" "$mem" | |
| total_cpu=$((total_cpu + cpu)) | |
| total_mem=$((total_mem + mem)) | |
| done | |
| echo | |
| # Function to sort and get top N pods by CPU usage | |
| get_top_cpu_pods() { | |
| printf "%s\n" "${pods_data[@]}" | sort -t"|" -k2 -hr | head -"$TOP_N" | |
| } | |
| # Function to sort and get top N pods by Memory usage | |
| get_top_mem_pods() { | |
| printf "%s\n" "${pods_data[@]}" | sort -t"|" -k3 -hr | head -"$TOP_N" | |
| } | |
| # Get top N CPU and Memory pods | |
| top_cpu_pods=($(get_top_cpu_pods)) | |
| top_mem_pods=($(get_top_mem_pods)) | |
| # Prepare data for top CPU and Memory pods display | |
| top_cpu_pods_display=("${top_cpu_pods[@]}") | |
| top_mem_pods_display=("${top_mem_pods[@]}") | |
| # Function to print top CPU usage pods | |
| print_top_cpu() { | |
| echo "Top ${TOP_N} CPU Usage Pods in Specified Namespaces:" | |
| printf "%-${max_name_len}s %-${max_cpu_len}s %-${max_mem_len}s %-${max_ns_len}s\n" "POD NAME" "CPU" "MEMORY" "NAMESPACE" | |
| printf "%0.s-" $(seq 1 $((max_name_len + max_cpu_len + max_mem_len + max_ns_len + 3))) | |
| echo | |
| printf "%s\n" "${top_cpu_pods_display[@]}" | awk -F"|" \ | |
| -v name_len="$max_name_len" -v cpu_len="$max_cpu_len" -v mem_len="$max_mem_len" -v ns_len="$max_ns_len" \ | |
| '{printf "%-*s %-*s %-*s %-*s\n", name_len, $1, cpu_len, $2, mem_len, $3, ns_len, $4}' | |
| } | |
| # Function to print top Memory usage pods | |
| print_top_mem() { | |
| echo "Top ${TOP_N} Memory Usage Pods in Specified Namespaces:" | |
| printf "%-${max_name_len}s %-${max_cpu_len}s %-${max_mem_len}s %-${max_ns_len}s\n" "POD NAME" "CPU" "MEMORY" "NAMESPACE" | |
| printf "%0.s-" $(seq 1 $((max_name_len + max_cpu_len + max_mem_len + max_ns_len + 3))) | |
| echo | |
| printf "%s\n" "${top_mem_pods_display[@]}" | awk -F"|" \ | |
| -v name_len="$max_name_len" -v cpu_len="$max_cpu_len" -v mem_len="$max_mem_len" -v ns_len="$max_ns_len" \ | |
| '{printf "%-*s %-*s %-*s %-*s\n", name_len, $1, cpu_len, $2, mem_len, $3, ns_len, $4}' | |
| } | |
| # Print top CPU usage pods | |
| print_top_cpu | |
| echo | |
| # Display total CPU and Memory usage | |
| printf "Total CPU Usage : %dm\n" "$total_cpu" | |
| printf "Total Memory Usage: %dMi\n" "$total_mem" | |
| echo | |
| # Print top Memory usage pods | |
| print_top_mem | |
| echo | |
| # Display total CPU and Memory usage again | |
| printf "Total CPU Usage : %dm\n" "$total_cpu" | |
| printf "Total Memory Usage: %dMi\n" "$total_mem" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment