Skip to content

Commit 965b00a

Browse files
committed
Add px/differential_flamegraph script
Signed-off-by: Dom Del Nano <ddelnano@gmail.com> (cherry picked from commit 12881672c021e47a9090df3335c29f6048e99df3)
1 parent 4778ba1 commit 965b00a

File tree

3 files changed

+119
-0
lines changed

3 files changed

+119
-0
lines changed
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
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+
def export_flame_graph(start_time: str, namespace: str, pod: str, baseline_pod: str):
20+
stack_traces = px.DataFrame(table='stack_traces.beta', start_time=start_time)
21+
stack_traces.namespace = stack_traces.ctx['namespace']
22+
stack_traces = stack_traces[px.contains(stack_traces.namespace, namespace)]
23+
stack_traces.node = px.Node(px._exec_hostname())
24+
stack_traces.pod = stack_traces.ctx['pod']
25+
stack_traces.keep_row = px.select(px.contains(stack_traces.pod, baseline_pod), True, False)
26+
stack_traces.keep_row = px.select(stack_traces.keep_row or px.contains(stack_traces.pod, pod), True, False)
27+
stack_traces = stack_traces[stack_traces.keep_row]
28+
29+
stack_traces = stack_traces.groupby(['node', 'namespace', 'pod', 'stack_trace_id']).agg(
30+
stack_trace=('stack_trace', px.any),
31+
count=('count', px.sum)
32+
)
33+
34+
pod1 = stack_traces[px.contains(stack_traces.pod, baseline_pod)]
35+
pod1 = pod1.drop(['node', 'namespace', 'pod', 'stack_trace_id'])
36+
37+
pod2 = stack_traces[px.contains(stack_traces.pod, pod)]
38+
pod2 = pod2.drop(['node', 'namespace', 'pod', 'stack_trace_id'])
39+
40+
merged = pod1.merge(
41+
pod2,
42+
how='right',
43+
left_on='stack_trace',
44+
right_on='stack_trace'
45+
suffixes=['_1', '_2'],
46+
)
47+
# Pixie's stack trace format permits spaces, but Brendan Gregg's scripts do not
48+
merged.stack_trace_2 = px.replace(' ', merged.stack_trace_2, '')
49+
merged.delta = merged.count_2 - merged.count_1
50+
return merged[['stack_trace_2', 'count_1', 'count_2', 'delta']]
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
short: Differential Flame Graph
3+
long: >
4+
This live view shows a differential CPU flame graph. This is helpful in identifying what code
5+
paths have changed between deployments, different container instances, etc.
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
{
2+
"variables": [
3+
{
4+
"name": "start_time",
5+
"type": "PX_STRING",
6+
"description": "The relative start time of the window. Current time is assumed to be now",
7+
"defaultValue": "-5m"
8+
},
9+
{
10+
"name": "namespace",
11+
"type": "PX_NAMESPACE",
12+
"description": "The namespace to filter on."
13+
},
14+
{
15+
"name": "pod",
16+
"type": "PX_POD",
17+
"description": "The pod that will have its flamegraph analyzed compared to the baseline_pod"
18+
},
19+
{
20+
"name": "baseline_pod",
21+
"type": "PX_POD",
22+
"description": "The pod to serve as the baseline. The resulting flamegraph will show the difference from this pod's profile."
23+
}
24+
],
25+
"globalFuncs": [],
26+
"widgets": [
27+
{
28+
"name": "Flamegraph",
29+
"position": {
30+
"x": 0,
31+
"y": 0,
32+
"w": 12,
33+
"h": 6
34+
},
35+
"func": {
36+
"name": "export_flame_graph",
37+
"args": [
38+
{
39+
"name": "start_time",
40+
"variable": "start_time"
41+
},
42+
{
43+
"name": "namespace",
44+
"variable": "namespace"
45+
},
46+
{
47+
"name": "pod",
48+
"variable": "pod"
49+
},
50+
{
51+
"name": "baseline_pod",
52+
"variable": "baseline_pod"
53+
}
54+
]
55+
},
56+
"displaySpec": {
57+
"@type": "types.px.dev/px.vispb.StackTraceFlameGraph",
58+
"stacktraceColumn": "stack_trace_2",
59+
"countColumn": "count_2",
60+
"differenceColumn": "delta"
61+
}
62+
}
63+
]
64+
}

0 commit comments

Comments
 (0)