CPU脚本
#!/usr/bin/env bash
T=${1:-5}
# 计算当前使用 (m)
get_usage_m() {
if [ -f /sys/fs/cgroup/cpu.stat ]; then
u1=$(awk '/^usage_usec/{print $2}' /sys/fs/cgroup/cpu.stat)
sleep "$T"
u2=$(awk '/^usage_usec/{print $2}' /sys/fs/cgroup/cpu.stat)
du=$((u2-u1))
awk -v du="$du" -v t="$T" 'BEGIN{printf "%.0f", du/(t*1000)}'
else
u1=$(cat /sys/fs/cgroup/cpu/cpuacct.usage)
sleep "$T"
u2=$(cat /sys/fs/cgroup/cpu/cpuacct.usage)
du=$((u2-u1))
awk -v du="$du" -v t="$T" 'BEGIN{printf "%.0f", du/(t*1000000)}'
fi
}
# 读取 limit (m)
get_limit_m() {
if [ -f /sys/fs/cgroup/cpu.max ]; then
read q p < /sys/fs/cgroup/cpu.max
if [ "$q" = "max" ]; then echo 0; else awk -v q="$q" -v p="$p" 'BEGIN{printf "%.0f", 1000*q/p}'; fi
elif [ -f /sys/fs/cgroup/cpu/cpu.cfs_quota_us ]; then
q=$(cat /sys/fs/cgroup/cpu/cpu.cfs_quota_us)
p=$(cat /sys/fs/cgroup/cpu/cpu.cfs_period_us)
if [ "$q" -lt 0 ]; then echo 0; else awk -v q="$q" -v p="$p" 'BEGIN{printf "%.0f", 1000*q/p}'; fi
else
echo 0
fi
}
usage_m=$(get_usage_m)
limit_m=$(get_limit_m)
if [ "$limit_m" -gt 0 ]; then
pct=$(awk -v u="$usage_m" -v l="$limit_m" 'BEGIN{printf "%.1f", (u/l)*100}')
echo "CPU: ${usage_m}m / limit ${limit_m}m (${pct}%) over ${T}s"
else
echo "CPU: ${usage_m}m (no CPU limit) over ${T}s"
fi
内存脚本
#!/usr/bin/env bash
set -euo pipefail
to_mib() { awk -v b="$1" 'BEGIN{printf "%.1f", b/1024/1024}'; }
# 主机总内存(整数,字节)
HOST_MEM_KB=$(awk '/^MemTotal:/ {print $2}' /proc/meminfo 2>/dev/null || echo 0)
HOST_MEM_BYTES=$(( HOST_MEM_KB * 1024 ))
# cgroup v2 ?
if [ -f /sys/fs/cgroup/cgroup.controllers ]; then
USAGE=$(cat /sys/fs/cgroup/memory.current)
INACTIVE=$(awk '/^inactive_file /{print $2}' /sys/fs/cgroup/memory.stat 2>/dev/null || echo 0)
RAW=$(cat /sys/fs/cgroup/memory.max)
if [ "$RAW" = "max" ]; then
MEM_LIMIT=0
NO_HARD_LIMIT=1
else
MEM_LIMIT=$RAW
NO_HARD_LIMIT=0
fi
else
# cgroup v1
USAGE=$(cat /sys/fs/cgroup/memory/memory.usage_in_bytes)
INACTIVE=$(awk '/^total_inactive_file|^inactive_file/ {v=$2} END{print (v=="")?0:v}' /sys/fs/cgroup/memory/memory.stat 2>/dev/null || echo 0)
MEM_LIMIT=$(cat /sys/fs/cgroup/memory/memory.limit_in_bytes)
NO_HARD_LIMIT=0
# 未设限常见现象:limit≈主机内存 或 64位巨大哨兵值
if [ "$HOST_MEM_BYTES" -gt 0 ]; then
diff=$(( MEM_LIMIT - HOST_MEM_BYTES ))
[ $diff -lt 0 ] && diff=$(( -diff ))
if [ $diff -lt $((1024*1024)) ]; then
NO_HARD_LIMIT=1
fi
fi
if [ "$MEM_LIMIT" -ge 9223372036850000000 ] 2>/dev/null; then
NO_HARD_LIMIT=1
fi
fi
WS=$(( USAGE - INACTIVE ))
[ "$WS" -lt 0 ] && WS=0
U_MIB=$(to_mib "$USAGE")
WS_MIB=$(to_mib "$WS")
if [ "${NO_HARD_LIMIT:-0}" -eq 1 ] || [ "${MEM_LIMIT:-0}" -le 0 ]; then
echo "Memory: usage=${U_MIB}MiB, working_set=${WS_MIB}MiB, limit=no hard limit"
else
L_MIB=$(to_mib "$MEM_LIMIT")
PCT_U=$(awk -v u="$USAGE" -v l="$MEM_LIMIT" 'BEGIN{printf "%.1f", (u/l)*100}')
PCT_WS=$(awk -v w="$WS" -v l="$MEM_LIMIT" 'BEGIN{printf "%.1f", (w/l)*100}')
echo "Memory: usage=${U_MIB}MiB (${PCT_U}%) | working_set=${WS_MIB}MiB (${PCT_WS}%) | limit=${L_MIB}MiB"
fi