Files
2026-07-13 13:22:34 +08:00

88 lines
2.5 KiB
Bash
Executable File

#!/usr/bin/env bash
# Sample CPU and memory usage while running a command, then post mermaid
# xychart-beta line charts to GITHUB_STEP_SUMMARY (or stdout if running
# locally outside GitHub Actions).
#
# Usage: dev/profile.sh <command> [args...]
#
# Environment overrides:
# PROFILE_INTERVAL_SECONDS sampling interval in seconds (default: 2)
# PROFILE_DATA_FILE path to write raw CSV samples (default: /tmp/profile-metrics.csv)
#
# Linux-only: reads /proc/stat and /proc/meminfo.
set -uo pipefail
SAMPLE_FILE=${PROFILE_DATA_FILE:-/tmp/profile-metrics.csv}
SAMPLE_INTERVAL_SECONDS=${PROFILE_INTERVAL_SECONDS:-2}
SUMMARY_FILE=${GITHUB_STEP_SUMMARY:-/dev/stdout}
if [ ! -r /proc/stat ] || [ ! -r /proc/meminfo ]; then
echo "profile.sh: /proc/stat or /proc/meminfo unavailable; running command without sampling" >&2
exec "$@"
fi
(
printf 'timestamp,cpu_pct,mem_gb\n'
prev_total=0
prev_idle=0
while true; do
read _ u n s i io irq si st _ < /proc/stat
t=$((u + n + s + i + io + irq + si + st))
if [ "$prev_total" -ne 0 ]; then
dt=$((t - prev_total))
di=$(((i + io) - prev_idle))
cpu=$((dt > 0 ? 100 * (dt - di) / dt : 0))
else
cpu=0
fi
prev_total=$t
prev_idle=$((i + io))
mem=$(awk '/MemTotal/{T=$2} /MemAvailable/{A=$2} END{printf "%.2f", (T-A)/1024/1024}' /proc/meminfo)
printf '%s,%s,%s\n' "$(date +%s)" "$cpu" "$mem"
sleep "$SAMPLE_INTERVAL_SECONDS"
done
) >"$SAMPLE_FILE" 2>&1 &
sampler_pid=$!
cleanup() {
kill "$sampler_pid" 2>/dev/null || true
wait "$sampler_pid" 2>/dev/null || true
if [ ! -s "$SAMPLE_FILE" ]; then
return 0
fi
local data_csv=/tmp/profile-data.csv
local sampled=/tmp/profile-sampled.csv
local n step total cpu_list mem_list
tail -n +2 "$SAMPLE_FILE" >"$data_csv"
n=$(wc -l <"$data_csv")
step=$((n / 30 + 1))
awk -v step="$step" 'NR % step == 0' "$data_csv" >"$sampled"
total=$(awk -F, 'NR==1{first=$1} END{print $1-first}' "$data_csv")
cpu_list=$(awk -F, '{printf "%s,",$2}' "$sampled" | sed 's/,$//')
mem_list=$(awk -F, '{printf "%s,",$3}' "$sampled" | sed 's/,$//')
{
echo '## CPU usage (%)'
echo '```mermaid'
echo 'xychart-beta'
echo " x-axis \"Elapsed (s)\" 0 --> $total"
echo ' y-axis "CPU %" 0 --> 100'
echo " line [$cpu_list]"
echo '```'
echo
echo '## Memory used (GB)'
echo '```mermaid'
echo 'xychart-beta'
echo " x-axis \"Elapsed (s)\" 0 --> $total"
echo ' y-axis "Memory GB"'
echo " line [$mem_list]"
echo '```'
} >>"$SUMMARY_FILE"
}
trap cleanup EXIT
"$@"