components/cronet/tracing.md
Cronet is deeply integrated with the Perfetto tracing framework. Using Perfetto, you can:
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]
Open this example trace in Perfetto
There are two ways to gather a Cronet-focused trace:
*** 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 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.
To ensure Cronet events are recorded, make sure that:
To record a trace using Perfetto, refer to the Perfetto Android Quick Start guide.
The following Perfetto trace 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"
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"
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
}
*** note The above config assumes your device is running a recent Android version. If you get a "No field named ..." error with the above config, the most likely explanation is you are running an Android version that is too old and does not support that particular data source. Either use a more recent Android version, or remove the data source from the config and try again.
*** note
If you find that your trace is mysteriously missing all ATrace events (e.g. you
don't see any user-facing Cronet API calls), it could be that your device may
not recognize some of the atrace_categories. This is especially likely if you
are running a trace on a device running an old Android version. If an ATrace
category is not recognized by the device, Perfetto will disable all of ATrace.
Try to remove the aidl and network ATrace categories, and watch out for
Perfetto unknown tracing category error messages in logcat.
NetLogs 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.
Cronet can only be configured to trace unredacted NetLogs if the following conditions are met:
*** 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.
Due to a Perfetto limitation, 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