美文网首页perfetto 官方文档翻译
Perfetto 翻译-核心概念-trace 配置

Perfetto 翻译-核心概念-trace 配置

作者: David_zhou | 来源:发表于2023-10-29 22:07 被阅读0次

    前言:虽然有翻译软件,虽然有chatgpt,毕竟语言隔阂,对这个工具还是一知半解,因此想通过翻译的方式和大家来一起学习下Perfetto这个强大的工具

    目录

    #####################以下分割线#####################
    英文原文在这里

    Trace configuration

    与许多始终在线的日志记录系统(例如 Linux 的 rsyslog、Android 的 logcat)不同,在 Perfetto 中,所有trace的数据源默认是关闭状态,并且仅在开关开启时才记录数据。

    当正在抓取一个(或多个)trace时,才会记录数据源的数据。通过调用 perfetto cmdline 客户端并传递配置来开始抓取(请参阅适用于 AndroidLinuxChrome on desktop 的快速入门指南)。

    一个简单的跟踪配置如下所示:

    duration_ms: 10000
    
    buffers {
      size_kb: 65536
      fill_policy: RING_BUFFER
    }
    
    data_sources {
      config {
        name: "linux.ftrace"
        target_buffer: 0
        ftrace_config {
          ftrace_events: "sched_switch"
          ftrace_events: "sched_wakeup"
        }
      }
    }
    

    其用法如下:

    perfetto --txt -c config.pbtx -o trace_file.perfetto-trace
    

    提示:可以在 的 repo 中找到 /test/configs/一些更完整的跟踪配置示例。

    TraceConfig
    trace_config.png
    Buffers

    缓冲区部分定义tracing service拥有的内存中缓冲区的数量、大小和策略。大体结构如下:

    # Buffer #0
    buffers {
      size_kb: 4096
      fill_policy: RING_BUFFER
    }
    
    # Buffer #1
    buffers {
      size_kb: 8192
      fill_policy: DISCARD
    }
    

    每个缓冲区都有一个填充策略,该策略是:

    • RING_BUFFER (默认): 缓冲区的行为类似于环形缓冲区,缓冲区满时最新的内容将替换缓冲区中最早的跟踪数据。
    • DISCARD: 缓冲区在数据满后停止接受数据。尝试写入的新数据将被丢弃。

    警告:对于在trace末尾提交数据的数据源,DISCARD 可能会产生意外的副作用。

    trace config必须至少定义一个缓冲区才能有效。在最简单的情况下,所有数据源都会将其跟踪数据写入同一缓冲区。

    虽然这适用于大多数情况,但在不同数据源以明显不同的速率写入的情况下,它可能会出现问题。
    例如,假设一个trace config同时支持:

    1. 内核调度程序跟踪器。在典型的 Android 手机上,这会记录 ~10000 个事件/秒,以 ~1 MB/s 的速度将trace数据写入缓冲区。
    2. 内存统计信息轮询。此数据源将 /proc/meminfo 的内容写入跟踪缓冲区,并配置为每 5 秒轮询一次,每个轮询间隔写入 约100 KB。

    如果两个数据源都配置为写入同一缓冲区,并且该缓冲区设置为 4MB, ,则大多数trace将仅包含一个内存快照。大多数跟踪很有可能根本不包含任何内存快照,即使第二个数据源工作正常。这是因为在 5 秒的轮询间隔内,调度程序数据源最终可能会填满整个缓冲区,导致内存快照数据没有机会写入缓冲区。

    动态缓冲区映射

    数据源<>缓冲区映射在 Perfetto 中是动态的。在最简单的情况下,跟踪会话只能定义一个缓冲区。默认情况下,所有数据源都会将数据记录到该缓冲区中。
    在上述示例中,最好将这些数据源分隔到不同的缓冲区中。这可以通过 TraceConfig target_buffer 的字段来实现。

    trace_config_buffer_mapping.png
    可以通过以下配置实现:
    data_sources {
      config {
        name: "linux.ftrace"
        target_buffer: 0       # <-- This goes into buffer 0.
        ftrace_config { ... }
      }
    }
    
    data_sources: {
      config {
          name: "linux.sys_stats"
          target_buffer: 1     # <-- This goes into buffer 1.
          sys_stats_config { ... }
      }
    }
    
    data_sources: {
      config {
        name: "android.heapprofd"
        target_buffer: 1       # <-- This goes into buffer 1 as well.
        heapprofd_config { ... }
      }
    }
    
    PBTX 与二进制格式

    使用 perfetto cmdline 客户端格式时,有两种方法可以传递trace config:

    文本格式

    它是人工驱动的工作流程和探索的首选格式。它允许直接以 PBTX(ProtoBuf TeXtual 表示)语法传递文本文件,用于 trace_config.proto中定义的模式(请参阅参考文档

    When using this mode pass the --txt flag to perfetto to indicate the config should be interpreted as a PBTX file: 使用此模式时,使用 --txt 参数表示应将配置解析为 PBTX 文件:

    <pre mdtype="fences" cid="n299" lang="" class="md-fences md-end-block ty-contain-cm modeLoaded" spellcheck="false" style="box-sizing: border-box; overflow: visible; font-family: Consolas, Menlo, Monaco, monospace, serif; font-size: 0.9rem; background-image: inherit; background-size: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: inherit; display: block; break-inside: avoid; text-align: left; white-space: normal; position: relative !important; margin-left: 1em; padding-left: 1em; border: 1px solid rgb(221, 221, 221); padding-bottom: 8px; padding-top: 6px; margin-bottom: 1.5em; width: inherit; background-position: inherit; background-repeat: inherit;">perfetto -c /path/to/config.pbtx --txt -o trace_file.perfetto-trace</pre>

    它是机器对机器 (M2M) 交互的首选格式。它将 TraceConfig 编码为 protobuf 二进制文件。这可以将 PBTX 作为输入传递给 protobuf protoc 的编译器(可在此处下载)获得。

    二进制格式

    警告:不要将文本格式用于机器对机器交互基准测试、脚本和工具),因为它更容易损坏(例如,如果字段被重命名或枚举被转换为整数)

    注意:该 --txt 选项仅在Android 10 (Q)中引入。旧版本仅支持二进制格式。

    cd ~/code/perfetto  # external/perfetto in the Android tree.protoc --encode=perfetto.protos.TraceConfig \        -I. protos/perfetto/config/perfetto_config.proto \        < config.txpb \        > config.bin
    

    然后将其传递给 perfetto,如下所示,不带 --txt 参数:

    perfetto -c config.bin -o trace_file.perfetto-trace
    
    
    流式处理长时间的trace

    默认情况下,Perfetto 将完整的跟踪缓冲区保留在内存中,并仅在trace结束时将其写入目标文件( -o cmdline 参数)。这是为了减少trace系统的性能侵入性。但是,这会将trace的最大大小限制为设备的物理内存大小,这通常是有限的。 在某些情况下(例如,基准测试、难以重现的案例),希望捕获比机器物理内存大得多的trace,虽然会带来额外的 I/O 开销。

    为了实现这一点,Perfetto 允许使用以下 TraceConfig 字段定期将跟踪缓冲区写入目标文件(或 stdout):

    • write_into_file (bool)`:如果为 true,则定期将trace缓冲区中的数据输入到输出文件中。启用此选项后,用户空间缓冲区需要足够大,以便在两个写入周期之间保存跟踪数据。缓冲区大小取决于设备的交互活动。典型trace的数据产生速率为 ~1-4 MB/s。因此,一个 16MB 的内存缓冲区可以保持 大约4 秒的写入周期,之后就会丢失数据。

    • file_write_period_ms (uint32)`:覆盖默认耗尽周期(5 秒)。较短的时间段需要的用户空间缓冲区会较小,但会增加跟踪的性能侵入性。如果给定的周期小于 100 毫秒,则跟踪服务将使用 100 毫秒的周期。

    • max_file_size_bytes (uint64):如果设置,则在写入 N 字节后停止trace 。用于限制跟踪的大小。

      有关长跟踪模式下工作跟踪配置的完整示例,请参见 /test/configs/long_trace.cfg.

    摘要:要捕获长跟踪,只需设置 ,设置 write_into_file:true 一个 long duration_ms 并使用 32MB 或更大的内存缓冲区大小。

    特定数据源的配置

    除了跟踪范围的配置参数外,trace config还可以定义特定于数据源的行为。在原型架构级别,这在以下 DataSourceConfig TraceConfig 部分中定义: 来自 data_source_config.proto:

    message TraceConfig {
      ...
      repeated DataSource data_sources = 2;  // See below.
    }
    
    message DataSource {
      optional protos.DataSourceConfig config = 1;  // See below.
      ...
    }
    
    message DataSourceConfig {
      optional string name = 1;
      ...
      optional FtraceConfig ftrace_config = 100 [lazy = true];
      ...
      optional AndroidPowerConfig android_power_config = 106 [lazy = true];
    }
    

    ftrace_config和android_power_config这样的字段是特定数据源配置的一个示范。tracing service将完全忽略这些字段的内容,并在其他地方也使用对应名字的DataSourceConfig对象(全局生效?) 该 [lazy=true] 标记在 protozero 生成器中具有特殊的含义。与标准嵌套消息不同,

    关于向后/向前兼容性的说明

    tracing service会将 DataSourceConfig 消息的原始二进制 blob 路由到名字匹配的数据源,而无需尝试对其进行解码和重新编码。如果跟踪配置 DataSourceConfig 的部分包含生成服务时不存在的新字段,则服务仍将传递 DataSourceConfig 到数据源。这允许引入新的数据源,而无需服务预先了解它们的任何信息。

    TODO:我们知道,今天使用自定义原型扩展需要 DataSourceConfig 更改 Perfetto 存储库 data_source_config.proto 中的 perfetto,这对于外部项目来说并不理想。长期计划是为非上游扩展保留一系列字段,并为客户端代码提供通用模板化访问器。在此之前,我们接受patches upstream,为您自己的数据源引入临时配置。

    多进程数据源

    某些数据源是单例的。例如,在 Perfetto 在 Android 上发布的调度程序tracing的情况下, traced_probes 整个系统只有数据源,由 traced_probes拥有。 但是,在一般情况下,多个进程可以播发同一数据源。例如,当使用 Perfetto SDK 进行用户态检测时,就是这种情况。 如果发生这种情况,则需要开始抓取trace时,在trace config中确定具体的数据来源。默认情况下,Perfetto 将要求发送该数据源的所有进程启动。

    在某些情况下,可能需要进一步将数据源的启用限制为特定进程(或一组进程)。这可以通过 producer_name_filterproducer_name_regex_filter .

    设置这些筛选器后,Perfetto tracing service将仅在与筛选器匹配的创建者子集中激活数据源。

    示范如下:

    buffers {
      size_kb: 4096
    }
    
    data_sources {
      config {
        name: "track_event"
      }
      # Enable the data source only on Chrome and Chrome canary.
      producer_name_filter: "com.android.chrome"
      producer_name_filter: "com.google.chrome.canary"
    }
    
    触发器

    在大多数条件下,跟踪会话的生命周期仅与 perfetto cmdline 客户端的调用命令匹配:跟踪数据记录在 TraceConfig 传递到 perfetto 时开始,并在已过 TraceConfig.duration_ms时或 cmdline 客户端终止时结束。

    Perfetto 支持基于触发器的启动或停止跟踪的模式。总体思路是在跟踪配置本身中声明:

    • 一组触发器,它们只是格式自由的字符串。

    • 给定触发器是否应导致跟踪启动或停止,以及启动/停止延迟。

    为什么要使用触发器?为什么不能在需要时启动 perfetto 或杀死 (SIGTERM) 它?所有这一切的基本原理是安全模型:在大多数 Perfetto 部署环境中(例如,在 Android 上),只有特权实体(例如 adb shell)可以配置/启动/停止跟踪。从这个意义上说,应用是无特权的,它们无法控制tracing。 触发器为非特权应用提供了一种以有限方式控制跟踪tracing生命周期的方法。概念模型为:

    • 特权消费者(请参阅服务模型),即通常被授权开始跟踪的实体(例如,Android 中的 adb shell),预先声明跟踪的可能触发器名称以及它们将执行的操作。

    • 非特权实体(任何随机应用进程)都可以激活这些触发器。非特权实体对触发器将做什么没有控制权,它们只传达事件发生了。

      可以通过 cmdline util 发出触发器信号

    /system/bin/trigger_perfetto "trigger_name"
    

    (或者也可以仅通过配置中的 activate_triggers: "trigger_name" 字段来启动独立trace抓取过程)

    有两种类型的触发器:

    启动触发器

    启动触发器可以仅在发生某些重大事件后激活tracing。传递具有 START_TRACING 触发器的跟踪配置会导致跟踪会话保持空闲状态(即不记录任何数据),直到触发器被触发或超过 trigger_timeout_ms 时被触发。

    trace_duration_ms 和有触发器的跟踪不能同时使用。

    配置示例:

    # If the "myapp_is_slow" is hit, the trace starts recording data and will be
    # stopped after 5s.
    trigger_config {
      trigger_mode: START_TRACING
      triggers {
        name: "myapp_is_slow"
        stop_delay_ms: 5000
      }
      # If no trigger is hit, the trace will end without having recorded any data
      # after 30s.
      trigger_timeout_ms: 30000
    }
    
    # The rest of the config is as usual.
    buffers { ... }
    data_sources { ... }
    
    停止触发器

    STOP_TRACING触发器允许在触发器触发时提前完成跟踪。在此模式下,调用 perfetto 客户端时,跟踪将立即启动(如在一般情况)。触发器发出提前结束信号。
    这可用于在飞行记录器模式下使用 perfetto。通过配置RING_BUFFERSTOP_TRACING 触发器中的缓冲区启动跟踪,跟踪将不断循环记录 ,知道检测到罪魁祸首事件时完成。对于根本原因在最近的事件(例如,应用检测到缓慢滚动或缺少帧)而言,这很关键。

    配置示例:

    # If no trigger is hit, the trace will end after 30s.
    trigger_timeout_ms: 30000
    
    # If the "missed_frame" is hit, the trace is stopped after 1s.
    trigger_config {
      trigger_mode: STOP_TRACING
      triggers {
        name: "missed_frame"
        stop_delay_ms: 1000
      }
    }
    
    # The rest of the config is as usual.
    buffers { ... }
    data_sources { ... }
    

    在 Android 上,有一些关于使用 adb shell的提示

    • Ctrl+C 通常会导致跟踪正常终止,在使用 adb shell perfetto 时并不支持,而仅在通过 adb shell 使用基于 PTY 的交互式会话时支持。
    • 在 Android 12 之前的非 root 设备上,由于 SELinux 规则限制性过强,配置只能作为 cat config | adb shell perfetto -c - (-: stdin) 传递。在 Android 12及之后的版本上, /data/misc/perfetto-configs 可用于存储配置。
    • O在 Android 10 之前的设备上,adb 无法直接拉取 /data/misc/perfetto-traces .使用adb shell cat /data/misc/perfetto-traces/trace > trace 解决这个限制。
      在 Android 10 之前的设备上,adb 无法直接拉取 /data/misc/perfetto-traces .用于 adb shell cat /data/misc/perfetto-traces/trace > trace 解决方法。
    • 捕获较长的跟踪时,例如在基准测试或 CI 的中,使用 PID=$(perfetto --background) 然后 kill $PID 停止。
    其他资源

    #####################以上分割线#####################

    后记:
    1 本次主要使用百度翻译,虽然被骂,但至少翻译这个工具降低了门槛。
    2 英文文档中的长难句真的是又长又难,基于百度的翻译,然后自己再调整下,水平实在有限。
    3 技术背景知识不够,有些专有名词不知道怎么翻译,也不知道百度翻译的是否准确,功夫在诗外。
    4 万事开头难,中间难不难,还不知道。中间的事后面再说,正确一天翻译一篇。
    5 虽然可能会有人不屑,但总要有人去做不起眼的小事。
    6 google 厉害,这个perfetto 工具也很厉害。君子善假于物也。
    7 工具的使用是最简单的入门,背后还有更多的东西值得学习。
    8 水平实在有限,闻过则喜,希望有更多的人反馈,期待更好的建议

    相关文章

      网友评论

        本文标题:Perfetto 翻译-核心概念-trace 配置

        本文链接:https://www.haomeiwen.com/subject/vynvidtx.html