Trace Processor is a C++ library (src/trace_processor) that ingests traces in a variety of formats and exposes an SQL interface for querying them through a consistent set of tables. It also computes trace summaries, annotates traces with human-readable descriptions, and derives new events from trace contents.
Most users interact with Trace Processor through the trace_processor shell, a command-line wrapper around the library that opens an interactive PerfettoSQL prompt. To embed Trace Processor in another C++ application, see Embedding the C++ library. Python users should use the Python API instead.
The trace_processor shell is a command-line binary that loads a trace and opens an interactive SQL prompt on it.
The shell is a thin Python wrapper that you download from the Perfetto website. On first use it fetches and caches the native binary for your platform (including trace_processor_shell.exe on Windows) under ~/.local/share/perfetto/prebuilts.
Once downloaded, run it on a trace file:
This opens an interactive SQL shell where you can query the trace. For how to write queries, see the Getting Started with PerfettoSQL guide.
TIP: the trace file can also be a ZIP or TAR archive containing several traces: they are merged onto a single timeline. See Merging traces from the command line.
For example, to see all the slices in a trace:
> SELECT ts, dur, name FROM slice LIMIT 10; ts dur name -------------------- -------------------- --------------------------- 261187017446933 358594 eglSwapBuffersWithDamageKHR 261187017518340 357 onMessageReceived 261187020825163 9948 queueBuffer 261187021345235 642 bufferLoad 261187121345235 153 query ...
Or, to see the values of all counters:
> SELECT ts, value FROM counter LIMIT 10; ts value -------------------- -------------------- 261187012149954 1454.000000 261187012399172 4232.000000 261187012447402 14304.000000 261187012535839 15490.000000 261187012590890 17490.000000 261187012590890 16590.000000 ...
Parsing a large trace takes time. If you plan to run several queries against the same trace, load it once into a named background session and point each invocation at that session:
# Load the trace once into a background session. trace_processor server unix --name mysession --daemonize trace.pftrace # Run queries against the warm session instead of re-loading the trace. trace_processor query --remote mysession "SELECT count(*) FROM slice"
The query, interactive, metrics and summarize subcommands all accept --remote, which talks to a session over the same TraceProcessor RPC interface the Perfetto UI uses. See Analyzing traces from the command line for a walkthrough, and the server reference for the mode and flag details.
See the Trace Processor command-line reference for commands, options, environment variables, and output behavior.
See query in the CLI reference.
See interactive in the CLI reference.
See server in the CLI reference.
See summarize in the CLI reference.
See export in the CLI reference.
See Global flags in the CLI reference.
The public API centers on the TraceProcessor class in trace_processor.h. All high-level operations (parsing trace bytes, executing SQL queries, computing summaries) are member functions of this class.
Create an instance with CreateInstance:
#include "perfetto/trace_processor/trace_processor.h" using namespace perfetto::trace_processor; Config config; std::unique_ptr<TraceProcessor> tp = TraceProcessor::CreateInstance(config);
To ingest a trace, call Parse repeatedly with chunks of trace bytes, then NotifyEndOfFile once the whole trace has been pushed:
while (/* more data available */) { TraceBlobView blob = /* ... */; base::Status status = tp->Parse(std::move(blob)); if (!status.ok()) { /* handle error */ } } base::Status status = tp->NotifyEndOfFile();
Because reading a trace from the filesystem is a common case, a helper ReadTrace is provided in read_trace.h:
#include "perfetto/trace_processor/read_trace.h" base::Status status = ReadTrace(tp.get(), "/path/to/trace.pftrace");
ReadTrace reads the file from disk, calls Parse with the contents, and calls NotifyEndOfFile for you.
Run queries with ExecuteQuery, which returns an Iterator that streams rows back to the caller:
auto it = tp->ExecuteQuery("SELECT ts, name FROM slice LIMIT 10"); while (it.Next()) { int64_t ts = it.Get(0).AsLong(); std::string name = it.Get(1).AsString(); // ... } if (!it.Status().ok()) { // Query produced an error. }
Two important rules when using the iterator:
Next before accessing values. The iterator is positioned before the first row when returned, so Get cannot be called until Next has returned true.Status after iteration finishes. A query may fail partway through; Next returning false only means iteration stopped, not that it succeeded. Inspect Status() to distinguish EOF from an error.See the comments in iterator.h for the full iterator API.
The TraceProcessor class also exposes:
Summarize): computes structured summaries of a trace. See Trace Summarization for a user-facing description.RegisterSqlPackage): registers PerfettoSQL files under a package name so queries can INCLUDE them.RegisterFileContent): passes auxiliary data to importers, e.g. binaries used to decode ETM traces.EnableMetatrace / DisableAndReadMetatrace): traces Trace Processor itself for performance debugging.Refer to the comments in trace_processor.h for the complete API surface.