使用 Perfetto 可视化外部 Trace 格式

在本指南中,你将了解:

Perfetto 能够打开和分析由各种外部工具和系统生成的 trace 文件,而不仅仅是其自己的原生 protobuf 格式。你可能已经拥有这些格式的 traces,如果:

使用 Perfetto 检查这些外部 traces 的主要优势是其强大的 profile 和可视化能力:

下面,我们详细介绍支持的格式,提供关于其典型用例的上下文,并概述将它们加载到 Perfetto 时期望的内容。

Chrome JSON 格式

描述: Chrome JSON trace 格式由事件对象的 JSON 数组组成。每个对象代表单个 trace 事件,通常包括 pid(进程 ID)、tid(线程 ID)、ts(以微秒为单位的时间戳)、ph(阶段,指示事件类型,如 begin、end、instant、counter 等)、name(事件名称)、cat(类别)和 args(特定于事件的参数)等字段。此格式最初是为 Chrome 的 about:tracing(现在为 chrome://tracing)工具开发的。

常见场景: 虽然 Chromium 浏览器开发者现在主要使用 Perfetto 的原生 protobuf 格式进行 trace 收集,但在几种情况下仍会遇到 Chrome JSON 格式:

Perfetto 支持:

如何生成:

外部资源:

Firefox Profiler JSON 格式

描述: Firefox Profiler JSON 格式主要用于 Firefox Profiler,这是一个基于 Web 的性能 profiling 工具。虽然该格式可以描述各种类型的 Timeline 数据,包括"markers"(类似于 trace 事件),但其主要优势以及 Perfetto 对它的主要兴趣在于表示 CPU profiling 数据,特别是采样调用栈。这使其成为可视化来自各种 profiling 源的火焰图和调用树的绝佳目标格式。

常见场景: Perfetto 用户遇到此格式的最常见原因是:

Perfetto 支持:

如何生成: 对于 Perfetto 用户最相关的生成路径涉及将 Linux perf 或 Android simpleperf 的原生 CPU profiles 进行转换。

  1. 使用 perf record 记录 profile: 以 99Hz 采样 1 秒,使用 DWARF 调用图捕获特定命令/进程或系统范围的 CPU 样本,生成 perf.data 文件。

    # 示例:以 99Hz 采样 1 秒,使用 DWARF 调用图 sudo perf record -F 99 -g --call-graph dwarf --output perf.data -- find ~ -name 'foo'

    有关详细命令选项,请参阅 man perf-record。确保二进制文件的调试符号可访问,以便正确进行符号化。

  2. perf.data 转换为 Firefox Profiler JSON: 使用 gecko 报告脚本与 perf script

    sudo perf script report gecko --save-only my_linux_profile.json

    此命令处理 perf.data 文件并输出 my_linux_profile.json,格式与 Firefox Profiler 兼容。如果你的 perf 版本中 report gecko 不可用,请查阅发行版的文档以获取替代方案或额外的 perf 脚本包。

  3. 在 ui.perfetto.dev 中打开此 trace

    导航到 ui.perfetto.dev 并将 my_linux_profile.json 文件上传到 UI。一旦 trace 打开,你应该能够选择单个 CPU 样本或包含 CPU 样本的时间范围,以获得该区域中所有样本的火焰图。

    这是一个示例效果图

在 Android 上,simpleperf 用于 CPU profiling。可以从 Android 开源项目 (AOSP) 使用 git 直接下载必要的 Python 脚本(app_profiler.pygecko_profile_generator.py)。你还需要 NDK。

  1. 下载 simpleperf 脚本:

    git clone https://android.googlesource.com/platform/system/extras --depth=1

    克隆后,脚本将位于 extras/simpleperf/scripts 子目录中。 注意:此方法提供后处理脚本,但你还需要一个兼容的 simpleperf 二进制文件来记录 profile。此二进制文件通常在你的 Android 设备上可用,app_profiler.py 会自动找到它。

  2. 使用 app_profiler.py 记录 profile: 此脚本在设备上调用记录,并通过 ADB 将 profile 拉到主机机器。

    # 替换 <your.app.package.name> python extras/simpleperf/scripts/app_profiler.py \ --app <your.app.package.name> \ -r "-g --duration 10" \ -o perf.data
    • 此命令使用 DWARF 调用图(-g)对指定应用进行 10 秒的 profiling。
    • 它写入 perf.data 和一个 binary_cache/(用于符号)。
    • 有关更多详细信息,请参阅 simpleperf 文档)。
  3. simpleperf 数据转换为 Firefox Profiler JSON: 使用来自同一 AOSP checkout 的 gecko_profile_generator.py 脚本。

    python extras/simpleperf/scripts/gecko_profile_generator.py \ --symfs binary_cache \ -i perf.data \ > gecko_profile.json
    • 这将使用 binary_cache 中的符号将 simpleperf 数据转换为 Firefox Profiler JSON 格式。
  4. 在 ui.perfetto.dev 中打开此 trace 导航到 ui.perfetto.dev 并将 gecko_profile.json 文件上传到 UI。一旦 trace 打开,你应该能够选择单个 CPU 样本或包含 CPU 样本的时间范围,以获得该区域中所有样本的火焰图。

    这是一个示例效果图

