# Quickstart: SQL-based analysis and trace-based metrics

_This quickstart explains how to use `trace_processor` as well as its Python API to 
programmatically query the trace contents through SQL and compute trace-based metrics._

## Trace Processor

TraceProcessor is a multi-format trace importing and query engine based on
SQLite. It comes both as a C++ library and as a standalone executable:
`trace_processor_shell` (or just `trace_processor`).

### Setup

```bash
# Download prebuilts (Linux and Mac only)
curl -LO https://get.perfetto.dev/trace_processor
chmod +x ./trace_processor

# Start the interactive shell
./trace_processor trace.perfetto-trace

# Start a local trace processor instance to replace wasm module in the UI
./trace_processor trace.perfetto-trace --http
```

NOTE: In HTTP mode the trace will be loaded into the `trace_processor` and
      the UI will connect and issue queries over TCP. This can allow
      arbitrary sized traces to be loaded since there are no memory
      constraints, unlike the WASM module. In addition, this can improve
      performance in the UI as it issues SQL queries.

See [Trace Processor docs](/docs/analysis/trace-processor.md) for the full
TraceProcessor guide.

### Sample queries

For more exhaustive examples see the _SQL_ section of the various _Data sources_
docs.

#### Slices

Slices are stackable events which have name and span some duration of time.

![](/docs/images/slices.png "Example of slices in the UI")

```
> SELECT ts, dur, name FROM slice
ts                   dur                  name
-------------------- -------------------- ---------------------------
     261187017446933               358594 eglSwapBuffersWithDamageKHR
     261187017518340                  357 onMessageReceived
     261187020825163                 9948 queueBuffer
     261187021345235                  642 bufferLoad
     261187121345235                  153 query
     ...
```

#### Counters

Counters are events with a value which changes over time.

![](/docs/images/counters.png "Example of counters in the UI")

```
> SELECT ts, value FROM counter
ts                   value
-------------------- --------------------
     261187012149954          1454.000000
     261187012399172          4232.000000
     261187012447402         14304.000000
     261187012535839         15490.000000
     261187012590890         17490.000000
     261187012590890         16590.000000
...
```

#### Scheduler slices

Scheduler slices indicate which thread was scheduled on which CPU at which time.

![](/docs/images/sched-slices.png "Example of scheduler slices in the UI")

```
> SELECT ts, dur, cpu, utid FROM sched
ts                   dur                  cpu                  utid
-------------------- -------------------- -------------------- --------------------
     261187012170489               267188                    0                  390
     261187012170995               247153                    1                  767
     261187012418183                12812                    2                 2790
     261187012421099               220000                    6                  683
     261187012430995                72396                    7                 2791
...
```

### Trace-based metrics

Trace Processor offers also a higher-level query interface that allows to run
pre-baked queries, herein called "metrics". Metrics are generally curated by
domain experts, often the same people who add the instrumentation points in the
first place, and output structured JSON/Protobuf/text.
Metrics allow to get a summarized view of the trace without having to type any
SQL or having to load the trace in the UI.

The metrics` schema files live in the
[/protos/perfetto/metrics](/protos/perfetto/metrics/) directory.
The corresponding SQL queries live in
[/src/trace_processor/metrics](/src/trace_processor/metrics/).

#### Run a single metric

Let's run the [`android_cpu`](/protos/perfetto/metrics/android/cpu_metric.proto)
metric. This metrics computes the total CPU time and the total cycles
(CPU frequency * time spent running at that frequency) for each process in the
trace, breaking it down by CPU (_core_) number.

```protobuf
./trace_processor --run-metrics android_cpu trace.perfetto-trace

android_cpu {
  process_info {
    name: "/system/bin/init"
    threads {
      name: "init"
      core {
        id: 1
        metrics {
          mcycles: 1
          runtime_ns: 570365
          min_freq_khz: 1900800
          max_freq_khz: 1900800
          avg_freq_khz: 1902017
        }
      }
      core {
        id: 3
        metrics {
          mcycles: 0
          runtime_ns: 366406
          min_freq_khz: 1900800
          max_freq_khz: 1900800
          avg_freq_khz: 1902908
        }
      }
      ...
    }
    ...
  }
  process_info {
    name: "/system/bin/logd"
    threads {
      name: "logd.writer"
      core {
        id: 0
        metrics {
          mcycles: 8
          runtime_ns: 33842357
          min_freq_khz: 595200
          max_freq_khz: 1900800
          avg_freq_khz: 1891825
        }
      }
      core {
        id: 1
        metrics {
          mcycles: 9
          runtime_ns: 36019300
          min_freq_khz: 1171200
          max_freq_khz: 1900800
          avg_freq_khz: 1887969
        }
      }
      ...
    }
    ...
  }
  ...
}
```

#### Running multiple metrics

Multiple metrics can be flagged using comma separators to the `--run-metrics`
flag. This will output a text proto with the combined result of running both
metrics.

```protobuf
$ ./trace_processor --run-metrics android_mem,android_cpu trace.perfetto-trace

