blob: 67e900e46bf13ad1ac9074f83f6fcf24099ad841 [file] [log] [blame] [view]
# UI Automation
This page covers how to automate common Perfetto UI tasks to speed up your
trace analysis workflow using commands, startup commands, and macros.
## Commands System Overview
### Commands
**Commands** are individual UI actions that can be triggered manually or
automatically. Examples include pinning tracks, running queries, or creating
debug tracks. Access commands through:
- Command palette: `Ctrl-Shift-P` (Windows/Linux) or `Cmd-Shift-P` (Mac)
- Omnibox: Type `>` to transform it into a command palette
- Commands support fuzzy matching and autocomplete
### Startup Commands
**Startup commands** run automatically every time you open any trace. Configure
them in **Settings > Startup Commands** to set up your preferred view
immediately. These affect only the UI display - the trace file itself is
unchanged.
#### JSON Schema
Startup commands must be a JSON array of command objects:
```typescript
[
{
"id": string, // Command identifier
"args": unknown[] // Array of arguments (types depend on the commands)
},
...
]
```
#### Notes
- Commands execute in the order specified
- Invalid JSON or unknown command IDs will cause errors
- These commands affect only the UI display - the trace file is unchanged
### Macros
**Macros** are named sequences of commands you trigger manually when needed.
Configure them in **Settings > Macros** and run them via the command palette
(`Ctrl-Shift-P` and then type `>macro name`). Use macros for analysis workflows
you run occasionally rather than always.
#### JSON Schema
Macros must be a JSON object with macro names as keys and command arrays as
values:
```typescript
{
"macro_name": [
{
"id": string, // Command identifier
"args": unknown[] // Array of arguments (types depend on the command)
},
...
],
...
}
```
#### Notes
- Macro names must be valid JSON string keys. Simple names without special
characters are recommended for easier use in the command palette.
- Run macros by typing `>macro name` in the command palette (e.g.,
`>CPU Analysis`)
- Commands in a macro execute sequentially
### Common Issues
- **JSON syntax errors**: Missing commas, trailing commas, or unescaped quotes
- **Invalid command IDs**: Use autocomplete in the command palette to find valid
IDs
- **Wrong argument types**: All arguments must be strings, even numbers
- **Wrong argument count**: Each command expects a specific number of arguments
## Startup Command Examples
### Pin important tracks automatically
Add this to **Settings > Startup Commands** to always pin CPU tracks when
opening traces:
```json
[
{
"id": "dev.perfetto.PinTracksByRegex",
"args": [".*CPU [0-3].*"]
}
]
```
This runs every time you open a trace, ensuring your most important tracks are
always visible.
### Create debug tracks for custom metrics
This startup command creates a debug track showing thread scheduling latency:
```json
[
{
"id": "dev.perfetto.AddDebugSliceTrack",
"args": [
"SELECT ts, thread.name as thread_name, dur as value FROM thread_state JOIN thread USING(utid) WHERE state = 'R' AND dur > 1000000",
"Long Scheduling Delays (>1ms)"
]
}
]
```
Debug tracks visualize SQL query results on the timeline. The query must return:
- `ts` (timestamp)
- For slice tracks: `dur` (duration)
- For counter tracks: `value` (the metric value)
- Optional pivot column. The query results will be grouped by the unique values
in this column, with each group appearing in its own track.
**Command argument patterns:**
- Without pivot: `AddDebugSliceTrack` - [query, title]
- With pivot: `AddDebugSliceTrackWithPivot` - [query, pivot_column, title]
### Standard analysis setup
This comprehensive startup configuration prepares the UI for system analysis:
```json
[
{
"id": "dev.perfetto.CollapseTracksByRegex",
"args": [".*"]
},
{
"id": "dev.perfetto.PinTracksByRegex",
"args": [".*CPU \\d+$"]
},
{
"id": "dev.perfetto.ExpandTracksByRegex",
"args": [".*freq.*"]
},
{
"id": "dev.perfetto.AddDebugSliceTrackWithPivot",
"args": [
"SELECT ts, blocked_function as name, dur as value FROM thread_state WHERE state = 'D' AND blocked_function IS NOT NULL",
"name",
"Blocking Functions"
]
}
]
```
## Macro Examples
### Focus on specific subsystem
Add this to **Settings > Macros** for analyzing memory when needed. This macro
creates a new workspace to isolate memory-related tracks from the main view:
```json
{
"Memory Analysis": [
{
"id": "dev.perfetto.CreateWorkspace",
"args": ["Memory Analysis"]
},
{
"id": "dev.perfetto.CopyTracksToWorkspaceByRegexWithAncestors",
"args": [".*mem.*|.*rss.*", "Memory Analysis"]
},
{
"id": "dev.perfetto.SwitchWorkspace",
"args": ["Memory Analysis"]
},
{
"id": "dev.perfetto.AddDebugCounterTrackWithPivot",
"args": [
"SELECT ts, process.name as process, value FROM counter JOIN process_counter_track ON counter.track_id = process_counter_track.id JOIN process USING (upid) WHERE counter.name = 'mem.rss' AND value > 50000000",
"process",
"High Memory Processes (>50MB)"
]
}
]
}
```
Run this macro by typing `>Memory Analysis` in the command palette when you need
to investigate memory issues.
### Latency investigation
This macro helps identify performance bottlenecks:
```json
{
"Find Latency": [
{
"id": "dev.perfetto.PinTracksByRegex",
"args": [".*CPU.*"]
},
{
"id": "dev.perfetto.RunQueryAndShowTab",
"args": [
"SELECT thread.name, COUNT(*) as blocks, SUM(dur)/1000000 as total_ms FROM thread_state JOIN thread USING(utid) WHERE state = 'D' GROUP BY thread.name ORDER BY total_ms DESC LIMIT 10"
]
},
{
"id": "dev.perfetto.AddDebugSliceTrackWithPivot",
"args": [
"SELECT ts, thread.name as thread_name, dur as value FROM thread_state JOIN thread USING (utid) WHERE state IN ('R', 'D+') AND dur > 5000000",
"thread_name",
"Long Waits (>5ms)"
]
}
]
}
```
## Combining with trace recording
When recording traces, you can specify startup commands that will execute when
the trace opens in the UI:
```bash
# These commands affect only the UI view when the trace opens from the script.
./record_android_trace \
--app com.example.app \
--ui-startup-commands '[
{"id":"dev.perfetto.PinTracksByRegex","args":[".*CPU.*"]},
{"id":"dev.perfetto.AddDebugSliceTrackWithPivot","args":["SELECT ts, thread.name as thread, dur as value FROM thread_state JOIN thread USING(utid) WHERE state = \"R\"","thread","Runnable Time"]}
]'
```
## Tips for effective automation
1. **Use startup commands for always-needed views**: If you always want certain
tracks pinned, use startup commands.
2. **Use macros for specific investigations**: Create macros for workflows you
run occasionally (memory analysis, latency hunting, etc.).
3. **Test interactively first**: Use the command palette (`Ctrl/Cmd+Shift+P`) to
test commands before adding to settings. Type commands to see available
options with autocomplete.
4. **Start clean**: Begin command sequences with `CollapseTracksByRegex` using
`".*"` to collapse all tracks first.
5. **Common regex patterns**:
- Escape dots in package names: `"com\\.example\\.app"`
- Match any digit: `\\d+`
- Match beginning/end: `^` and `$`
6. **Debug tracks need good queries**: Ensure your SQL returns `ts` and either
`dur` (for slices) or `value` (for counters) columns. Use the pivot commands
to split into multiple tracks. For Android use cases, see
[Android Trace Analysis Cookbook](/docs/getting-started/android-trace-analysis.md)
for examples of common queries used by Android engineers.
## See Also
- [Commands Automation Reference](/docs/visualization/commands-automation-reference.md) -
Complete reference for stable automation commands with backwards compatibility
guarantees
- [Perfetto UI Guide](/docs/visualization/perfetto-ui.md) - General UI
documentation including commands configuration
- [Deep Linking](/docs/visualization/deep-linking-to-perfetto-ui.md) - Opening
traces with pre-configured commands via URLs