其他方法(对于 Perfetto 导入场景较少见):

外部资源:

Android systrace 格式

描述: Android Systrace 是 Android 的旧版系统级 tracing 工具,主要在 Android 9 (Pie) 引入 Perfetto 之前使用。它通过 ftrace 捕获内核活动(例如,CPU 调度、I/O)并通过 ATrace 捕获用户空间注释(例如,android.os.Trace)。Systrace 通常生成一个交互式 HTML 文件,将 trace 数据嵌入到基于文本的格式中。

常见场景(主要是旧版): 你通常只会在处理旧数据或旧工作流时遇到 Android Systrace 格式,例如:

对于 Android 上的任何当前或新 tracing(9 Pie 及更新版本),Perfetto 是标准且强烈推荐的工具。

Perfetto 支持:

如何生成(旧版方法): 以下方法描述了 Systrace 文件的历史创建方式,为了在处理旧 traces 时提供上下文。这些方法已弃用,不应在 Android 9 (Pie) 或更新版本上用于新的 trace 收集。

外部资源:

Perf 文本格式(来自 perf script)

描述: "Perf 文本格式"通常指 Linux 上 perf script 命令生成的人类可读的文本输出。此命令处理 perf.data 文件(由 perf record 创建)并按时间顺序打印记录的事件日志。输出通过 perf script 选项高度可配置,但通常包括 CPU 样本及其调用栈、时间戳、进程/线程标识符、CPU 编号和事件名称。

常见场景: 此格式通常用于:

Perfetto 支持:

如何生成:

  1. 使用 perf record 记录 profile: 首先,使用 perf record 捕获 profiling 数据。这会创建一个 perf.data 文件。

    # 示例:以 99Hz 采样 1 秒,使用 DWARF 调用图 sudo perf record -F 99 -g --call-graph dwarf --output perf.data -- find ~ -name 'foo'

    有关详细命令选项,请参阅 man perf-record。确保二进制文件的调试符号可访问,以便 perf script 正确进行符号化。

  2. 使用 perf script 生成文本输出: 处理 perf.data 文件以生成文本输出。

    # 默认输出 sudo perf script -i perf.data > my_perf_output.txt

    对于通常对其他工具有用(以及可能对 Perfetto 的解析器有用,如果它查找特定字段)的更详细输出,你可以指定字段:

    perf script -i perf.data -F comm,pid,tid,cpu,time,event,ip,sym,dso,trace > my_perf_output_detailed.txt

    有关其广泛的格式化选项,请参阅 man perf-script

  3. 在 ui.perfetto.dev 中打开此 trace

    导航到 ui.perfetto.dev 并将 my_perf_output.txt 文件上传到 UI。一旦 trace 打开,你应该能够选择单个 CPU 样本或包含 CPU 样本的时间范围,以获得该区域中所有样本的火焰图。

    这是一个示例效果图

外部资源:

Simpleperf proto 格式

描述: Simpleperf 是 Android 基于 Linux perf 框架构建的 profiling 工具。"Simpleperf proto 格式"指 simpleperf report-sample --protobuf 命令生成的二进制 protobuf 格式。此格式包含 CPU 样本及调用栈、进程/线程信息、文件映射和符号表,以紧凑的二进制表示。Android Studio 的 CPU profiler 在显示 simpleperf profiles 时在内部使用此格式。

常见场景: 此格式用于:

