|
| 1 | +#!/usr/bin/env bash |
| 2 | + |
| 3 | +print_metric() { |
| 4 | + local label="$1" |
| 5 | + local raw_value="$2" |
| 6 | + local trimmed_value |
| 7 | + |
| 8 | + # Use read -rd '' to trim leading/trailing IFS whitespace (space, tab, newline) |
| 9 | + read -rd '' trimmed_value <<< "$raw_value" || : |
| 10 | + |
| 11 | + # Check if trimmed_value contains a newline character for formatting |
| 12 | + if [[ "$trimmed_value" == *$'\n'* ]]; then |
| 13 | + local indent=" " |
| 14 | + # Using a more robust way to handle potential leading/trailing newlines in raw_value for printf |
| 15 | + printf "%-35s :\n" "$label" |
| 16 | + printf "%s\n" "$indent${trimmed_value//$'\n'/$'\n'$indent}" # Indent and print the value on new lines |
| 17 | + else |
| 18 | + printf "%-35s : %s\n" "$label" "$trimmed_value" |
| 19 | + fi |
| 20 | +} |
| 21 | + |
| 22 | +cat_file() { |
| 23 | + cat "$1" 2>/dev/null || echo 'not found' |
| 24 | +} |
| 25 | + |
| 26 | +# Show cgroup memory usage |
| 27 | +print_metric "RAM memory" "$( (grep MemTotal /proc/meminfo | tr -s ' ' | cut -d ' ' -f 2) 2>/dev/null || echo 'not found')" |
| 28 | + |
| 29 | +if [ -f /sys/fs/cgroup/cgroup.controllers ]; then |
| 30 | + # cgroup v2 |
| 31 | + print_metric "cgroup v2 memory.peak" "$(cat_file /sys/fs/cgroup/memory.peak)" |
| 32 | + print_metric "cgroup v2 memory.max" "$(cat_file /sys/fs/cgroup/memory.max)" |
| 33 | + print_metric "cgroup v2 memory.high" "$(cat_file /sys/fs/cgroup/memory.high)" |
| 34 | + print_metric "cgroup v2 memory.current" "$(cat_file /sys/fs/cgroup/memory.current)" |
| 35 | + if [ -f /sys/fs/cgroup/memory.pressure ]; then |
| 36 | + print_metric "cgroup v2 memory.pressure" "$(cat_file /sys/fs/cgroup/memory.pressure)" |
| 37 | + fi |
| 38 | + if [ -f /sys/fs/cgroup/memory.events ]; then |
| 39 | + print_metric "cgroup v2 memory.events oom" "$( (grep -E '^oom\\s' /sys/fs/cgroup/memory.events | cut -d' ' -f2) 2>/dev/null || echo 'not found')" |
| 40 | + print_metric "cgroup v2 memory.events oom_kill" "$( (grep -E '^oom_kill\\s' /sys/fs/cgroup/memory.events | cut -d' ' -f2) 2>/dev/null || echo 'not found')" |
| 41 | + print_metric "cgroup v2 memory.events high" "$( (grep -E '^high\\s' /sys/fs/cgroup/memory.events | cut -d' ' -f2) 2>/dev/null || echo 'not found')" |
| 42 | + fi |
| 43 | + |
| 44 | + # CPU metrics |
| 45 | + print_metric "cgroup v2 cpu.max" "$(cat_file /sys/fs/cgroup/cpu.max)" |
| 46 | + print_metric "cgroup v2 cpu.nr_throttled" "$( (grep -E "^nr_throttled[[:space:]]+" /sys/fs/cgroup/cpu.stat | cut -d' ' -f2) 2>/dev/null || echo 'not found')" |
| 47 | + print_metric "cgroup v2 cpu.throttled_usec" "$( (grep -E "^throttled_usec[[:space:]]+" /sys/fs/cgroup/cpu.stat | cut -d' ' -f2) 2>/dev/null || echo 'not found')" |
| 48 | + print_metric "cgroup v2 cpu.usage_usec" "$( (grep -E "^usage_usec[[:space:]]+" /sys/fs/cgroup/cpu.stat | cut -d' ' -f2) 2>/dev/null || echo 'not found')" |
| 49 | + if [ -f /sys/fs/cgroup/cpu.pressure ]; then # cpu.pressure might not exist on older kernels/setups |
| 50 | + print_metric "cgroup v2 cpu.pressure" "$(cat_file /sys/fs/cgroup/cpu.pressure)" |
| 51 | + fi |
| 52 | + |
| 53 | +elif [ -d "/sys/fs/cgroup/memory" ]; then # Assuming if memory cgroup v1 exists, cpu might too |
| 54 | + # cgroup v1 |
| 55 | + # Note: In cgroup v1, memory stats are typically found under /sys/fs/cgroup/memory/ |
| 56 | + # The specific path might vary if inside a nested cgroup. |
| 57 | + # This script assumes it's running in a context where /sys/fs/cgroup/memory/ points to the relevant cgroup. |
| 58 | + print_metric "cgroup v1 memory.usage_in_bytes" "$(cat_file /sys/fs/cgroup/memory/memory.usage_in_bytes)" |
| 59 | + print_metric "cgroup v1 memory.limit_in_bytes" "$(cat_file /sys/fs/cgroup/memory/memory.limit_in_bytes)" |
| 60 | + print_metric "cgroup v1 memory.failcnt" "$(cat_file /sys/fs/cgroup/memory/memory.failcnt)" |
| 61 | + print_metric "cgroup v1 memory.max_usage_in_bytes" "$(cat_file /sys/fs/cgroup/memory/memory.max_usage_in_bytes)" |
| 62 | + |
| 63 | + # Throttling stats from /sys/fs/cgroup/cpu/cpu.stat |
| 64 | + if [ -f /sys/fs/cgroup/cpu/cpu.stat ]; then |
| 65 | + print_metric "cgroup v1 cpu.nr_throttled" "$( (grep -E "^nr_throttled[[:space:]]+" /sys/fs/cgroup/cpu/cpu.stat | cut -d' ' -f2) 2>/dev/null || echo 'not found')" |
| 66 | + print_metric "cgroup v1 cpu.throttled_time_ns" "$( (grep -E "^throttled_time[[:space:]]+" /sys/fs/cgroup/cpu/cpu.stat | cut -d' ' -f2) 2>/dev/null || echo 'not found')" |
| 67 | + else |
| 68 | + # Print not found for these specific metrics if cpu.stat is missing, to avoid ambiguity |
| 69 | + print_metric "cgroup v1 cpu.nr_throttled" "not found (cpu.stat)" |
| 70 | + print_metric "cgroup v1 cpu.throttled_time_ns" "not found (cpu.stat)" |
| 71 | + fi |
| 72 | + # CPU Quota settings from /sys/fs/cgroup/cpu/ |
| 73 | + print_metric "cgroup v1 cpu.cfs_period_us" "$(cat_file /sys/fs/cgroup/cpu/cpu.cfs_period_us)" |
| 74 | + print_metric "cgroup v1 cpu.cfs_quota_us" "$(cat_file /sys/fs/cgroup/cpu/cpu.cfs_quota_us)" |
| 75 | + # CPU usage from /sys/fs/cgroup/cpuacct/ (usually same hierarchy as cpu) |
| 76 | + print_metric "cgroup v1 cpuacct.usage_ns" "$(cat_file /sys/fs/cgroup/cpuacct/cpuacct.usage)" |
| 77 | + print_metric "cgroup v1 cpuacct.usage_user_ns" "$(cat_file /sys/fs/cgroup/cpuacct/cpuacct.usage_user)" |
| 78 | + print_metric "cgroup v1 cpuacct.usage_sys_ns" "$(cat_file /sys/fs/cgroup/cpuacct/cpuacct.usage_sys)" |
| 79 | + |
| 80 | +else |
| 81 | + printf "cgroup memory paths not found. Neither cgroup v2 controller file nor cgroup v1 memory directory detected.\n" |
| 82 | +fi |
| 83 | + |
0 commit comments