前言:虽然有翻译软件,虽然有chatgpt,毕竟语言隔阂,对这个工具还是一知半解,因此想通过翻译的方式和大家来一起学习下Perfetto这个强大的工具
#####################以下分割线#####################
英文原文在这里
本篇入门示范如何使用Trace Processor和Python 的API 来查询trace中的内容以及如何计算基于trace的度量
Trace Processor
Trace Processor是一个基于SQLite的多格式trace导入和查询引擎。它既是一个C++库,也是一个独立的可执行文件:trace_processor_shell(或者只是trace_proccessor)。
安装
# Download prebuilts (Linux and Mac only)
curl -LO https://get.perfetto.dev/trace_processor
chmod +x ./trace_processor
# Start the interactive shell
./trace_processor trace.perfetto-trace
# Start a local trace processor instance to replace wasm module in the UI
./trace_processor trace.perfetto-trace --httpd
在HTTP模式下,trace将加载到trace_processor中,而UI将通过TCP进行连接并发出查询。这可以允许加载任意大小的trace,因为与WASM模块不同,没有内存约束。因此这可以提高UI在SQL查询时的响应速度。
查询Trace Processor docs了解完整的使用方式
查询示范
有关更详尽的示例,请参阅各种数据源文档的SQL部分。
切片
切片是类似堆栈的事件,具有名称并持续一定的时间。
查询示范及输出样例:
> SELECT ts, dur, name FROM slice
ts dur name
-------------------- -------------------- ---------------------------
261187017446933 358594 eglSwapBuffersWithDamageKHR
261187017518340 357 onMessageReceived
261187020825163 9948 queueBuffer
261187021345235 642 bufferLoad
261187121345235 153 query
...
计数器
计数器是有具体数值的事件,数值会随着时间变化。示意图:
查询示范及输出:
> SELECT ts, value FROM counter
ts value
-------------------- --------------------
261187012149954 1454.000000
261187012399172 4232.000000
261187012447402 14304.000000
261187012535839 15490.000000
261187012590890 17490.000000
261187012590890 16590.000000
...
调度程序切片
调度器切片指示哪个线程在哪个CPU上、哪个时间被调度。
查询示范:
> SELECT ts, dur, cpu, utid FROM sched
ts dur cpu utid
-------------------- -------------------- -------------------- --------------------
261187012170489 267188 0 390
261187012170995 247153 1 767
261187012418183 12812 2 2790
261187012421099 220000 6 683
261187012430995 72396 7 2791
...
基于trace的度量
Trace Processor还提供了一个更高级的查询接口,允许运行预处理的查询,这里称为“metrics”。度量通常由领域专家策划,通常是最初添加插入点并输出结构化JSON/Protobuf/文本的人。度量允许获得trace的摘要视图,而无需键入任何SQL或在UI中加载trace。
metrics的模式文件位于/protos/perfetto/metrics目录中。相应的SQL查询位于/src/trace_processor/metrics中。
运行一个metrics
以运行android_cpu度量为例。该指标计算跟踪中每个进程的总CPU时间和总周期(CPU频率*在该频率下运行的时间),并按CPU(核心)数进行细分。
./trace_processor --run-metrics android_cpu trace.perfetto-trace
android_cpu {
process_info {
name: "/system/bin/init"
threads {
name: "init"
core {
id: 1
metrics {
mcycles: 1
runtime_ns: 570365
min_freq_khz: 1900800
max_freq_khz: 1900800
avg_freq_khz: 1902017
}
}
core {
id: 3
metrics {
mcycles: 0
runtime_ns: 366406
min_freq_khz: 1900800
max_freq_khz: 1900800
avg_freq_khz: 1902908
}
}
...
}
...
}
process_info {
name: "/system/bin/logd"
threads {
name: "logd.writer"
core {
id: 0
metrics {
mcycles: 8
runtime_ns: 33842357
min_freq_khz: 595200
max_freq_khz: 1900800
avg_freq_khz: 1891825
}
}
core {
id: 1
metrics {
mcycles: 9
runtime_ns: 36019300
min_freq_khz: 1171200
max_freq_khz: 1900800
avg_freq_khz: 1887969
}
}
...
}
...
}
...
}
运行多个metrics
可以使用逗号分隔符对--run metrics、标记多个度量。这将输出一个文本原型,其中包含运行两个度量的组合结果。
$ ./trace_processor --run-metrics android_mem,android_cpu trace.perfetto-trace
android_mem {
process_metrics {
process_name: ".dataservices"
total_counters {
anon_rss {
min: 19451904
max: 19890176
avg: 19837548.157829277
}
file_rss {
min: 25804800
max: 25829376
avg: 25827909.957489081
}
swap {
min: 9289728
max: 9728000
avg: 9342355.8421707246
}
anon_and_swap {
min: 29179904
max: 29179904
avg: 29179904
}
}
...
}
...
}
android_cpu {
process_info {
name: "/system/bin/init"
threads {
name: "init"
core {
id: 1
metrics {
mcycles: 1
runtime_ns: 570365
min_freq_khz: 1900800
max_freq_khz: 1900800
avg_freq_khz: 1902017
}
}
...
}
...
}
...
}
JSON 和二进制文件输出
trace processor还支持二进制protobuf和JSON作为替代输出格式。当离线时,这很有用。
与原始文本输出一样,支持单个和多个度量。
./trace_processor --run-metrics android_mem --metrics-output=binary trace.perfetto-trace
<binary protobuf output>
./trace_processor --run-metrics android_mem,android_cpu --metrics-output=json trace.perfetto-trace
{
"android_mem": {
"process_metrics": [
{
"process_name": ".dataservices",
"total_counters": {
"anon_rss": {
"min": 19451904.000000,
"max": 19890176.000000,
"avg": 19837548.157829
},
"file_rss": {
"min": 25804800.000000,
"max": 25829376.000000,
"avg": 25827909.957489
},
"swap": {
"min": 9289728.000000,
"max": 9728000.000000,
"avg": 9342355.842171
},
"anon_and_swap": {
"min": 29179904.000000,
"max": 29179904.000000,
"avg": 29179904.000000
}
},
...
},
...
]
}
"android_cpu": {
"process_info": [
{
"name": "\/system\/bin\/init",
"threads": [
{
"name": "init",
"core": [
{
"id": 1,
"metrics": {
"mcycles": 1,
"runtime_ns": 570365,
"min_freq_khz": 1900800,
"max_freq_khz": 1900800,
"avg_freq_khz": 1902017
}
},
...
]
...
}
...
]
...
},
...
]
...
}
}
Python API
使用Python可以直接查询trace,而不再需要trace_processor
。
安装
$ pip install perfetto
注意:perfetto仅支持Python 3.
功能演示
请参阅 Trace Processor (SQL) 的Python API部分,以获取有关所有可用函数的更多详细信息。
查询
from perfetto.trace_processor import TraceProcessor
tp = TraceProcessor(trace='trace.perfetto-trace')
qr_it = tp.query('SELECT name FROM slice')
for row in qr_it:
print(row.name)
输出
eglSwapBuffersWithDamageKHR
onMessageReceived
queueBuffer
bufferLoad
query
...
使用Pandas 数据帧查询
from perfetto.trace_processor import TraceProcessor
tp = TraceProcessor(trace='trace.perfetto-trace')
qr_it = tp.query('SELECT ts, name FROM slice')
qr_df = qr_it.as_pandas_dataframe()
print(qr_df.to_string())
输出
ts name
-------------------- ---------------------------
261187017446933 eglSwapBuffersWithDamageKHR
261187017518340 onMessageReceived
261187020825163 queueBuffer
261187021345235 bufferLoad
261187121345235 query
...
Metic
from perfetto.trace_processor import TraceProcessor
tp = TraceProcessor(trace='trace.perfetto-trace')
cpu_metrics = tp.metric(['android_cpu'])
print(cpu_metrics)
输出:
metrics {
android_cpu {
process_info {
name: "/system/bin/init"
threads {
name: "init"
core {
id: 1
metrics {
mcycles: 1
runtime_ns: 570365
min_freq_khz: 1900800
max_freq_khz: 1900800
avg_freq_khz: 1902017
}
}
core {
id: 3
metrics {
mcycles: 0
runtime_ns: 366406
min_freq_khz: 1900800
max_freq_khz: 1900800
avg_freq_khz: 1902908
}
}
...
}
...
}
...
}
}
还可以从以下这些方面来探索Perfetto更多trace分析功能:
- trace conversion quickstart 示范了如何将trace 转换成其他的数据格式,以便和现有的工具一起配合使用。
- Trace Processor documentation 提供了使用的更加介绍,包括如何查询以及Trace Processor中的表组成详细信息。
- metrics documentation 对度量有更加深入的介绍,包括如何从头开始构建一个实验性质的度量。
- SQL table reference 可以看到Trace Processor中所有表格的信息
- common tasks列出了如何将新度量添加到跟踪处理器的步骤
#####################以上分割线#####################
后记:
1 本次主要使用百度翻译,虽然被骂,但至少翻译这个工具降低了门槛。
2 英文文档中的长难句真的是又长又难,基于百度的翻译,然后自己再调整下,水平实在有限。
3 技术背景知识不够,有些专有名词不知道怎么翻译,也不知道百度翻译的是否准确,功夫在诗外。
4 万事开头难,中间难不难,还不知道。中间的事后面再说,正确一天翻译一篇。
5 虽然可能会有人不屑,但总要有人去做不起眼的小事。
6 google 厉害,这个perfetto 工具也很厉害。君子善假于物也。
7 工具的使用是最简单的入门,背后还有更多的东西值得学习。
8 水平实在有限,闻过则喜,希望有更多的人反馈,期待更好的建议