Perfetto 支持:

如何生成:

  1. 使用 simpleperf 记录 profile: 首先,使用 simpleperf record 捕获 profiling 数据。

    # 示例:使用调用图对 Android 应用进行 profiling adb shell simpleperf record -p <pid> -g --duration 10 adb pull /data/local/tmp/perf.data simpleperf.data

    有关详细命令选项,请参阅 simpleperf record --help

  2. 转换为 proto 格式: 使用 simpleperf report-sample 将原始记录转换为 protobuf 格式:

    # 使用调用链转换为 proto 格式 simpleperf report-sample --protobuf --show-callchain \ -i simpleperf.data -o simpleperf.proto # 可选提供符号目录以获得更好的符号化 simpleperf report-sample --protobuf --show-callchain \ -i simpleperf.data -o simpleperf.proto \ --symdir /path/to/symbols

    --show-callchain 标志是必需的,以在输出中包含调用栈信息。

  3. 在 ui.perfetto.dev 中打开

    导航到 ui.perfetto.dev 并上传 simpleperf.proto 文件。trace 将被导入,你可以在 UI 中选择时间范围来查看 CPU 样本的火焰图。

Linux ftrace 文本格式

描述: Linux ftrace 文本格式是 Linux 内核 ftrace tracing 基础设施生成的原始、人类可读的输出。此基于文本的格式中的每一行通常代表单个 trace 事件,并遵循常见结构:TASK-PID CPU# [MARKERS] TIMESTAMP FUNCTION --- ARGS。例如,sched_switch 事件可能如下所示:bash-1234 [002] ...1 5075.958079: sched_switch: prev_comm=bash prev_pid=1234 prev_prio=120 prev_state=R ==> next_comm=trace-cmd next_pid=5678 next_prio=120。此格式可能非常详细,但它是 ftrace 运行方式的基础,并通过 tracefs 文件系统公开(通常挂载在 /sys/kernel/tracing)。

常见场景: 你可能会在以下情况下遇到或使用此格式:

Perfetto 支持: Perfetto 对 ftrace 文本格式的支持主要是为了遗留兼容性,并以尽最大努力的方式维护。

如何生成(关于现有日志的上下文): 这些方法描述了如何使用 tracefs(通常挂载在 /sys/kernel/tracing)创建 ftrace 文本日志。对于新的 tracing,首选直接使用 Perfetto 的 ftrace 数据源。

外部资源:

ART method tracing 格式

描述: Android Runtime (ART) method tracing 格式(通常在 .trace 文件中找到)是 Android 特定的二进制格式。它捕获关于 Android 应用内 Java 和 Kotlin 方法执行的详细信息,本质上是记录每个被调用方法的进入和退出点。这允许对应用的运行时行为进行细粒度的方法级分析。

常见场景: 此格式通常在以下情况下使用:

Perfetto 支持:

如何生成:

外部资源:

macOS Instruments 格式(XML 导出)

描述: Apple 的 Instruments 工具是 Xcode 的一部分,用于 macOS 和 iOS 的性能分析。虽然 Instruments 将其完整数据保存在专有的 .trace 包格式中,但 Perfetto 的支持专注于可以从这些 Instruments traces 导出的 XML 格式。此 XML 导出主要用于提取 CPU profiling 数据(栈样本)。

常见场景: 此导入路径在以下情况下相关:

Perfetto 支持:

如何生成: Traces 最初使用 Xcode 中的 Instruments 应用程序或 xctrace 命令行实用程序收集,生成 .trace 包。Perfetto 摄取的 XML 文件是从此类 trace 导出的。(在 Instruments 工具本身中导出到此 XML 格式的具体步骤需要遵循;Perfetto 然后消费生成的 XML 文件)。

外部资源:

Ninja logs 格式(.ninja_log)

描述: Ninja 构建系统,以其速度和在 Chromium 和 Android 等项目中的使用而闻名,生成一个通常名为 .ninja_log 的日志文件。此文件是一个制表符分隔的文本文件,记录关于构建过程中执行的每个命令(构建步骤)的元数据。每个条目的关键信息包括开始时间(毫秒)、结束时间(毫秒)、restat mtime(毫秒)、构建步骤的主要输出文件路径以及命令本身的哈希值。该格式是版本化的,新版本偶尔添加字段。