android_mem {
  process_metrics {
    process_name: ".dataservices"
    total_counters {
      anon_rss {
        min: 19451904
        max: 19890176
        avg: 19837548.157829277
      }
      file_rss {
        min: 25804800
        max: 25829376
        avg: 25827909.957489081
      }
      swap {
        min: 9289728
        max: 9728000
        avg: 9342355.8421707246
      }
      anon_and_swap {
        min: 29179904
        max: 29179904
        avg: 29179904
      }
    }
    ...
  }
  ...
}
android_cpu {
  process_info {
    name: "/system/bin/init"
    threads {
      name: "init"
      core {
        id: 1
        metrics {
          mcycles: 1
          runtime_ns: 570365
          min_freq_khz: 1900800
          max_freq_khz: 1900800
          avg_freq_khz: 1902017
        }
      }
      ...
    }
    ...
  }
  ...
}
```

#### JSON and binary output

The trace processor also supports binary protobuf and JSON as alternative output
formats. This is useful when the intended reader is an offline tool.

Both single and multiple metrics are supported as with proto text output.

```
./trace_processor --run-metrics android_mem --metrics-output=binary trace.perfetto-trace


./trace_processor --run-metrics android_mem,android_cpu --metrics-output=json trace.perfetto-trace
{
  "android_mem": {
    "process_metrics": [
      {
        "process_name": ".dataservices",
        "total_counters": {
          "anon_rss": {
            "min": 19451904.000000,
            "max": 19890176.000000,
            "avg": 19837548.157829
          },
          "file_rss": {
            "min": 25804800.000000,
            "max": 25829376.000000,
            "avg": 25827909.957489
          },
          "swap": {
            "min": 9289728.000000,
            "max": 9728000.000000,
            "avg": 9342355.842171
          },
          "anon_and_swap": {
            "min": 29179904.000000,
            "max": 29179904.000000,
            "avg": 29179904.000000
          }
        },
        ...
      },
      ...
    ]
  }
  "android_cpu": {
    "process_info": [
      {
        "name": "\/system\/bin\/init",
        "threads": [
          {
            "name": "init",
            "core": [
              {
                "id": 1,
                "metrics": {
                  "mcycles": 1,
                  "runtime_ns": 570365,
                  "min_freq_khz": 1900800,
                  "max_freq_khz": 1900800,
                  "avg_freq_khz": 1902017
                }
              },
              ...
            ]
            ...
          }
          ...
        ]
        ...
      },
      ...
    ]
    ...
  }
}
```

## Python API

The API can be run without requiring the `trace_processor` binary to be
downloaded or installed.

### Setup
```
$ pip install perfetto
```
NOTE: The API is only compatible with Python3.

### Example functions
See the Python API section of
[Trace Processor (SQL)](/docs/analysis/trace-processor.md) to get
more details on all available functions.

#### Query
```python
from perfetto.trace_processor import TraceProcessor
tp = TraceProcessor(trace='trace.perfetto-trace')

qr_it = tp.query('SELECT name FROM slice')
for row in qr_it:
  print(row.name)
```
**Output**
```
eglSwapBuffersWithDamageKHR
onMessageReceived
queueBuffer
bufferLoad
query
...
```
#### Query as Pandas DataFrame
```python
from perfetto.trace_processor import TraceProcessor
tp = TraceProcessor(trace='trace.perfetto-trace')

qr_it = tp.query('SELECT ts, name FROM slice')
qr_df = qr_it.as_pandas_dataframe()
print(qr_df.to_string())
```
**Output**
```
ts                   name
-------------------- ---------------------------
     261187017446933 eglSwapBuffersWithDamageKHR
     261187017518340 onMessageReceived
     261187020825163 queueBuffer
     261187021345235 bufferLoad
     261187121345235 query
     ...
```
#### Metric
```python
from perfetto.trace_processor import TraceProcessor
tp = TraceProcessor(trace='trace.perfetto-trace')

cpu_metrics = tp.metric(['android_cpu'])
print(cpu_metrics)
```
**Output**
```
metrics {
  android_cpu {
    process_info {
      name: "/system/bin/init"
      threads {
        name: "init"
        core {
          id: 1
          metrics {
            mcycles: 1
            runtime_ns: 570365
            min_freq_khz: 1900800
            max_freq_khz: 1900800
            avg_freq_khz: 1902017
          }
        }
        core {
          id: 3
          metrics {
            mcycles: 0
            runtime_ns: 366406
            min_freq_khz: 1900800
            max_freq_khz: 1900800
            avg_freq_khz: 1902908
          }
        }
        ...
      }
      ...
    }
    ...
  }
}
```

## Next steps

There are several options for exploring more of the trace analysis features
Perfetto provides:

* The [trace conversion quickstart](/docs/quickstart/traceconv.md) gives an
  overview on how to convert Perfetto traces to legacy formats to integrate with
  existing tooling.
* The [Trace Processor documentation](/docs/analysis/trace-processor.md) gives
  more information about how to work with trace processor including details on
  how to write queries and how tables in trace processor are organized.
* The [metrics documentation](/docs/analysis/metrics.md) gives a more in-depth
  look into metrics including a short walkthrough on how to build an
  experimental metric from scratch.
* The [SQL table reference](/docs/analysis/sql-tables.autogen) gives a
  comprehensive guide to the all the available tables in trace processor.
* The [common tasks](/docs/contributing/common-tasks.md) page gives a list of
  steps on how new metrics can be added to the trace processor.