blob: c4326e626b4ec59df0800374cabaeccbfdc5fdd6 [file] [log] [blame] [view]
Primiano Tuccia6624852020-05-21 19:12:50 +01001# Trace configuration
2
3Unlike many always-on logging systems (e.g. Linux's rsyslog, Android's logcat),
4in Perfetto all tracing data sources are idle by default and record data only
5when instructed to do so.
6
7Data sources record data only when one (or more) tracing sessions are active.
8A tracing session is started by invoking the `perfetto` cmdline client and
9passing a config (see QuickStart guide for
Violetta Fedotovad1a49282022-07-26 16:59:27 +000010[Android](/docs/quickstart/android-tracing.md),
11[Linux](/docs/quickstart/linux-tracing.md), or [Chrome on desktop](/docs/quickstart/chrome-tracing.md)).
Primiano Tuccia6624852020-05-21 19:12:50 +010012
13A simple trace config looks like this:
14
15```protobuf
16duration_ms: 10000
17
18buffers {
19 size_kb: 65536
20 fill_policy: RING_BUFFER
21}
22
23data_sources {
24 config {
25 name: "linux.ftrace"
26 target_buffer: 0
27 ftrace_config {
28 ftrace_events: "sched_switch"
29 ftrace_events: "sched_wakeup"
30 }
31 }
32}
33
34````
35
36And is used as follows:
37
38```bash
Carmen Jacksonaad2d912021-03-15 10:22:29 -070039perfetto --txt -c config.pbtx -o trace_file.perfetto-trace
Primiano Tuccia6624852020-05-21 19:12:50 +010040```
41
42TIP: Some more complete examples of trace configs can be found in the repo in
43[`/test/configs/`](/test/configs/).
44
Florian Mayer375af9a2021-04-13 20:21:08 +010045NOTE: If you are tracing on Android using adb and experiencing problems, see
46 [the Android section](#android) below.
47
Primiano Tuccia6624852020-05-21 19:12:50 +010048## TraceConfig
49
50The TraceConfig is a protobuf message
51([reference docs](/docs/reference/trace-config-proto.autogen)) that defines:
52
531. The general behavior of the whole tracing system, e.g.:
54 * The max duration of the trace.
55 * The number of in-memory buffers and their size.
56 * The max size of the output trace file.
57
582. Which data sources to enable and their configuration, e.g.:
59 * For the [kernel tracing data source](/docs/data-sources/cpu-scheduling.md)
60 , which ftrace events to enable.
61 * For the [heap profiler](/docs/data-sources/native-heap-profiler.md), the
62 target process name and sampling rate.
63
64 See the _data sources_ section of the docs for details on how to
65 configure the data sources bundled with Perfetto.
66
673. The `{data source} x {buffer}` mappings: which buffer each data
68 source should write into (see [buffers section](#buffers) below).
69
70The tracing service (`traced`) acts as a configuration dispatcher: it receives
71a config from the `perfetto` cmdline client (or any other
72[Consumer](/docs/concepts/service-model.md#consumer)) and forwards parts of the
73config to the various [Producers](/docs/concepts/service-model.md#producer)
74connected.
75
76When a tracing session is started by a consumer, the tracing service will:
77
78* Read the outer section of the TraceConfig (e.g. `duration_ms`, `buffers`) and
79 use that to determine its own behavior.
80* Read the list of data sources in the `data_sources` section. For each data
81 source listed in the config, if a corresponding name (`"linux.ftrace"` in the
82 example below) was registered, the service will ask the producer process to
83 start that data source, passing it the raw bytes of the
84 [`DataSourceConfig` subsection][dss] verbatim to the data source (See
85 backward/forward compat section below).
86
87![TraceConfig diagram](/docs/images/trace_config.png)
88
89[dss]: /docs/reference/trace-config-proto.autogen#DataSourceConfig
90
91## Buffers
92
93The buffer sections define the number, size and policy of the in-memory buffers
94owned by the tracing service. It looks as follows:
95
96```protobuf
Daniele Di Proietto436b3262022-11-30 10:13:29 +000097# Buffer #0
Primiano Tuccia6624852020-05-21 19:12:50 +010098buffers {
99 size_kb: 4096
100 fill_policy: RING_BUFFER
101}
102
Daniele Di Proietto436b3262022-11-30 10:13:29 +0000103# Buffer #1
Primiano Tuccia6624852020-05-21 19:12:50 +0100104buffers {
105 size_kb: 8192
106 fill_policy: DISCARD
107}
108```
109
110Each buffer has a fill policy which is either:
111
112* RING_BUFFER (default): the buffer behaves like a ring buffer and writes when
113 full will wrap over and replace the oldest trace data in the buffer.
114
115* DISCARD: the buffer stops accepting data once full. Further write attempts are
116 dropped.
117
118WARNING: DISCARD can have unexpected side-effect with data sources that commit
119data at the end of the trace.
120
121A trace config must define at least one buffer to be valid. In the simplest case
122all data sources will write their trace data into the same buffer.
123
124 While this is
125fine for most basic cases, it can be problematic in cases where different data
126sources write at significantly different rates.
127
128For instance, imagine a trace config that enables both:
129
1301. The kernel scheduler tracer. On a typical Android phone this records
131 ~10000 events/second, writing ~1 MB/s of trace data into the buffer.
132
1332. Memory stat polling. This data source writes the contents of /proc/meminfo
134 into the trace buffer and is configured to poll every 5 seconds, writing
135 ~100 KB per poll interval.
136
137If both data sources are configured to write into the same buffer and such
138buffer is set to 4MB, most traces will contain only one memory snapshot. There
139are very good chances that most traces won't contain any memory snapshot at all,
140even if the 2nd data sources was working perfectly.
141This is because during the 5 s. polling interval, the scheduler data source can
142end up filling the whole buffer, pushing the memory snapshot data out of the
143buffer.
144
145## Dynamic buffer mapping
146
147Data-source <> buffer mappings are dynamic in Perfetto.
148In the simplest case a tracing session can define only one buffer. By default,
149all data sources will record data into that one buffer.
150
151In cases like the example above, it might be preferable separating these data
152sources into different buffers.
153This can be achieved with the `target_buffer` field of the TraceConfig.
154
155![Buffer mapping](/docs/images/trace_config_buffer_mapping.png)
156
157Can be achieved with:
158
159```protobuf
160data_sources {
161 config {
162 name: "linux.ftrace"
Daniele Di Proietto436b3262022-11-30 10:13:29 +0000163 target_buffer: 0 # <-- This goes into buffer 0.
Primiano Tuccia6624852020-05-21 19:12:50 +0100164 ftrace_config { ... }
165 }
166}
167
168data_sources: {
169 config {
170 name: "linux.sys_stats"
Daniele Di Proietto436b3262022-11-30 10:13:29 +0000171 target_buffer: 1 # <-- This goes into buffer 1.
Primiano Tuccia6624852020-05-21 19:12:50 +0100172 sys_stats_config { ... }
173 }
174}
175
176data_sources: {
177 config {
178 name: "android.heapprofd"
Daniele Di Proietto436b3262022-11-30 10:13:29 +0000179 target_buffer: 1 # <-- This goes into buffer 1 as well.
Primiano Tuccia6624852020-05-21 19:12:50 +0100180 heapprofd_config { ... }
181 }
182}
183```
184
185## PBTX vs binary format
186
187There are two ways to pass the trace config when using the `perfetto` cmdline
188client format:
189
190#### Text format
191
192It is the preferred format for human-driven workflows and exploration. It
193allows to pass directly the text file in the PBTX (ProtoBuf TeXtual
194representation) syntax, for the schema defined in the
195[trace_config.proto](/protos/perfetto/config/trace_config.proto)
196(see [reference docs](/docs/reference/trace-config-proto.autogen))
197
198When using this mode pass the `--txt` flag to `perfetto` to indicate the config
199should be interpreted as a PBTX file:
200
201```bash
Carmen Jacksonaad2d912021-03-15 10:22:29 -0700202perfetto -c /path/to/config.pbtx --txt -o trace_file.perfetto-trace
Primiano Tuccia6624852020-05-21 19:12:50 +0100203```
204
205NOTE: The `--txt` option has been introduced only in Android 10 (Q). Older
206versions support only the binary format.
207
208WARNING: Do not use the text format for machine-to-machine interaction
209benchmark, scripts and tools) as it's more prone to breakages (e.g. if a field
210is renamed or an enum is turned into an integer)
211
212#### Binary format
213
214It is the preferred format for machine-to-machine (M2M) interaction. It involves
215passing the protobuf-encoded binary of the TraceConfig message.
216This can be obtained passing the PBTX in input to the protobuf's `protoc`
217compiler (which can be downloaded
218[here](https://github.com/protocolbuffers/protobuf/releases)).
219
220```bash
221cd ~/code/perfetto # external/perfetto in the Android tree.
222
223protoc --encode=perfetto.protos.TraceConfig \
224 -I. protos/perfetto/config/perfetto_config.proto \
225 < config.txpb \
226 > config.bin
227```
228
229and then passing it to perfetto as follows, without the `--txt` argument:
230
231```bash
Carmen Jacksonaad2d912021-03-15 10:22:29 -0700232perfetto -c config.bin -o trace_file.perfetto-trace
Primiano Tuccia6624852020-05-21 19:12:50 +0100233```
234
235## {#long-traces} Streaming long traces
236
237By default Perfetto keeps the full trace buffer(s) in memory and writes it into
238the destination file (the `-o` cmdline argument) only at the end of the tracing
239session. This is to reduce the perf-intrusiveness of the tracing system.
240This, however, limits the max size of the trace to the physical memory size of
241the device, which is often too limiting.
242
243In some cases (e.g., benchmarks, hard to repro cases) it is desirable to capture
244traces that are way larger than that, at the cost of extra I/O overhead.
245
246To achieve that, Perfetto allows to periodically write the trace buffers into
247the target file (or stdout) using the following TraceConfig fields:
248
249* `write_into_file (bool)`:
250When true periodically drains the trace buffers into the output
251file. When this option is enabled, the userspace buffers need to be just
252big enough to hold tracing data between two write periods.
253The buffer sizing depends on the activity of the device.
254The data rate of a typical trace is ~1-4 MB/s. So a 16MB in-memory buffer can
255hold for up write periods of ~4 seconds before starting to lose data.
256
257* `file_write_period_ms (uint32)`:
258Overrides the default drain period (5s). Shorter periods require a smaller
259userspace buffer but increase the performance intrusiveness of tracing. If
260the period given is less than 100ms, the tracing service will use a period
261of 100ms.
262
263* `max_file_size_bytes (uint64)`:
264If set, stops the tracing session after N bytes have been written. Used to
265cap the size of the trace.
266
267For a complete example of a working trace config in long-tracing mode see
268[`/test/configs/long_trace.cfg`](/test/configs/long_trace.cfg).
269
270Summary: to capture a long trace just set `write_into_file:true`, set a long
271 `duration_ms` and use an in-memory buffer size of 32MB or more.
272
273## Data-source specific config
274
275Alongside the trace-wide configuration parameters, the trace config also defines
276data-source-specific behaviors. At the proto schema level, this is defined in
277the `DataSourceConfig` section of `TraceConfig`:
278
279From [data_source_config.proto](/protos/perfetto/config/data_source_config.proto):
280
281```protobuf
282message TraceConfig {
283 ...
284 repeated DataSource data_sources = 2; // See below.
285}
286
287message DataSource {
288 optional protos.DataSourceConfig config = 1; // See below.
289 ...
290}
291
292message DataSourceConfig {
293 optional string name = 1;
294 ...
295 optional FtraceConfig ftrace_config = 100 [lazy = true];
296 ...
297 optional AndroidPowerConfig android_power_config = 106 [lazy = true];
298}
299```
300
301Fields like `ftrace_config`, `android_power_config` are examples of data-source
302specific configs. The tracing service will completely ignore the contents of
303those fields and route the whole DataSourceConfig object to any data source
304registered with the same name.
305
306The `[lazy=true]` marker has a special implication in the
307[protozero](/docs/design-docs/protozero.md) code generator. Unlike standard
308nested messages, it generates raw accessors (e.g.,
309`const std::string& ftrace_config_raw()` instead of
310`const protos::FtraceConfig& ftrace_config()`). This is to avoid injecting too
311many `#include` dependencies and avoiding binary size bloat in the code that
312implements data sources.
313
314#### A note on backwards/forward compatibility
315The tracing service will route the raw binary blob of the `DataSourceConfig`
316message to the data sources with a matching name, without attempting to decode
317and re-encode it. If the `DataSourceConfig` section of the trace config contains
318a new field that didn't exist at the time when the service was built, the
319service will still pass the `DataSourceConfig` through to the data source.
320This allows to introduced new data sources without needing the service to
321know anything about them upfront.
322
323TODO: we are aware of the fact that today extending the `DataSourceConfig` with
324a custom proto requires changing the `data_source_config.proto` in the Perfetto
325repo, which is unideal for external projects. The long-term plan is to reserve
326a range of fields for non-upstream extensions and provide generic templated
327accessors for client code. Until then, we accept patches upstream to introduce
328ad-hoc configurations for your own data sources.
329
330## Multi-process data sources
331
332Some data sources are singletons. E.g., in the case of scheduler tracing that
333Perfetto ships on Android, there is only data source for the whole system,
334owned by the `traced_probes` service.
335
336However, in the general case multiple processes can advertise the same data
337source. This is the case, for instance, when using the
338[Perfetto SDK](/docs/instrumentation/tracing-sdk.md) for userspace
339instrumentation.
340
341If this happens, when starting a tracing session that specifies that data
342source in the trace config, Perfetto by default will ask all processes that
343advertise that data source to start it.
344
345In some cases it might be desirable to further limit the enabling of the data
346source to a specific process (or set of processes). That is possible through the
347`producer_name_filter` and `producer_name_regex_filter`.
348
349NOTE: the typical Perfetto run-time model is: one process == one Perfetto
350 Producer; one Producer typically hosts multiple data sources.
351
352When those filters are set, the Perfetto tracing service will activate the data
353source only in the subset of producers matching the filter.
354
355Example:
356
357```protobuf
358buffers {
359 size_kb: 4096
360}
361
362data_sources {
363 config {
364 name: "track_event"
Primiano Tuccia6624852020-05-21 19:12:50 +0100365 }
Primiano Tucciab7210b2020-06-25 09:46:16 +0100366 # Enable the data source only on Chrome and Chrome canary.
367 producer_name_filter: "com.android.chrome"
368 producer_name_filter: "com.google.chrome.canary"
Primiano Tuccia6624852020-05-21 19:12:50 +0100369}
370```
371
372## Triggers
373
374In nominal conditions, a tracing session has a lifecycle that simply matches the
375invocation of the `perfetto` cmdline client: trace data recording starts when
376the TraceConfig is passed to `perfetto` and ends when either the
377`TraceConfig.duration_ms` has elapsed, or when the cmdline client terminates.
378
379Perfetto supports an alternative mode of either starting or stopping the trace
380which is based on triggers. The overall idea is to declare in the trace config
381itself:
382
383* A set of triggers, which are just free-form strings.
384* Whether a given trigger should cause the trace to be started or stopped, and
385 the start/stop delay.
386
387Why using triggers? Why can't one just start perfetto or kill(SIGTERM) it when
388needed? The rationale of all this is the security model: in most Perfetto
389deployments (e.g., on Android) only privileged entities (e.g., adb shell) can
390configure/start/stop tracing. Apps are unprivileged in this sense and they
391cannot control tracing.
392
393Triggers offer a way to unprivileged apps to control, in a limited fashion, the
394lifecycle of a tracing session. The conceptual model is:
395
396* The privileged Consumer (see
397 [_Service model_](/docs/concepts/service-model.md)), i.e. the entity
398 that is normally authorized to start tracing (e.g., adb shell in Android),
399 declares upfront what are the possible trigger names for the trace and what
400 they will do.
401* Unprivileged entities (any random app process) can activate those triggers.
402 Unprivileged entities don't get a say on what the triggers will do, they only
403 communicate that an event happened.
404
405Triggers can be signaled via the cmdline util
406
407```bash
408/system/bin/trigger_perfetto "trigger_name"
409```
410
411(or also by starting an independent trace session which uses only the
412`activate_triggers: "trigger_name"` field in the config)
413
414There are two types of triggers:
415
416#### Start triggers
417
418Start triggers allow activating a tracing session only after some significant
419event has happened. Passing a trace config that has `START_TRACING` trigger
420causes the tracing session to stay idle (i.e. not recording any data) until either
Hector Dearmanaa4b23b2020-10-30 13:32:51 +0000421the trigger is hit or the `trigger_timeout_ms` timeout is hit.
422
423`trace_duration_ms` and triggered traces can not be used at the same time.
Primiano Tuccia6624852020-05-21 19:12:50 +0100424
425Example config:
426```protobuf
Hector Dearmanaa4b23b2020-10-30 13:32:51 +0000427# If the "myapp_is_slow" is hit, the trace starts recording data and will be
428# stopped after 5s.
Primiano Tuccia6624852020-05-21 19:12:50 +0100429trigger_config {
430 trigger_mode: START_TRACING
431 triggers {
432 name: "myapp_is_slow"
433 stop_delay_ms: 5000
434 }
Lalit Maganti4b076e12021-08-23 13:22:47 +0100435 # If no trigger is hit, the trace will end without having recorded any data
436 # after 30s.
437 trigger_timeout_ms: 30000
Primiano Tuccia6624852020-05-21 19:12:50 +0100438}
439
Hector Dearmanaa4b23b2020-10-30 13:32:51 +0000440# The rest of the config is as usual.
Primiano Tuccia6624852020-05-21 19:12:50 +0100441buffers { ... }
442data_sources { ... }
443```
444
445#### Stop triggers
446
447STOP_TRACING triggers allow to prematurely finalize a trace when the trigger is
448hit. In this mode the trace starts immediately when the `perfetto` client is
449invoked (like in nominal cases). The trigger acts as a premature finalization
450signal.
451
452This can be used to use perfetto in flight-recorder mode. By starting a trace
453with buffers configured in `RING_BUFFER` mode and `STOP_TRACING` triggers,
454the trace will be recorded in a loop and finalized when the culprit event is
455detected. This is key for events where the root cause is in the recent past
456(e.g., the app detects a slow scroll or a missing frame).
457
458Example config:
459```protobuf
Hector Dearmanaa4b23b2020-10-30 13:32:51 +0000460# If no trigger is hit, the trace will end after 30s.
461trigger_timeout_ms: 30000
Primiano Tuccia6624852020-05-21 19:12:50 +0100462
Hector Dearmanaa4b23b2020-10-30 13:32:51 +0000463# If the "missed_frame" is hit, the trace is stopped after 1s.
Primiano Tuccia6624852020-05-21 19:12:50 +0100464trigger_config {
465 trigger_mode: STOP_TRACING
466 triggers {
467 name: "missed_frame"
468 stop_delay_ms: 1000
469 }
470}
471
Hector Dearmanaa4b23b2020-10-30 13:32:51 +0000472# The rest of the config is as usual.
Primiano Tuccia6624852020-05-21 19:12:50 +0100473buffers { ... }
474data_sources { ... }
475```
476
Florian Mayer375af9a2021-04-13 20:21:08 +0100477## Android
478
479On Android, there are some caveats around using `adb shell`
480
481* Ctrl+C, which normally causes a graceful termination of the trace, is not
482 propagated by ADB when using `adb shell perfetto` but only when using an
483 interactive PTY-based session via `adb shell`.
484* On non-rooted devices before Android 12, the config can only be passed as
485 `cat config | adb shell perfetto -c -` (-: stdin) because of over-restrictive
486 SELinux rules. Since Android 12 `/data/misc/perfetto-configs` can be used for
487 storing configs.
488* On devices before Android 10, adb cannot directly pull
489 `/data/misc/perfetto-traces`. Use
490 `adb shell cat /data/misc/perfetto-traces/trace > trace` to work around.
491* When capturing longer traces, e.g. in the context of benchmarks or CI, use
492 `PID=$(perfetto --background)` and then `kill $PID` to stop.
493
494
Primiano Tuccia6624852020-05-21 19:12:50 +0100495## Other resources
496
497* [TraceConfig Reference](/docs/reference/trace-config-proto.autogen)
498* [Buffers and dataflow](/docs/concepts/buffers.md)