You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
121 lines
5.4 KiB
121 lines
5.4 KiB
# Service-based model
|
|
|
|
![Perfetto Stack](https://storage.googleapis.com/perfetto/markdown_img/producer-service-consumer.png)
|
|
|
|
## Service
|
|
|
|
The tracing service is a long-lived entity (a system daemon on Linux/Android,
|
|
a service in Chrome) that has the following responsibilities:
|
|
|
|
* Maintains a registry of active producers and their data sources.
|
|
* Owns the trace buffers.
|
|
* Handles multiplexing of several tracing sessions.
|
|
* Routes the trace config from the consumers to the corresponding producers.
|
|
* Tells the Producers when and what to trace.
|
|
* Moves data from the Producer's shared memory buffer to the central non-shared
|
|
trace buffers.
|
|
|
|
## Producer
|
|
|
|
A producer is an untrusted entity that offers the ability to contribute to the
|
|
trace. In a multiprocess model, a producer almost always corresponds to a client
|
|
process of the tracing service. It advertises its ability to contribute to the trace with one or more data sources.
|
|
Each producer has exactly:
|
|
|
|
* One shared memory buffer, shared exclusively with the tracing service.
|
|
* One IPC channel with the tracing service.
|
|
|
|
A producer is completely decoupled (both technically and conceptually) from
|
|
consumer(s). A producer knows nothing about:
|
|
|
|
* How many consumer(s) are connected to the service.
|
|
* How many tracing sessions are active.
|
|
* How many other producer(s) are registered or active.
|
|
* Trace data written by other producer(s).
|
|
|
|
NOTE: In rare circumstances a process can host more than one producer and hence more
|
|
than one shared memory buffer. This can be the case for a process bundling
|
|
third-party libraries that in turn include the Perfetto client library.
|
|
Concrete example: at some point in the future Chrome might expose one Producer for tracing within the main project, one for V8 and one for Skia (for each child
|
|
process).
|
|
|
|
## Consumer
|
|
A consumer is a trusted entity (a cmdline client on Linux/Android, an interface
|
|
of the Browser process in Chrome) that controls (non-exclusively) the tracing service and reads back (destructively) the trace buffers.
|
|
A consumer has the ability to:
|
|
* Send a [trace config](#) to the service, determining:
|
|
* How many trace buffers to create.
|
|
* How big the trace buffers should be.
|
|
* The policy for each buffer (*ring-buffer* or *stop-when-full*).
|
|
* Which data sources to enable.
|
|
* The configuration for each data source.
|
|
* The target buffer for the data produced by each data source configured.
|
|
* Enable and disable tracing.
|
|
* Read back the trace buffers:
|
|
* Streaming data over the IPC channel.
|
|
* Passing a file descriptor to the service and instructing it to periodically
|
|
save the trace buffers into the file.
|
|
|
|
## Data source
|
|
|
|
A data source is a capability, exposed by a Producer, of providing some tracing
|
|
data. A data source almost always defines its own schema (a protobuf) consisting
|
|
of:
|
|
* At most one `DataSourceConfig` sub-message:
|
|
|
|
([example](/protos/perfetto/config/ftrace/ftrace_config.proto))
|
|
* One or more `TracePacket` sub-messages
|
|
([example](/protos/perfetto/trace/ps/process_tree.proto))
|
|
|
|
Different producers may expose the same data source. Concrete example:
|
|
*** aside
|
|
At some point in the near future we might offer, as part of Perfetto, a library
|
|
for in-process heap profiling. In such case more than one producer, linking
|
|
against the updated Perfetto library, will expose the heap profiler data source,
|
|
for its own process.
|
|
**
|
|
|
|
## IPC channel
|
|
In a multiprocess scenario, each producer and each consumer interact with the
|
|
service using an IPC channel. IPC is used only in non-fast-path interactions,
|
|
mostly handshakes such as enabling/disabling trace (consumer), (un)registering
|
|
and starting/stopping data sources (producer). The IPC is typically NOT employed
|
|
to transport the protobufs for the trace.
|
|
Perfetto provides a POSIX-friendly IPC implementation, based on protobufs over a
|
|
UNIX socket (see
|
|
[Socket protocol](/docs/design-docs/api-and-abi#socket-protocol)).
|
|
|
|
That IPC implementation is not mandated. Perfetto allows the embedder:
|
|
|
|
* Wrap its own IPC subsystem (e.g., Perfetto in Chromium uses Mojo)
|
|
* Not use an IPC mechanism at all and just short circuit the
|
|
Producer <> Service <> Consumer interaction via `PostTask(s)`.
|
|
|
|
## Shared memory buffer
|
|
Producer(s) write tracing data, in the form of protobuf-encoded binary blobs,
|
|
directly into its shared memory buffer, using a special library called
|
|
[ProtoZero](/docs/design-docs/protozero.md). The shared memory buffer:
|
|
|
|
* Has a fixed and typically small size (configurable, default: 128 KB).
|
|
* Is an ABI and must maintain backwards compatibility.
|
|
* Is shared by all data sources of the producer.
|
|
* Is independent of the number and the size of the trace buffers.
|
|
* Is independent of the number of Consumer(s).
|
|
* Is partitioned in *chunks* of variable size.
|
|
|
|
Each chunk:
|
|
|
|
* Is owned exclusively by one Producer thread (or shared through a mutex).
|
|
* Contains a linear sequence of `TracePacket(s)`, or
|
|
fragments of that. A `TracePacket` can span across several chunks, the
|
|
fragmentation is not exposed to the consumers (consumers always see whole
|
|
packets as if they were never fragmented).
|
|
* Can be owned and written by exactly one `TraceWriter`.
|
|
* Is part of a reliable and ordered sequence, identified by the `WriterID`:
|
|
packets in a sequence are guaranteed to be read back in order, without gaps
|
|
and without repetitions.
|
|
|
|
See the comments in
|
|
[shared_memory_abi.h](/include/perfetto/ext/tracing/core/shared_memory_abi.h)
|
|
for more details about the binary format of this buffer.
|