Add perfetto metric for ANRs
Change-Id: I158c5d3e11c0183ea3fa24a8edd55864a9fa72e9
Bug: 297193790
Test: tools/diff_test_trace_processor.py
diff --git a/Android.bp b/Android.bp
index 85b8ae8..460b776 100644
--- a/Android.bp
+++ b/Android.bp
@@ -4590,6 +4590,7 @@
"protos/perfetto/metrics/android/android_frame_timeline_metric.proto",
"protos/perfetto/metrics/android/android_sysui_notifications_blocking_calls_metric.proto",
"protos/perfetto/metrics/android/android_trusty_workqueues.proto",
+ "protos/perfetto/metrics/android/anr_metric.proto",
"protos/perfetto/metrics/android/batt_metric.proto",
"protos/perfetto/metrics/android/binder_metric.proto",
"protos/perfetto/metrics/android/camera_metric.proto",
@@ -4669,6 +4670,7 @@
"protos/perfetto/metrics/android/android_frame_timeline_metric.proto",
"protos/perfetto/metrics/android/android_sysui_notifications_blocking_calls_metric.proto",
"protos/perfetto/metrics/android/android_trusty_workqueues.proto",
+ "protos/perfetto/metrics/android/anr_metric.proto",
"protos/perfetto/metrics/android/batt_metric.proto",
"protos/perfetto/metrics/android/binder_metric.proto",
"protos/perfetto/metrics/android/camera_metric.proto",
@@ -4730,6 +4732,7 @@
"protos/perfetto/metrics/android/android_frame_timeline_metric.proto",
"protos/perfetto/metrics/android/android_sysui_notifications_blocking_calls_metric.proto",
"protos/perfetto/metrics/android/android_trusty_workqueues.proto",
+ "protos/perfetto/metrics/android/anr_metric.proto",
"protos/perfetto/metrics/android/batt_metric.proto",
"protos/perfetto/metrics/android/binder_metric.proto",
"protos/perfetto/metrics/android/camera_metric.proto",
@@ -10386,6 +10389,7 @@
genrule {
name: "perfetto_src_trace_processor_metrics_sql_gen_amalgamated_sql_metrics",
srcs: [
+ "src/trace_processor/metrics/sql/android/android_anr.sql",
"src/trace_processor/metrics/sql/android/android_batt.sql",
"src/trace_processor/metrics/sql/android/android_binder.sql",
"src/trace_processor/metrics/sql/android/android_blocking_calls_cuj_metric.sql",
@@ -10427,6 +10431,7 @@
"src/trace_processor/metrics/sql/android/android_task_names.sql",
"src/trace_processor/metrics/sql/android/android_trace_quality.sql",
"src/trace_processor/metrics/sql/android/android_trusty_workqueues.sql",
+ "src/trace_processor/metrics/sql/android/anr/anrs.sql",
"src/trace_processor/metrics/sql/android/codec_metrics.sql",
"src/trace_processor/metrics/sql/android/composer_execution.sql",
"src/trace_processor/metrics/sql/android/composition_layers.sql",
diff --git a/BUILD b/BUILD
index a33b35f..f4c23a8 100644
--- a/BUILD
+++ b/BUILD
@@ -1833,6 +1833,7 @@
perfetto_filegroup(
name = "src_trace_processor_metrics_sql_android_android",
srcs = [
+ "src/trace_processor/metrics/sql/android/android_anr.sql",
"src/trace_processor/metrics/sql/android/android_batt.sql",
"src/trace_processor/metrics/sql/android/android_binder.sql",
"src/trace_processor/metrics/sql/android/android_blocking_calls_cuj_metric.sql",
@@ -1874,6 +1875,7 @@
"src/trace_processor/metrics/sql/android/android_task_names.sql",
"src/trace_processor/metrics/sql/android/android_trace_quality.sql",
"src/trace_processor/metrics/sql/android/android_trusty_workqueues.sql",
+ "src/trace_processor/metrics/sql/android/anr/anrs.sql",
"src/trace_processor/metrics/sql/android/codec_metrics.sql",
"src/trace_processor/metrics/sql/android/composer_execution.sql",
"src/trace_processor/metrics/sql/android/composition_layers.sql",
@@ -4059,6 +4061,7 @@
"protos/perfetto/metrics/android/android_frame_timeline_metric.proto",
"protos/perfetto/metrics/android/android_sysui_notifications_blocking_calls_metric.proto",
"protos/perfetto/metrics/android/android_trusty_workqueues.proto",
+ "protos/perfetto/metrics/android/anr_metric.proto",
"protos/perfetto/metrics/android/batt_metric.proto",
"protos/perfetto/metrics/android/binder_metric.proto",
"protos/perfetto/metrics/android/camera_metric.proto",
diff --git a/protos/perfetto/metrics/android/BUILD.gn b/protos/perfetto/metrics/android/BUILD.gn
index 3c18498..bd639d8 100644
--- a/protos/perfetto/metrics/android/BUILD.gn
+++ b/protos/perfetto/metrics/android/BUILD.gn
@@ -25,6 +25,7 @@
"android_frame_timeline_metric.proto",
"android_sysui_notifications_blocking_calls_metric.proto",
"android_trusty_workqueues.proto",
+ "anr_metric.proto",
"batt_metric.proto",
"binder_metric.proto",
"camera_metric.proto",
diff --git a/protos/perfetto/metrics/android/anr_metric.proto b/protos/perfetto/metrics/android/anr_metric.proto
new file mode 100644
index 0000000..30d3fc2
--- /dev/null
+++ b/protos/perfetto/metrics/android/anr_metric.proto
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+ syntax = "proto2";
+
+ package perfetto.protos;
+
+ message AndroidAnrMetric {
+ repeated Anr anr = 1;
+
+ // Next id: 12
+ message Anr {
+ // UUID that identifies the ANR.
+ optional string error_id = 1;
+
+ // Name of the process that ANRed.
+ optional string process_name = 2;
+
+ // PID of the ANRing process.
+ optional int32 pid = 3;
+
+ // ANR subject line.
+ optional string subject = 4;
+
+ // Timestamp of the ANR in the trace.
+ optional int64 ts = 5;
+ }
+}
\ No newline at end of file
diff --git a/protos/perfetto/metrics/metrics.proto b/protos/perfetto/metrics/metrics.proto
index dfad850..feb2d72 100644
--- a/protos/perfetto/metrics/metrics.proto
+++ b/protos/perfetto/metrics/metrics.proto
@@ -19,6 +19,7 @@
package perfetto.protos;
import "protos/perfetto/metrics/android/android_frame_timeline_metric.proto";
+import "protos/perfetto/metrics/android/anr_metric.proto";
import "protos/perfetto/metrics/android/batt_metric.proto";
import "protos/perfetto/metrics/android/android_sysui_notifications_blocking_calls_metric.proto";
import "protos/perfetto/metrics/android/android_blocking_calls_cuj_metric.proto";
@@ -106,7 +107,7 @@
// Root message for all Perfetto-based metrics.
//
-// Next id: 55
+// Next id: 56
message TraceMetrics {
reserved 4, 10, 13, 14, 16, 19;
@@ -256,6 +257,9 @@
// is clear that this data is necessary.
optional AndroidIoUnaggregated android_io_unagg = 54;
+ // Metrics for App Not Responding (ANR) errors.
+ optional AndroidAnrMetric android_anr = 55;
+
// Demo extensions.
extensions 450 to 499;
diff --git a/protos/perfetto/metrics/perfetto_merged_metrics.proto b/protos/perfetto/metrics/perfetto_merged_metrics.proto
index 7106f0e..588cd05 100644
--- a/protos/perfetto/metrics/perfetto_merged_metrics.proto
+++ b/protos/perfetto/metrics/perfetto_merged_metrics.proto
@@ -191,6 +191,31 @@
// End of protos/perfetto/metrics/android/android_trusty_workqueues.proto
+// Begin of protos/perfetto/metrics/android/anr_metric.proto
+
+ message AndroidAnrMetric {
+ repeated Anr anr = 1;
+
+ // Next id: 12
+ message Anr {
+ // UUID that identifies the ANR.
+ optional string error_id = 1;
+
+ // Name of the process that ANRed.
+ optional string process_name = 2;
+
+ // PID of the ANRing process.
+ optional int32 pid = 3;
+
+ // ANR subject line.
+ optional string subject = 4;
+
+ // Timestamp of the ANR in the trace.
+ optional int64 ts = 5;
+ }
+}
+// End of protos/perfetto/metrics/android/anr_metric.proto
+
// Begin of protos/perfetto/metrics/android/batt_metric.proto
message AndroidBatteryMetric {
@@ -2219,7 +2244,7 @@
// Root message for all Perfetto-based metrics.
//
-// Next id: 55
+// Next id: 56
message TraceMetrics {
reserved 4, 10, 13, 14, 16, 19;
@@ -2369,6 +2394,9 @@
// is clear that this data is necessary.
optional AndroidIoUnaggregated android_io_unagg = 54;
+ // Metrics for App Not Responding (ANR) errors.
+ optional AndroidAnrMetric android_anr = 55;
+
// Demo extensions.
extensions 450 to 499;
diff --git a/python/perfetto/trace_processor/metrics.descriptor b/python/perfetto/trace_processor/metrics.descriptor
index 820f47e..8f80340 100644
--- a/python/perfetto/trace_processor/metrics.descriptor
+++ b/python/perfetto/trace_processor/metrics.descriptor
Binary files differ
diff --git a/src/trace_processor/metrics/sql/android/BUILD.gn b/src/trace_processor/metrics/sql/android/BUILD.gn
index 28eb9d0..92da898 100644
--- a/src/trace_processor/metrics/sql/android/BUILD.gn
+++ b/src/trace_processor/metrics/sql/android/BUILD.gn
@@ -19,6 +19,7 @@
perfetto_sql_source_set("android") {
sources = [
+ "android_anr.sql",
"android_batt.sql",
"android_binder.sql",
"android_blocking_calls_cuj_metric.sql",
@@ -60,6 +61,7 @@
"android_task_names.sql",
"android_trace_quality.sql",
"android_trusty_workqueues.sql",
+ "anr/anrs.sql",
"codec_metrics.sql",
"composer_execution.sql",
"composition_layers.sql",
diff --git a/src/trace_processor/metrics/sql/android/android_anr.sql b/src/trace_processor/metrics/sql/android/android_anr.sql
new file mode 100644
index 0000000..17d6f95
--- /dev/null
+++ b/src/trace_processor/metrics/sql/android/android_anr.sql
@@ -0,0 +1,34 @@
+--
+-- Copyright 2022 The Android Open Source Project
+--
+-- Licensed under the Apache License, Version 2.0 (the "License");
+-- you may not use this file except in compliance with the License.
+-- You may obtain a copy of the License at
+--
+-- https://www.apache.org/licenses/LICENSE-2.0
+--
+-- Unless required by applicable law or agreed to in writing, software
+-- distributed under the License is distributed on an "AS IS" BASIS,
+-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+-- See the License for the specific language governing permissions and
+-- limitations under the License.
+
+-- Create the base table (`android_anr_anrs`) containing all ANRs found
+-- in the trace.
+SELECT RUN_METRIC('android/anr/anrs.sql');
+
+DROP VIEW IF EXISTS android_anr_output;
+CREATE VIEW android_anr_output AS
+SELECT
+ AndroidAnrMetric(
+ 'anr', (
+ SELECT RepeatedField(
+ AndroidAnrMetric_Anr(
+ 'process_name', process_name,
+ 'pid', pid,
+ 'subject', subject,
+ 'error_id', error_id,
+ 'ts', ts))
+ FROM android_anr_anrs
+ )
+ );
\ No newline at end of file
diff --git a/src/trace_processor/metrics/sql/android/anr/anrs.sql b/src/trace_processor/metrics/sql/android/anr/anrs.sql
new file mode 100644
index 0000000..769fe14
--- /dev/null
+++ b/src/trace_processor/metrics/sql/android/anr/anrs.sql
@@ -0,0 +1,50 @@
+--
+-- Copyright 2022 The Android Open Source Project
+--
+-- Licensed under the Apache License, Version 2.0 (the "License");
+-- you may not use this file except in compliance with the License.
+-- You may obtain a copy of the License at
+--
+-- https://www.apache.org/licenses/LICENSE-2.0
+--
+-- Unless required by applicable law or agreed to in writing, software
+-- distributed under the License is distributed on an "AS IS" BASIS,
+-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+-- See the License for the specific language governing permissions and
+-- limitations under the License.
+
+-- One row per ANR that occurred in the trace.
+DROP TABLE IF EXISTS android_anr_anrs;
+CREATE TABLE android_anr_anrs AS
+-- Process and PID that ANRed.
+WITH anr_process AS (
+ SELECT
+ -- Counter formats:
+ -- v1: "ErrorId:<process_name>#<UUID>"
+ -- v2: "ErrorId:<process_name> <pid>#<UUID>"
+ STR_SPLIT(SUBSTR(STR_SPLIT(process_counter_track.name, '#', 0), 9), ' ', 0) AS process_name,
+ CAST(STR_SPLIT(SUBSTR(STR_SPLIT(process_counter_track.name, '#', 0), 9), ' ', 1) AS INT32) AS pid,
+ STR_SPLIT(process_counter_track.name, '#', 1) AS error_id,
+ counter.ts
+ FROM process_counter_track
+ JOIN process USING (upid)
+ JOIN counter ON (counter.track_id = process_counter_track.id)
+ WHERE process_counter_track.name GLOB 'ErrorId:*'
+ AND process.name = 'system_server'
+),
+-- ANR subject line.
+anr_subject AS (
+ --- Counter format:
+ --- "Subject(for ErrorId <UUID>):<subject>"
+ SELECT
+ SUBSTR(STR_SPLIT(process_counter_track.name, ')', 0), 21) AS error_id,
+ SUBSTR(process_counter_track.name, length(STR_SPLIT(process_counter_track.name, ')', 0)) + 3) AS subject
+ FROM process_counter_track
+ JOIN process
+ USING (upid)
+ WHERE process_counter_track.name GLOB 'Subject(for ErrorId *'
+ AND process.name = 'system_server'
+)
+SELECT *
+FROM anr_process
+LEFT JOIN anr_subject USING (error_id);
\ No newline at end of file
diff --git a/test/trace_processor/diff_tests/android/android_anr_metric.out b/test/trace_processor/diff_tests/android/android_anr_metric.out
new file mode 100644
index 0000000..306d438
--- /dev/null
+++ b/test/trace_processor/diff_tests/android/android_anr_metric.out
@@ -0,0 +1,20 @@
+android_anr {
+ anr {
+ process_name: "com.google.android.app1"
+ pid: 11167
+ ts: 1000
+ subject: "Test ANR subject 1"
+ error_id: "da24554c-452a-4ae1-b74a-fb898f6e0982"
+ }
+ anr {
+ process_name: "com.google.android.app2"
+ ts: 2000
+ subject: "Test ANR subject 2"
+ error_id: "8612fece-c2f1-4aeb-9d45-8e6d9d0201cf"
+ }
+ anr {
+ process_name: "com.google.android.app3"
+ ts: 3000
+ error_id: "c25916a0-a8f0-41f3-87df-319e06471a0f"
+ }
+}
\ No newline at end of file
diff --git a/test/trace_processor/diff_tests/android/android_anr_metric.py b/test/trace_processor/diff_tests/android/android_anr_metric.py
new file mode 100644
index 0000000..9b624b2
--- /dev/null
+++ b/test/trace_processor/diff_tests/android/android_anr_metric.py
@@ -0,0 +1,73 @@
+#!/usr/bin/env python3
+# Copyright (C) 2023 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+from os import sys
+import synth_common
+
+from google.protobuf import text_format
+
+SS_PID = 1234
+
+trace = synth_common.create_trace()
+
+trace.add_packet()
+trace.add_process(pid=SS_PID, ppid=1, cmdline="system_server", uid=10001)
+
+# Add first ANR.
+trace.add_ftrace_packet(cpu=0)
+trace.add_atrace_counter(
+ ts=1000,
+ pid=SS_PID,
+ tid=SS_PID,
+ buf="ErrorId:com.google.android.app1 11167#da24554c-452a-4ae1-b74a-fb898f6e0982",
+ cnt=1)
+
+trace.add_ftrace_packet(cpu=0)
+trace.add_atrace_counter(
+ ts=1001,
+ tid=SS_PID,
+ pid=SS_PID,
+ buf="Subject(for ErrorId da24554c-452a-4ae1-b74a-fb898f6e0982):Test ANR subject 1",
+ cnt=1)
+
+# Add second ANR.
+# Does not include PID
+trace.add_ftrace_packet(cpu=0)
+trace.add_atrace_counter(
+ ts=2000,
+ pid=SS_PID,
+ tid=SS_PID,
+ buf="ErrorId:com.google.android.app2#8612fece-c2f1-4aeb-9d45-8e6d9d0201cf",
+ cnt=1)
+
+trace.add_ftrace_packet(cpu=0)
+trace.add_atrace_counter(
+ ts=2001,
+ tid=SS_PID,
+ pid=SS_PID,
+ buf="Subject(for ErrorId 8612fece-c2f1-4aeb-9d45-8e6d9d0201cf):Test ANR subject 2",
+ cnt=1)
+
+# Add third ANR.
+# Does not include PID or subject
+trace.add_ftrace_packet(cpu=0)
+trace.add_atrace_counter(
+ ts=3000,
+ pid=SS_PID,
+ tid=SS_PID,
+ buf="ErrorId:com.google.android.app3#c25916a0-a8f0-41f3-87df-319e06471a0f",
+ cnt=1)
+
+sys.stdout.buffer.write(trace.trace.SerializeToString())
diff --git a/test/trace_processor/diff_tests/android/tests.py b/test/trace_processor/diff_tests/android/tests.py
index 0565554..f05f9b1 100644
--- a/test/trace_processor/diff_tests/android/tests.py
+++ b/test/trace_processor/diff_tests/android/tests.py
@@ -277,6 +277,12 @@
""",
out=Path('android_network_activity.out'))
+ def test_anr_metric(self):
+ return DiffTestBlueprint(
+ trace=Path('android_anr_metric.py'),
+ query=Metric('android_anr'),
+ out=Path('android_anr_metric.out'))
+
def test_binder_sync_binder_metrics(self):
return DiffTestBlueprint(
trace=DataPath('android_binder_metric_trace.atr'),