Primiano Tucci | 1e96f3b | 2019-06-04 12:08:16 +0100 | [diff] [blame] | 1 | # Perfetto public API surface |
| 2 | |
| 3 | **This API surface is not stable yet, don't depend on it** |
| 4 | |
| 5 | This folder contains the public perfetto API headers. This allows an app to |
| 6 | inject trace events into perfetto with ~10 lines of code (see |
| 7 | api_usage_example.cc). |
| 8 | |
| 9 | The ext/ subdirectory expose the API-unstable classes and types that are |
| 10 | exposed to emvbedders that have exceptional requirements in terms of interposing |
| 11 | their own custom IPC layer. To the day the only case is chromium. Nothing else |
| 12 | should depend on ext/. Contact perfetto-dev@ if you think you need to |
| 13 | depend on an ext/ header. |
| 14 | |
| 15 | Headers in this folder must be hermetic. No ext/ perfetto header must be |
| 16 | leaked from the includes. |
| 17 | |
| 18 | What is a client supposed to do to use tracing? See example below in this page. |
| 19 | |
| 20 | |
| 21 | Source code layout: what goes where? |
| 22 | ------------------------------------ |
| 23 | |
| 24 | **include/perfetto (this folder):** |
| 25 | Embedders are allowed to access and depend on any folder of this but ext/. |
| 26 | This contains classes to: (i) use tracing; (ii) extend the tracing internals |
| 27 | (i.e. implement the Platform). |
| 28 | |
| 29 | Rules: |
| 30 | - This directory should contain only .h files and no .cc files. |
| 31 | - Corresponding .cc files go into `src/`. |
| 32 | - .h files in here can depend only on `include/perfetto/` but not on |
| 33 | `include/perfetto/ext/`, |
| 34 | |
| 35 | **include/perfetto/tracing/internal:** |
| 36 | This directory contains headers that are required to implement the public-facing |
| 37 | tracing API efficiently but that are not part of the API surface. |
| 38 | In an ideal world there would be no need of these headers and everything would |
| 39 | be handle via forward-declarations and PIMPL patterns. Unfortunately, however, |
| 40 | PIMPL cannot be used for inline functions, where the implementation needs to be |
| 41 | exposed in the public headers, which in turn need to depend on the memory layout |
| 42 | of structs/classes. |
| 43 | |
| 44 | Rules: |
| 45 | - All classes / types declared in this folder must be wrapped in the |
| 46 | ::perfetto::internal namespace. |
| 47 | - Both public and internal .h headers must not pull other perfetto headers |
| 48 | from ext/. |
| 49 | - .cc files instead can depend on other perfetto classes, as well as .h headers |
| 50 | located in src/. |
| 51 | - Embedders must not depend on the perfetto::internal namespace. |
| 52 | - Internal types cannot be used as input, output or return arguments of public |
| 53 | API functions. |
| 54 | - Internal types cannot be directly exposed to virtual methods that are |
| 55 | intended to be called or overridden by the embedder (e.g. TracingBackend's |
| 56 | methods). For those the solution is to create a matching non-internal base |
| 57 | class with a static factory method. |
| 58 | - We don't guarantee binary compatibility between versions (i.e. this client |
| 59 | library can only be statically linked) but we guarantee source-level |
| 60 | compatibility and ABI of the UNIX socket and shared memory buffers. |
| 61 | |
| 62 | |
| 63 | Usage example |
| 64 | ------------- |
| 65 | 1. Call `perfetto::Tracing::Initialize(...)` once, when starting the app. |
| 66 | While doing so the app can chose the tracing model: |
| 67 | - Fully in-process: the service runs in a thread within the same process. |
| 68 | - System: connects to the traced system daemon via a UNIX socket. This allows |
| 69 | the app to join system-wide tracing sessions. This is available only on |
| 70 | Linux/Android/MacOS for now. |
| 71 | - Private dedicated process: similar to the in-process case, but the service |
| 72 | runs in a dedicated process rather than a thread. This is for performance, |
| 73 | stability and security isolation. Also, this is not implemented yet. |
| 74 | - Custom backend: this is for peculiar cases (mainly chromium) where the |
| 75 | embedder is multi-process but wants to use a different IPC mechanism. The |
| 76 | embedder needs to deal with the larger and clunkier set of perfetto APIs. |
| 77 | Reach out to the team before using this mode. It's very unlikely you need |
| 78 | this unless you are a project rolled into chromium. |
| 79 | |
| 80 | 2. Define and register one or more data sources, like this: |
| 81 | ```cpp |
| 82 | #include "perfetto/tracing.h" |
| 83 | |
| 84 | class MyDataSource : public perfetto::DataSource<MyDataSource> { |
Florian Mayer | 10b3548 | 2019-07-22 18:43:27 +0100 | [diff] [blame] | 85 | void OnSetup(const SetupArgs&) override {} |
| 86 | void OnStart(const StartArgs&) override {} |
| 87 | void OnStop(const StopArgs&) override {} |
Primiano Tucci | 1e96f3b | 2019-06-04 12:08:16 +0100 | [diff] [blame] | 88 | }; |
| 89 | ... |
Primiano Tucci | 1e96f3b | 2019-06-04 12:08:16 +0100 | [diff] [blame] | 90 | perfetto::DataSourceDescriptor dsd; |
| 91 | dsd.set_name("my_data_source"); |
| 92 | MyDataSource::Register(dsd); |
| 93 | ``` |
| 94 | |
| 95 | 3. Optionally define a new proto schema in `trace_packet.proto` |
| 96 | |
| 97 | 4. Emit trace events |
| 98 | ```cpp |
Florian Mayer | f337c7b | 2019-07-23 13:05:42 +0100 | [diff] [blame] | 99 | MyDataSource::Trace([](MyDataSource::TraceContext ctx) { |
Primiano Tucci | 1e96f3b | 2019-06-04 12:08:16 +0100 | [diff] [blame] | 100 | auto trace_packet = ctx.NewTracePacket(); |
Florian Mayer | f337c7b | 2019-07-23 13:05:42 +0100 | [diff] [blame] | 101 | trace_packet->set_timestamp(...); |
| 102 | auto* my_custom_proto = trace_packet->set_my_custom_proto(); |
Primiano Tucci | 1e96f3b | 2019-06-04 12:08:16 +0100 | [diff] [blame] | 103 | }); |
| 104 | ``` |
| 105 | |
Primiano Tucci | 66b08c3 | 2020-07-23 12:37:48 +0200 | [diff] [blame] | 106 | The passed lambda will be called only if tracing is enabled and the data source |
Primiano Tucci | 1e96f3b | 2019-06-04 12:08:16 +0100 | [diff] [blame] | 107 | was enabled in the trace config. It might be called multiple times, one for each |
| 108 | active tracing session, in case of concurrent tracing sessions (or even within a |
| 109 | single tracing session, if the data source is listed twice in the trace config). |