Skip to content

Commit 625dd8c

Browse files
committed
devlib.collector: Add PerfettoCollector
Add a Collector for accessing Google's Perfetto tracing infrastructure. The Collector takes a path to an on-device config file, starts tracing in the background using the perfetto binary and then stops by killing the tracing process. Signed-off-by: Kajetan Puchalski <[email protected]>
1 parent 3d2cdd9 commit 625dd8c

File tree

2 files changed

+69
-0
lines changed

2 files changed

+69
-0
lines changed

devlib/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@
4646
from devlib.derived.fps import DerivedGfxInfoStats, DerivedSurfaceFlingerStats
4747

4848
from devlib.collector.ftrace import FtraceCollector
49+
from devlib.collector.perfetto import PerfettoCollector
4950
from devlib.collector.perf import PerfCollector
5051
from devlib.collector.serial_trace import SerialTraceCollector
5152
from devlib.collector.dmesg import DmesgCollector

devlib/collector/perfetto.py

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
# Copyright 2023 ARM Limited
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+
16+
import os
17+
import time
18+
import subprocess
19+
20+
from devlib.collector import (CollectorBase, CollectorOutput,
21+
CollectorOutputEntry)
22+
from devlib.exception import TargetStableError, HostError
23+
from devlib.utils.misc import check_output, which, memoized
24+
25+
OUTPUT_PERFETTO_TRACE = 'trace.perfetto-trace'
26+
27+
class PerfettoCollector(CollectorBase):
28+
29+
def __init__(self, target, config=None):
30+
super(PerfettoCollector, self).__init__(target)
31+
self.target_output_file = target.path.join(self.target.working_directory, OUTPUT_PERFETTO_TRACE)
32+
self.output_path = None
33+
self.config = config
34+
35+
if not self.target.is_installed('perfetto'):
36+
raise TargetStableError('No perfetto found on device.')
37+
self.target_binary = 'perfetto'
38+
39+
def start(self):
40+
# start tracing and save the PID to stop it later
41+
self.pid = self.target.execute(
42+
"cat {} | {} --background --txt -c - -o {}".format(
43+
self.config, self.target_binary, self.target_output_file
44+
)
45+
)
46+
47+
def stop(self):
48+
# stop tracing by killing the process
49+
self.target.execute("kill {}".format(self.pid))
50+
51+
def set_output(self, output_path):
52+
if os.path.isdir(output_path):
53+
output_path = os.path.join(output_path,
54+
os.path.basename(self.target_output_file))
55+
self.output_path = output_path
56+
57+
def get_data(self):
58+
if self.output_path is None:
59+
raise RuntimeError("Output path was not set.")
60+
# adjust the pull timeout based on the size of the file
61+
self.target.pull(self.target_output_file, self.output_path)
62+
output = CollectorOutput()
63+
if not os.path.isfile(self.output_path):
64+
self.logger.warning('Perfetto trace not pulled from device.')
65+
else:
66+
output.append(CollectorOutputEntry(self.output_path, 'file'))
67+
return output
68+

0 commit comments

Comments
 (0)