File: tracing.md

package info (click to toggle)
chromium 139.0.7258.127-1
  • links: PTS, VCS
  • area: main
  • in suites:
  • size: 6,122,068 kB
  • sloc: cpp: 35,100,771; ansic: 7,163,530; javascript: 4,103,002; python: 1,436,920; asm: 946,517; xml: 746,709; pascal: 187,653; perl: 88,691; sh: 88,436; objc: 79,953; sql: 51,488; cs: 44,583; fortran: 24,137; makefile: 22,147; tcl: 15,277; php: 13,980; yacc: 8,984; ruby: 7,485; awk: 3,720; lisp: 3,096; lex: 1,327; ada: 727; jsp: 228; sed: 36
file content (294 lines) | stat: -rw-r--r-- 11,199 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
# Tracing Cronet

Cronet is deeply integrated with the [Perfetto](https://perfetto.dev/) tracing
framework. Using Perfetto, you can:

- Trace app-facing Cronet **API calls** and callbacks
- Get insights into **Chromium call stacks**, e.g. network thread operation
- Visualize [NetLogs](/net/docs/net-log.md), which provide deep insights into
  the operation of the **Chromium network stack** (e.g. DNS, TLS, IPv4/IPv6/Happy
  Eyeballs, TCP, QUIC, socket pools, sockets, packets, etc.) and make it
  possible to see the plaintext **contents of HTTP requests and responses**
- Correlate all of the above with other **events happening elsewhere** in the
  app (e.g. app business logic) and on the system/device (e.g. modem activity)

This makes Perfetto a very powerful swiss-army knife for all your Cronet
inspection, troubleshooting, debugging, and optimization needs.

Cronet tracing is usable out-of-the-box on every variant of Cronet across every
release channel, including production builds running in production apps on
production devices, as long as the Cronet version is recent enough. There is no
need to rebuild Cronet nor the app.

[TOC]

## Example trace

[Open this example trace in Perfetto](https://ui.perfetto.dev/#!/?s=4e7888dbaf280973305ff55cf514c833adccbef9)

![Trace screenshot](tracing.png)

## Getting started

There are two ways to gather a Cronet-focused trace:

 - Using the **Android System Tracing** feature built into the Android system UI;
   - The easiest method. Only usable on recent versions of Android.
 - Or using **Perfetto tools**.
   - Requires adb access. More flexible and produces more detailed traces.

### Using the Android System Tracing app (Traceur)

*** note
Using this method, events from Cronet native code and NetLog will only be
included in the trace if your Android version is recent enough for Traceur to
[use track events](https://r.android.com/2852485) in its Perfetto trace config.
This is true for Android 15+, and some versions of Android 14.
***

To capture a trace using this method, follow the [Android instructions on how
to capture a system trace](https://developer.android.com/topic/performance/tracing/on-device).

To ensure Cronet events are recorded, make sure that:

 - The *Trace debuggable applications* setting is on so that Cronet Android
   trace API (ATrace) events are captured.
 - The *webview* category is enabled so that Cronet track events (native code
   and NetLog) are captured.

### Using Perfetto tools

To record a trace using Perfetto, refer to the [Perfetto Android Quick Start
guide](https://perfetto.dev/docs/quickstart/android-tracing).

#### Recommended config

The following [Perfetto trace config](https://perfetto.dev/docs/concepts/config)
provides a good starting point for gathering a Cronet-focused trace:

```
# Trace for up to 1 minute. Adjust to taste.
duration_ms: 60000

data_sources {
  config {
      # Most Chromium code below the Cronet app-facing API uses the Perfetto
      # Track Event framework for tracing. This includes Chromium native call
      # stacks and NetLogs.
      name: "track_event"
      track_event_config {
        # Uncomment to record unredacted NetLogs, potentially revealing
        # credentials and other private information.
        # Note for this to work, you will also need to follow the instructions
        # in "Gathering unredacted NetLogs" below.
        #   enabled_categories: "disabled-by-default-netlog.sensitive"
      }
  }
  # Only collect track events from Cronet, as opposed to other Chromium products
  # (e.g. WebView) that may be running at the same time. Uncomment if you want
  # to collect events from those too.
  # You can also use this to restrict the events to a single app. For example:
  #   producer_name_filter: "cronet-com.google.android.googlequicksearchbox"
  producer_name_regex_filter: "cronet-.*"
}

data_sources {
  config {
    name: "linux.ftrace"
    ftrace_config {
      # Cronet Java code, including the app-facing higher layers (close to the
      # Cronet API), uses the Android Trace APIs (ATrace) for tracing.
      # You may wish to restrict this to the app you are interested in.
      atrace_apps: "*"

      # Required to get correct thread names.
      ftrace_events: "task/task_newtask"
      ftrace_events: "task/task_rename"

      # Trace ActivityManager. Useful to get insights into app initialization.
      atrace_categories: "am"

      # Trace the standard C library. Particularly useful to get insights into
      # Cronet native shared library (.so) loading (dlopen) performance. Also
      # provides insights into pthreads.
      atrace_categories: "bionic"

      # Trace the Java VM. Notably provides insights into Java class loading,
      # Java threads. Note this may also spam you with Java GC events.
      atrace_categories: "dalvik"

      # Surfaces IPCs.
      atrace_categories: "aidl"
      atrace_categories: "binder_driver"

      # Trace the Android OS network stack. Provides insights into a variety of
      # networking components such as WiFi, cellular, app network access policy,
      # firewall rules, etc. Can go as deep as providing detailed events about
      # cellular modem operation (RIL), such as data setup and signal strength.
      atrace_categories: "network"

      # ------------------------------------------------------------------------
      # Note the below settings add a lot of high-frequency events to the trace.
      # You may want to comment them out if you want smaller, possibly more
      # readable traces and are not interested in highly detailed system
      # performance information.

      # Surfaces which threads are running on which CPU at any given time.
      # Useful for troubleshooting CPU contention.
      ftrace_events: "sched/sched_switch"

      # Surfaces the reason why a thread became schedulable (e.g. a mutex being
      # unlocked). Useful for troubleshooting lock contention.
      ftrace_events: "sched/sched_wakeup"
      ftrace_events: "sched/sched_wakeup_new"
      ftrace_events: "sched/sched_waking"

      # Surfaces thread terminations.
      ftrace_events: "sched/sched_process_exit"
      ftrace_events: "sched/sched_process_free"

      # Surfaces system calls. Useful for surfacing mutex waits and individual
      # socket send/receive calls.
      ftrace_events: "raw_syscalls/sys_enter"
      ftrace_events: "raw_syscalls/sys_exit"

      # ------------------------------------------------------------------------
    }
  }
}

data_sources {
  config {
    name: "android.statsd"
    # Note: this data source only exists in Android 14+, see
    # https://r.android.com/2132122. If you get a "no field named ..." error
    # on the next line, you'll have to remove this data source.
    statsd_tracing_config {
      # Log Cronet telemetry atoms; see
      # org.chromium.net.telemetry.CronetStatsLog.
      # These can be used to troubleshoot Cronet telemetry, and the atom data
      # itself can provide insights into Cronet operation.
      # These will show up under "System" > "Statsd Atoms" in the Perfetto UI.
      push_atom_id: ATOM_CRONET_ENGINE_CREATED
      push_atom_id: ATOM_CRONET_TRAFFIC_REPORTED
      push_atom_id: ATOM_CRONET_ENGINE_BUILDER_INITIALIZED
      push_atom_id: ATOM_CRONET_INITIALIZED
    }
  }
}

data_sources {
  config {
    # Surfaces individual network packets being sent or received at the OS
    # level. Provides insights below the Cronet socket layer. This will show
    # up under "System" > "Network" in the Perfetto UI, and as counters under
    # process tracks.
    name: "android.network_packets"
    # Note: this data source only exists in Android 14+, see
    # https://r.android.com/2310392. If you get a "no field named ..." error
    # on the next line, you'll have to remove this data source.
    network_packet_trace_config {
      poll_ms: 250
    }
  }
}

data_sources {
  config {
    name: "linux.process_stats"
    process_stats_config {
        scan_all_processes_on_start: true
        record_thread_names: true
    }
  }
}

data_sources {
  config {
    # Include the logcat in the trace.
    # Note that, sadly, this only works on userdebug/eng Android system
    # images, not production devices. See https://crbug.com/126721497.
    name: "android.log"
  }
}

data_sources {
  config {
    # Gather the list of packages installed on the device, along with their
    # versions. This can be found in the "Info and stats" section in the
    # Perfetto UI.
    name: "android.packages_list"
  }
}

buffers {
    size_kb: 65536
}
```

## Gathering unredacted NetLogs

[NetLogs](/net/docs/net-log.md) are included in the trace by default. However,
for privacy and security reasons, Cronet NetLog tracing operates in "heavily
redacted" mode, where most of the metadata is stripped out. Notably, this means
the resulting trace will not contain IP addresses, hostnames, URLs, HTTP
headers, request/response bodies, TLS certificate details, etc.

If this is a problem, it is possible to configure Cronet to trace unredacted,
unstripped NetLogs that will include the above information.

*** aside
If you feel that a particular field is safe enough to be included in redacted
NetLogs, but isn't, feel free to propose it for inclusion in the
[allowlist](/net/log/net_log_heavily_redacted_allowlist.h).
***

### Requirements

Cronet can only be configured to trace unredacted NetLogs if the following
conditions are met:

- The Android device is running a [userdebug or eng system
  image](https://source.android.com/docs/setup/build/building#choose-a-target),
  **OR** the app running Cronet is [marked as
  debuggable](https://developer.android.com/guide/topics/manifest/application-element#debug).
  - It is not possible to collect an unredacted NetLog from a production app
    running on a production device.
- You have adb access to the device.

### Enabling unredacted Cronet NetLog tracing

*** note
**WARNING: DO NOT DO THIS ON A DEVICE THAT HANDLES REAL USER DATA.** In this
mode the trace will include the equivalent of plaintext HTTP requests and
responses. Unredacted NetLogs collected from an app handling real user data will
likely contain extremely sensitive data, such as personal information, private
keys, and plaintext passwords.
***

To enable unredacted NetLog tracing, run:

```
adb shell setprop debug.cronet.trace_netlog everything
```

Then restart the app. This setting will persist until the next device reboot.

You will also need to explicitly enable the
`disabled-by-default-netlog.sensitive` track event category in your trace config
(see above), otherwise no NetLog events will be logged while the above setting
is active.

## Early events getting dropped

Due to a [Perfetto limitation](https://crbug.com/324031921), events logged using
the Perfetto SDK very shortly (single-digit milliseconds) after Cronet library
initialization are liable to get dropped.

If you suspect this is preventing you from seeing the events you are looking
for, use the following setting to delay Cronet initialization. This will
hopefully allow Perfetto enough time to initialize.

```
adb shell setprop debug.cronet.init_trace_sleep 10ms
```