Primiano Tucci | a662485 | 2020-05-21 19:12:50 +0100 | [diff] [blame] | 1 | # Common tasks |
| 2 | |
| 3 | The checklists below show how to achieve some common tasks in the codebase. |
| 4 | |
| 5 | ## Add a new ftrace event |
| 6 | |
| 7 | 1. Find the `format` file for your event. The location of the file depends where `tracefs` is mounted but can often be found at `/sys/kernel/debug/tracing/events/EVENT_GROUP/EVENT_NAME/format`. |
| 8 | 2. Copy the format file into the codebase at `src/traced/probes/ftrace/test/data/synthetic/events/EVENT_GROUP/EVENT_NAME/format`. |
Hector Dearman | 3ead0a7 | 2022-05-30 17:22:10 +0100 | [diff] [blame] | 9 | 3. Add the event to [src/tools/ftrace_proto_gen/event_list](/src/tools/ftrace_proto_gen/event_list). |
Primiano Tucci | a662485 | 2020-05-21 19:12:50 +0100 | [diff] [blame] | 10 | 4. Run `tools/run_ftrace_proto_gen`. This will update `protos/perfetto/trace/ftrace/ftrace_event.proto` and `protos/perfetto/trace/ftrace/GROUP_NAME.proto`. |
| 11 | 5. Run `tools/gen_all out/YOUR_BUILD_DIRECTORY`. This will update `src/traced/probes/ftrace/event_info.cc` and `protos/perfetto/trace/perfetto_trace.proto`. |
| 12 | 6. If special handling in `trace_processor` is desired update [src/trace_processor/importers/ftrace/ftrace_parser.cc](/src/trace_processor/importers/ftrace/ftrace_parser.cc) to parse the event. |
| 13 | 7. Upload and land your change as normal. |
| 14 | |
| 15 | Here is an [example change](https://android-review.googlesource.com/c/platform/external/perfetto/+/1290645) which added the `ion/ion_stat` event. |
| 16 | |
Anna Mayzner | 73c0671 | 2022-12-12 13:56:14 +0000 | [diff] [blame] | 17 | ## Contribute to SQL standard library |
| 18 | |
Anna Mayzner | fee912c | 2024-03-22 11:50:22 +0000 | [diff] [blame] | 19 | 1. Add or edit an SQL file inside `perfetto/src/trace_processor/stdlib/`. This SQL file will be a new standard library module. |
| 20 | 2. For a new file inside an existing package add the file to the corresponding `BUILD.gn`. |
| 21 | 3. For a new package (subdirectory of `/stdlib/`), the package name (directory name) has to be added to the list in `/stdlib/BUILD.gn`. |
Anna Mayzner | 73c0671 | 2022-12-12 13:56:14 +0000 | [diff] [blame] | 22 | |
| 23 | Files inside the standard library have to be formatted in a very specific way, as its structure is used to generate documentation. There are presubmit checks, but they are not infallible. |
| 24 | |
Anna Mayzner | fee912c | 2024-03-22 11:50:22 +0000 | [diff] [blame] | 25 | - Running the file cannot generate any data. There can be only `CREATE PERFETTO {FUNCTION|TABLE|VIEW|MACRO}` statements inside. |
| 26 | - The name of each standard library object needs to start with `{module_name}_` or be prefixed with an underscore(`_`) for internal objects. |
| 27 | The names must only contain lower and upper case letters and underscores. When a module is included (using the `INCLUDE PERFETTO MODULE`) the internal objects should not be treated as an API. |
Alexander Timin | dd0cda8 | 2023-11-06 14:26:53 +0000 | [diff] [blame] | 28 | - Every table or view should have [a schema](/docs/analysis/perfetto-sql-syntax.md#tableview-schema). |
Anna Mayzner | fee912c | 2024-03-22 11:50:22 +0000 | [diff] [blame] | 29 | |
| 30 | ### Documentation |
| 31 | |
Alexander Timin | dd0cda8 | 2023-11-06 14:26:53 +0000 | [diff] [blame] | 32 | - Every non internal object, as well as its function arguments and columns in its schema have to be prefixed with an SQL comment documenting it. |
Anna Mayzner | fee912c | 2024-03-22 11:50:22 +0000 | [diff] [blame] | 33 | - Any text is going to be parsed as markdown, so usage of markdown functionality (code, links, lists) is encouraged. |
| 34 | Whitespaces in anything apart from descriptions are ignored, so comments can be formatted neatly. |
| 35 | If the line with description exceeds 80 chars, description can be continued in following lines. |
Alexander Timin | dd0cda8 | 2023-11-06 14:26:53 +0000 | [diff] [blame] | 36 | - **Table/view**: each has to have schema, object description and a comment above each column's definition in the schema. |
| 37 | - Description is any text in the comment above `CREATE PERFETTO {TABLE,VIEW}` statement. |
| 38 | - Column's comment is the text immediately above column definition in the schema. |
| 39 | - **Scalar Functions**: each has to have a function description and description of return value in this order. |
| 40 | - Function description is any text in the comment above `CREATE PERFETTO FUNCTION` statement. |
| 41 | - For each argument there has to be a comment line immediately above argument definition. |
| 42 | - Return comment should immediately precede `RETURNS`. |
Lalit Maganti | 240a5c0 | 2023-09-25 19:24:26 +0100 | [diff] [blame] | 43 | - **Table Functions**: each has to have a function description, list of arguments (names, types, description) and list of columns. |
Alexander Timin | dd0cda8 | 2023-11-06 14:26:53 +0000 | [diff] [blame] | 44 | - Function description is any text in the comment above `CREATE PERFETTO FUNCTION` statement. |
| 45 | - For each argument there has to be a comment line immediately above argument definition. |
| 46 | - For each column there has to be a comment line immediately above column definition. |
Anna Mayzner | 7f600c4 | 2022-12-15 18:54:17 +0000 | [diff] [blame] | 47 | |
| 48 | NOTE: Break lines outside of import description will be ignored. |
Anna Mayzner | 73c0671 | 2022-12-12 13:56:14 +0000 | [diff] [blame] | 49 | |
| 50 | Example of properly formatted view in module `android`: |
| 51 | ```sql |
| 52 | -- Count Binder transactions per process. |
Alexander Timin | dd0cda8 | 2023-11-06 14:26:53 +0000 | [diff] [blame] | 53 | CREATE PERFETTO VIEW android_binder_metrics_by_process( |
| 54 | -- Name of the process that started the binder transaction. |
| 55 | process_name STRING, |
| 56 | -- PID of the process that started the binder transaction. |
| 57 | pid INT, |
| 58 | -- Name of the slice with binder transaction. |
| 59 | slice_name STRING, |
| 60 | -- Number of binder transactions in process in slice. |
| 61 | event_count INT |
| 62 | ) AS |
Anna Mayzner | 73c0671 | 2022-12-12 13:56:14 +0000 | [diff] [blame] | 63 | SELECT |
| 64 | process.name AS process_name, |
| 65 | process.pid AS pid, |
| 66 | slice.name AS slice_name, |
| 67 | COUNT(*) AS event_count |
| 68 | FROM slice |
Anna Mayzner | fee912c | 2024-03-22 11:50:22 +0000 | [diff] [blame] | 69 | JOIN thread_track ON slice.track_id = thread_track.id |
| 70 | JOIN thread ON thread.utid = thread_track.utid |
| 71 | JOIN process ON thread.upid = process.upid |
Anna Mayzner | 73c0671 | 2022-12-12 13:56:14 +0000 | [diff] [blame] | 72 | WHERE |
| 73 | slice.name GLOB 'binder*' |
| 74 | GROUP BY |
| 75 | process_name, |
| 76 | slice_name; |
| 77 | ``` |
| 78 | |
Lalit Maganti | 240a5c0 | 2023-09-25 19:24:26 +0100 | [diff] [blame] | 79 | Example of table function in module `android`: |
Anna Mayzner | 7f600c4 | 2022-12-15 18:54:17 +0000 | [diff] [blame] | 80 | ```sql |
| 81 | -- Given a launch id and GLOB for a slice name, returns columns for matching slices. |
Lalit Maganti | 240a5c0 | 2023-09-25 19:24:26 +0100 | [diff] [blame] | 82 | CREATE PERFETTO FUNCTION ANDROID_SLICES_FOR_LAUNCH_AND_SLICE_NAME( |
Alexander Timin | dd0cda8 | 2023-11-06 14:26:53 +0000 | [diff] [blame] | 83 | -- Id of launch. |
Lalit Maganti | 240a5c0 | 2023-09-25 19:24:26 +0100 | [diff] [blame] | 84 | launch_id INT, |
Alexander Timin | dd0cda8 | 2023-11-06 14:26:53 +0000 | [diff] [blame] | 85 | -- Name of slice with launch. |
Lalit Maganti | 240a5c0 | 2023-09-25 19:24:26 +0100 | [diff] [blame] | 86 | slice_name STRING |
| 87 | ) |
| 88 | RETURNS TABLE( |
Alexander Timin | dd0cda8 | 2023-11-06 14:26:53 +0000 | [diff] [blame] | 89 | -- Name of slice with launch. |
Lalit Maganti | 240a5c0 | 2023-09-25 19:24:26 +0100 | [diff] [blame] | 90 | slice_name STRING, |
Alexander Timin | dd0cda8 | 2023-11-06 14:26:53 +0000 | [diff] [blame] | 91 | -- Timestamp of slice start. |
Lalit Maganti | 240a5c0 | 2023-09-25 19:24:26 +0100 | [diff] [blame] | 92 | slice_ts INT, |
Alexander Timin | dd0cda8 | 2023-11-06 14:26:53 +0000 | [diff] [blame] | 93 | -- Duration of slice. |
Lalit Maganti | 240a5c0 | 2023-09-25 19:24:26 +0100 | [diff] [blame] | 94 | slice_dur INT, |
Alexander Timin | dd0cda8 | 2023-11-06 14:26:53 +0000 | [diff] [blame] | 95 | -- Name of thread with slice. |
Lalit Maganti | 240a5c0 | 2023-09-25 19:24:26 +0100 | [diff] [blame] | 96 | thread_name STRING, |
Alexander Timin | dd0cda8 | 2023-11-06 14:26:53 +0000 | [diff] [blame] | 97 | -- Arg set id. |
Lalit Maganti | 240a5c0 | 2023-09-25 19:24:26 +0100 | [diff] [blame] | 98 | arg_set_id INT |
| 99 | ) |
| 100 | AS |
Anna Mayzner | fee912c | 2024-03-22 11:50:22 +0000 | [diff] [blame] | 101 | SELECT |
| 102 | slice_name, |
| 103 | slice_ts, |
| 104 | slice_dur, |
| 105 | thread_name, |
| 106 | arg_set_id |
Lalit Maganti | 240a5c0 | 2023-09-25 19:24:26 +0100 | [diff] [blame] | 107 | FROM thread_slices_for_all_launches |
| 108 | WHERE launch_id = $launch_id AND slice_name GLOB $slice_name; |
Anna Mayzner | 7f600c4 | 2022-12-15 18:54:17 +0000 | [diff] [blame] | 109 | ``` |
| 110 | |
Anna Mayzner | 73c0671 | 2022-12-12 13:56:14 +0000 | [diff] [blame] | 111 | |
Primiano Tucci | a662485 | 2020-05-21 19:12:50 +0100 | [diff] [blame] | 112 | ## {#new-metric} Add a new trace-based metric |
| 113 | |
| 114 | 1. Create the proto file containing the metric in the [protos/perfetto/metrics](/protos/perfetto/metrics) folder. The appropriate` BUILD.gn` file should be updated as well. |
| 115 | 2. Import the proto in [protos/perfetto/metrics/metrics.proto](/protos/perfetto/metrics/metrics.proto) and add a field for the new message. |
| 116 | 3. Run `tools/gen_all out/YOUR_BUILD_DIRECTORY`. This will update the generated headers containing the descriptors for the proto. |
| 117 | * *Note: this step has to be performed any time any metric-related proto is modified.* |
Anna Mayzner | bc1f85c | 2022-09-15 14:20:52 +0000 | [diff] [blame] | 118 | * If you don't see anything inside the `out/` directory you might have to |
Anna Mayzner | 5089d22 | 2022-11-07 16:25:55 +0000 | [diff] [blame] | 119 | rerun `tools/setup_all_configs.py`. |
Primiano Tucci | a662485 | 2020-05-21 19:12:50 +0100 | [diff] [blame] | 120 | 4. Add a new SQL file for the metric to [src/trace_processor/metrics](/src/trace_processor/metrics). The appropriate `BUILD.gn` file should be updated as well. |
| 121 | * To learn how to write new metrics, see the [trace-based metrics documentation](/docs/analysis/metrics.md). |
| 122 | 5. Build all targets in your out directory with `tools/ninja -C out/YOUR_BUILD_DIRECTORY`. |
Lalit Maganti | a951d3d | 2020-07-16 23:57:00 +0100 | [diff] [blame] | 123 | 6. Add a new diff test for the metric. This can be done by adding files to |
Anna Mayzner | b392a08 | 2023-01-25 12:31:21 +0000 | [diff] [blame] | 124 | the `tests.*.py` files in a proper [test/trace_processor](/test/trace_processor) subfolder. |
| 125 | 1. Run the newly added test with `tools/diff_test_trace_processor.py <path to trace processor binary>`. |
| 126 | 2. Upload and land your change as normal. |
Primiano Tucci | a662485 | 2020-05-21 19:12:50 +0100 | [diff] [blame] | 127 | |
| 128 | Here is an [example change](https://android-review.googlesource.com/c/platform/external/perfetto/+/1290643) which added the `time_in_state` metric. |
| 129 | |
| 130 | ## Add a new trace processor table |
| 131 | |
| 132 | 1. Create the new table in the appropriate header file in [src/trace_processor/tables](/src/trace_processor/tables) by copying one of the existing macro definitions. |
| 133 | * Make sure to understand whether a root or derived table is needed and copy the appropriate one. For more information see the [trace processor](/docs/analysis/trace-processor.md) documentation. |
| 134 | 2. Register the table with the trace processor in the constructor for the [TraceProcessorImpl class](/src/trace_processor/trace_processor_impl.cc). |
| 135 | 3. If also implementing ingestion of events into the table: |
| 136 | 1. Modify the appropriate parser class in [src/trace_processor/importers](/src/trace_processor/importers) and add the code to add rows to the newly added table. |
Anna Mayzner | a91f0f8 | 2023-03-02 16:22:10 +0000 | [diff] [blame] | 137 | 2. Add a new diff test for the added parsing code and table. |
| 138 | 3. Run the newly added test with `tools/diff_test_trace_processor.py <path to trace processor shell binary>`. |
Primiano Tucci | a662485 | 2020-05-21 19:12:50 +0100 | [diff] [blame] | 139 | 4. Upload and land your change as normal. |
| 140 | |
Hector Dearman | f7296c0 | 2023-05-21 11:44:06 +0100 | [diff] [blame] | 141 | |
| 142 | ## Update `TRACE_PROCESSOR_CURRENT_API_VERSION` |
| 143 | |
| 144 | Generally you do not have to worry about version skew between the UI |
| 145 | and the `trace_processor` since they are built together at the same |
| 146 | commit. However version skew can occur when using the `--httpd` mode |
| 147 | which allows a native `trace_processor` instance to be used with the UI. |
| 148 | |
| 149 | A common case is when the UI is more recent than `trace_processor` |
| 150 | and depends on a new table definition. With older versions of |
| 151 | `trace_processor` in `--httpd` mode the UI crashes attempting to query |
| 152 | a non-existant table. To avoid this we use a version number. If the |
| 153 | version number `trace_processor` reports is older than the one the UI |
| 154 | was built with we prompt the user to update. |
| 155 | |
| 156 | 1. Go to `protos/perfetto/trace_processor/trace_processor.proto` |
| 157 | 2. Increment `TRACE_PROCESSOR_CURRENT_API_VERSION` |
| 158 | 3. Add a comment explaining what has changed. |