Skip to content

Commit e2b92f0

Browse files
committed
Add collect_heap_pprofs.sh script for easier collection of heap profiles
Signed-off-by: Dom Del Nano <ddelnano@gmail.com>
1 parent 9309846 commit e2b92f0

3 files changed

Lines changed: 79 additions & 6 deletions

File tree

scripts/collect_heap_pprofs.sh

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
#!/bin/bash
2+
3+
# Copyright 2018- The Pixie Authors.
4+
#
5+
# Licensed under the Apache License, Version 2.0 (the "License");
6+
# you may not use this file except in compliance with the License.
7+
# You may obtain a copy of the License at
8+
#
9+
# http://www.apache.org/licenses/LICENSE-2.0
10+
#
11+
# Unless required by applicable law or agreed to in writing, software
12+
# distributed under the License is distributed on an "AS IS" BASIS,
13+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
# See the License for the specific language governing permissions and
15+
# limitations under the License.
16+
#
17+
# SPDX-License-Identifier: Apache-2.0
18+
19+
usage() {
20+
echo "This script downloads all of the files listed in the mappings section of a heap profile."
21+
echo ""
22+
echo "Usage: $0 <heap_profile_dir> <vizier_cluster_id> [<gcloud ssh opts>...]"
23+
echo "<heap_profile_dir> : the directory where the heap profile and memory mapped files will be stored. It will be created if it does not exist."
24+
echo "<vizier_cluster_id> : the ID of the Vizier cluster to connect to."
25+
echo "Common gcloud ssh options include --project."
26+
exit 1
27+
}
28+
29+
set -e
30+
31+
heap_profile_dir="$1"
32+
cluster_id="$2"
33+
script_dir=$(dirname "$(realpath "$0")")
34+
repo_root=$(git rev-parse --show-toplevel)
35+
36+
if [ -z "$heap_profile_dir" ] || [ -z "$cluster_id" ]; then
37+
usage
38+
fi
39+
40+
mkdir -p "$heap_profile_dir"
41+
42+
pxl_heap_output_file="${heap_profile_dir}/raw_output_from_hot_table_test.json"
43+
44+
px run -o json -c "$cluster_id" -f "${repo_root}/src/pxl_scripts/px/collect_heap_dumps.pxl" > "$pxl_heap_output_file"
45+
46+
while IFS= read -r line; do
47+
hostname=$(echo "$line" | jq -r '.hostname')
48+
heap_content=$(echo "$line" | jq -r '.heap')
49+
echo "$heap_content" > "${heap_profile_dir}/${hostname}.txt"
50+
echo "Wrote ${heap_profile_dir}/${hostname}.txt"
51+
done < "$pxl_heap_output_file"
52+
53+
nodes=()
54+
for file in "${heap_profile_dir}"/*.txt; do
55+
hostname=$(basename "${file%.*}")
56+
nodes+=("$hostname")
57+
hostname_dir="${heap_profile_dir}/${hostname}"
58+
mkdir -p "$hostname_dir"
59+
done
60+
61+
for node in "${nodes[@]}"; do
62+
"${script_dir}/download_heap_prof_mapped_files.sh" "${heap_profile_dir}/${node}.txt" "$node" "${@:3}"
63+
done

scripts/download_heap_prof_mapped_files.sh

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -20,13 +20,14 @@ usage() {
2020
echo "This script downloads all of the files listed in the mappings section of a heap profile."
2121
echo ""
2222
echo "Usage: $0 <heap_profile> <node_name> [<gcloud ssh opts>...]"
23+
echo "Common gcloud ssh options include --project."
2324
exit 1
2425
}
2526
set -e
2627

2728
heap_profile="$1"
2829
node_name="$2"
29-
output_dir=/tmp/prof_bins
30+
output_dir="${heap_profile%.txt}"
3031

3132
if [ -z "$heap_profile" ] || [ -z "$node_name" ]; then
3233
usage
@@ -44,7 +45,8 @@ mkdir -p "$output_dir"
4445
mappings=$(awk 'BEGIN{m=0} /MAPPED_LIBRARIES/{m=1} { if(m) { print $6 }}' "$heap_profile" | grep "^/" | sort | uniq)
4546

4647
err_file="$output_dir/gcloud_error.log"
47-
procs=$(gcloud compute ssh --command='ps ax' "$node_name" "${@:3}" 2> "$err_file") || cat "$err_file" && rm "$err_file"
48+
zone=$(gcloud compute instances list "${@:3}" --filter="$node_name" --format="table(name, zone)"| tail -n 1 | awk '{print $2}')
49+
procs=$(gcloud compute ssh --zone "$zone" --command='ps ax' "$node_name" "${@:3}" 2> "$err_file") || cat "$err_file" && rm "$err_file"
4850

4951
# Find the mapping that corresponds to a process on the node.
5052
# We assume that the process was started by running one of the files in the mappings
@@ -79,15 +81,15 @@ output_on_err() {
7981
}
8082

8183
# Create tar archive on node.
82-
output_on_err gcloud compute ssh --command="$create_tar_cmd" "$node_name" "${@:3}"
84+
output_on_err gcloud compute ssh --zone "$zone" --command="$create_tar_cmd" "$node_name" "${@:3}"
8385

8486
# Copy archive to local machine.
85-
output_on_err gcloud compute scp "${@:3}" "$USER@$node_name:~/$tar_file" "/tmp/$tar_file"
87+
output_on_err gcloud compute scp --zone "$zone" "${@:3}" "$USER@$node_name:~/$tar_file" "${output_dir}/$tar_file"
8688

8789
# Cleanup tar archive on node.
88-
output_on_err gcloud compute ssh --command="rm ~/$tar_file" "$node_name" "${@:3}"
90+
output_on_err gcloud compute ssh --zone "$zone" --command="rm ~/$tar_file" "$node_name" "${@:3}"
8991

90-
tar --strip-components=1 -C "$output_dir" -xzf "/tmp/$tar_file"
92+
tar --strip-components=1 -C "$output_dir" -xzf "${output_dir}/$tar_file"
9193

9294
echo "Dumped mapped binaries to $output_dir"
9395
echo "Run 'PPROF_BINARY_PATH=$output_dir pprof -http=localhost:8888 $heap_profile' to visualize the profile."
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
import px
2+
3+
df = px.GetAgentStatus(False)
4+
df = df[['asid', 'hostname']]
5+
heap_stats = px._HeapGrowthStacks()
6+
df = df.merge(heap_stats, how='inner', left_on='asid', right_on='asid')
7+
df = df[['hostname', 'heap']]
8+
px.display(df)

0 commit comments

Comments
 (0)