Skip to content

Commit 93cf09f

Browse files
authored
Add collect_heap_pprofs.sh script for easier collection of heap profiles (#2160)
1 parent 78855da commit 93cf09f

File tree

3 files changed

+94
-8
lines changed

3 files changed

+94
-8
lines changed

scripts/collect_heap_pprofs.sh

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
#!/bin/bash -e
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+
heap_profile_dir="$1"
30+
cluster_id="$2"
31+
script_dir=$(dirname "$(realpath "$0")")
32+
repo_root=$(git rev-parse --show-toplevel)
33+
34+
if [ -z "$heap_profile_dir" ] || [ -z "$cluster_id" ]; then
35+
usage
36+
fi
37+
38+
mkdir -p "$heap_profile_dir"
39+
40+
pxl_heap_output_file="${heap_profile_dir}/raw_output_from_hot_table_test.json"
41+
42+
px run -o json -c "$cluster_id" -f "${repo_root}/src/pxl_scripts/px/collect_heap_dumps.pxl" > "$pxl_heap_output_file"
43+
44+
while IFS= read -r line; do
45+
hostname=$(echo "$line" | jq -r '.hostname')
46+
heap_content=$(echo "$line" | jq -r '.heap')
47+
echo "$heap_content" > "${heap_profile_dir}/${hostname}.txt"
48+
echo "Wrote ${heap_profile_dir}/${hostname}.txt"
49+
done < "$pxl_heap_output_file"
50+
51+
nodes=()
52+
for file in "${heap_profile_dir}"/*.txt; do
53+
hostname=$(basename "${file%.*}")
54+
nodes+=("$hostname")
55+
hostname_dir="${heap_profile_dir}/${hostname}"
56+
mkdir -p "$hostname_dir"
57+
done
58+
59+
for node in "${nodes[@]}"; do
60+
"${script_dir}/download_heap_prof_mapped_files.sh" "${heap_profile_dir}/${node}.txt" "$node" "${@:3}"
61+
done

scripts/download_heap_prof_mapped_files.sh

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
#!/bin/bash
1+
#!/bin/bash -e
22

33
# Copyright 2018- The Pixie Authors.
44
#
@@ -20,13 +20,13 @@ 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
}
25-
set -e
2626

2727
heap_profile="$1"
2828
node_name="$2"
29-
output_dir=/tmp/prof_bins
29+
output_dir="${heap_profile%.txt}"
3030

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

4646
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"
47+
zone=$(gcloud compute instances list "${@:3}" --filter="$node_name" --format="table(name, zone)"| tail -n 1 | awk '{print $2}')
48+
procs=$(gcloud compute ssh --zone "$zone" --command='ps ax' "$node_name" "${@:3}" 2> "$err_file") || cat "$err_file" && rm "$err_file"
4849

4950
# Find the mapping that corresponds to a process on the node.
5051
# We assume that the process was started by running one of the files in the mappings
@@ -79,15 +80,15 @@ output_on_err() {
7980
}
8081

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

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

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

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

9293
echo "Dumped mapped binaries to $output_dir"
9394
echo "Run 'PPROF_BINARY_PATH=$output_dir pprof -http=localhost:8888 $heap_profile' to visualize the profile."
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
# Copyright 2018- The Pixie Authors.
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
#
15+
# SPDX-License-Identifier: Apache-2.0
16+
17+
import px
18+
19+
df = px.GetAgentStatus(False)
20+
df = df[['asid', 'hostname']]
21+
heap_stats = px._HeapGrowthStacks()
22+
df = df.merge(heap_stats, how='inner', left_on='asid', right_on='asid')
23+
df = df[['hostname', 'heap']]
24+
px.display(df)

0 commit comments

Comments
 (0)