常见场景: 此格式在以下情况下使用:

Perfetto 支持:

如何生成:

外部资源:

Android logcat 文本格式

描述: Android logcat 是用于访问来自 Android 系统级日志服务 logd 的消息的命令行工具。adb logcat 的文本输出是 Perfetto 可以导入的。此输出可以根据指定的格式化选项(例如,通过 adb logcat -v <format>)而有很大差异,但通常包括时间戳、日志优先级(Verbose、Debug、Info、Warn、Error、Fatal/Assert)、标识日志来源的 tag、进程 ID(PID)、通常是线程 ID(TID)以及日志消息本身。

常见场景: 你可能会在以下情况下处理文本 logcat 文件:

Perfetto 支持:

如何生成文本 Logcat 文件:

外部资源:

Android bugreport zip 格式(.zip)

描述: Android bugreport 是由 Android 设备生成的 .zip 存档,包含特定时间点来自 Android 设备的全面诊断信息快照。此存档捆绑了各种日志(如 logcat)、系统属性、进程信息、ANR 和崩溃的堆栈跟踪,以及重要的是系统 trace(通常是在现代 Android 版本上的 Perfetto trace)。它还包含详细的 dumpstate 输出,其中包括板级信息和特定服务转储,如 batterystats

常见场景: Bugreport zip 文件主要用于:

Perfetto 支持:

如何生成:

外部资源:

Fuchsia tracing 格式(.fxt)

描述: Fuchsia trace 格式(通常在 .fxt 文件中找到)是 Fuchsia 操作系统使用的二进制格式。它设计用于从用户空间组件和 Zircon 内核进行高性能、低开销的诊断信息记录。该格式具有紧凑、内存对齐的记录,并且是可扩展的,trace 数据通常直接写入 Zircon 虚拟机对象 (VMO) 以提高效率。

常见场景: 此格式主要在以下情况下遇到:

Perfetto 支持:

如何生成:

外部资源:

pprof 格式

描述: pprof 格式是一种基于 protocol buffer 的格式,用于存储 CPU profile 数据。pprof 是一个用于可视化和 profile profiling 数据的工具。它读取 profile.proto 格式的 profiling 样本集合,并生成报告以可视化和帮助profile 数据。它是为 Go 编程语言的 pprof profiler 开发的,但后来被许多其他语言的其他 profilers 广泛采用(例如 Python、C++、Rust 等)。

常见场景: Perfetto 用户遇到此格式的最常见原因是:

Perfetto 支持:

如何生成: 对于 Perfetto 用户最相关的生成路径涉及从 Go 程序收集 CPU profiles 或转换 perf.data 文件。

  1. 从 Go 程序收集 CPU profile: 你可以使用 runtime/pprof 包以编程方式收集 profile,或使用 net/http/pprof 包在运行的服务器上公开 profiling 端点。

    要从运行的服务器收集 profile,你可以使用 go tool pprof 命令:

    go tool pprof http://localhost:6060/debug/pprof/profile?seconds=30

    这将收集 30 秒的 CPU profile 并在 pprof 工具中打开它。然后你可以使用 pprof 工具中的 save 命令将 profile 保存到文件。

  2. 将 Linux perf.data 转换为 pprof 格式: 使用 perf_data_converter 包中的 perf_to_profile 工具。

    perf_to_profile -i perf.data -o perf.pprof

外部资源:

Collapsed Stack 格式

描述: Collapsed Stack 格式是一种简单的基于文本的格式,用于表示 profiling 数据,通常与 Brendan Gregg 的 FlameGraph 工具一起使用。每行包含一个分号分隔的栈跟踪(从根到叶),后跟一个空格和样本计数。此格式因其简单性而受欢迎,并且通常在用各种 profiling 源生成火焰图时用作中间格式。

格式规范:

frame1;frame2;frame3 count # 以 # 开头的行是注释

常见场景: 此格式通常在以下情况下使用:

Perfetto 支持:

如何生成:

最常见的生成路径涉及处理 perf 输出:

# 记录 profile sudo perf record -F 99 -g -- ./my_program # 转换为 collapsed stack 格式 perf script | stackcollapse-perf.pl > profile.collapsed # 在 Perfetto 中打开 # 导航到 ui.perfetto.dev 并上传 profile.collapsed

外部资源: