|
| 1 | +#!/usr/bin/env bash |
| 2 | + |
| 3 | +set -eu -o pipefail |
| 4 | +trap cleanup INT EXIT |
| 5 | + |
| 6 | +# config |
| 7 | +declare DURATION=${DURATION:-30} |
| 8 | +declare KEPLER_PORT=${KEPLER_PORT:-28282} |
| 9 | + |
| 10 | +# constants |
| 11 | +PROJECT_ROOT="$(git rev-parse --show-toplevel)" |
| 12 | +declare -r PROJECT_ROOT |
| 13 | +declare -r TMP_DIR="$PROJECT_ROOT/tmp" |
| 14 | +declare -r CPU_PROFILE_DIR="$TMP_DIR/cpu-profile" |
| 15 | +declare -r MEM_PROFILE_DIR="$TMP_DIR/mem-profile" |
| 16 | +declare -r KEPLER_BIN_DIR="$PROJECT_ROOT/bin" |
| 17 | +declare -r CPU_HTTP_PORT=29000 |
| 18 | +declare -r MEM_HTTP_PORT=29001 |
| 19 | + |
| 20 | +source "$PROJECT_ROOT/hack/utils.bash" |
| 21 | + |
| 22 | +cleanup() { |
| 23 | + info "Cleaning up ..." |
| 24 | + # Terminate all background jobs (e.g. pprof servers) |
| 25 | + { jobs -p | xargs -I {} -- pkill -TERM -P {}; } || true |
| 26 | + wait |
| 27 | + sleep 1 |
| 28 | + |
| 29 | + return 0 |
| 30 | +} |
| 31 | + |
| 32 | +capture_cpu_profile() { |
| 33 | + run go tool pprof -proto -seconds "$DURATION" \ |
| 34 | + -output "$CPU_PROFILE_DIR"/profile.pb.gz "$KEPLER_BIN_DIR/kepler" \ |
| 35 | + "http://localhost:$KEPLER_PORT/debug/pprof/profile" || return 1 |
| 36 | + |
| 37 | + # Start pprof web server in background |
| 38 | + run go tool pprof --http "localhost:$CPU_HTTP_PORT" --no_browser \ |
| 39 | + "$KEPLER_BIN_DIR/kepler" "$CPU_PROFILE_DIR/profile.pb.gz" </dev/null & |
| 40 | + sleep 1 |
| 41 | + # Fetch visualizations |
| 42 | + for sample in {cpu,samples}; do |
| 43 | + curl "http://localhost:$CPU_HTTP_PORT/ui/?si=$sample" -o "$CPU_PROFILE_DIR/graph-$sample.html" |
| 44 | + curl "http://localhost:$CPU_HTTP_PORT/ui/flamegraph?si=$sample" -o "$CPU_PROFILE_DIR/flamegraph-$sample.html" |
| 45 | + for page in top peek disasm; do |
| 46 | + curl "http://localhost:$CPU_HTTP_PORT/ui/$page?si=$sample" -o "$CPU_PROFILE_DIR/$page-$sample.html" |
| 47 | + done |
| 48 | + done |
| 49 | + |
| 50 | + return 0 |
| 51 | +} |
| 52 | + |
| 53 | +capture_mem_profile() { |
| 54 | + run go tool pprof -proto -seconds "$DURATION" \ |
| 55 | + -output "$MEM_PROFILE_DIR"/profile.pb.gz "$KEPLER_BIN_DIR/kepler" \ |
| 56 | + "http://localhost:$KEPLER_PORT/debug/pprof/heap" || return 1 |
| 57 | + |
| 58 | + # Start pprof web server in background |
| 59 | + run go tool pprof --http "localhost:$MEM_HTTP_PORT" --no_browser \ |
| 60 | + "$KEPLER_BIN_DIR/kepler" "$MEM_PROFILE_DIR/profile.pb.gz" </dev/null & |
| 61 | + sleep 1 |
| 62 | + # Fetch visualizations |
| 63 | + for sample in {alloc,inuse}_{objects,space}; do |
| 64 | + curl "http://localhost:$MEM_HTTP_PORT/ui/?si=$sample" -o "$MEM_PROFILE_DIR/graph-$sample.html" |
| 65 | + curl "http://localhost:$MEM_HTTP_PORT/ui/flamegraph?si=$sample" -o "$MEM_PROFILE_DIR/flamegraph-$sample.html" |
| 66 | + for page in top peek disasm; do |
| 67 | + curl "http://localhost:$MEM_HTTP_PORT/ui/$page?si=$sample" -o "$MEM_PROFILE_DIR/$page-$sample.html" |
| 68 | + done |
| 69 | + done |
| 70 | + |
| 71 | + return 0 |
| 72 | +} |
| 73 | + |
| 74 | +main() { |
| 75 | + cd "$PROJECT_ROOT" |
| 76 | + mkdir -p "${CPU_PROFILE_DIR}" |
| 77 | + mkdir -p "${MEM_PROFILE_DIR}" |
| 78 | + |
| 79 | + header "Running CPU Profiling" |
| 80 | + capture_cpu_profile || { |
| 81 | + fail "CPU Profiling failed" |
| 82 | + return 1 |
| 83 | + } |
| 84 | + header "Running Memory Profiling" |
| 85 | + capture_mem_profile || { |
| 86 | + fail "Memory Profiling failed" |
| 87 | + return 1 |
| 88 | + } |
| 89 | +} |
| 90 | + |
| 91 | +main "$@" |
0 commit comments