Dump connmetrics in protobuf format
Add protobuf dumpsys of connmetrics. Primarily used by incident service
to capture an incident report proto.
Currently, "proto" is used to dump the ring buffer in base64-encoded
proto. The newly added "--proto" arg is a dumpsys convention to dump
a service in proto wire format. This change reuses most of the code
for executing "proto". Other cmds remain unchanged.
Command to invoke (any of the following after lunch and env setup):
$ adb shell dumpsys connmetrics --proto
$ incident_report 3049
Bug: 146086778
Test: $ incident_report 3049, then compare the content with "dumpsys
connmetrics"
Change-Id: Ief2297d99aeb553224a83894ba3b9695ff0b87aa
diff --git a/Android.bp b/Android.bp
index 908274d..b7ca9a6 100644
--- a/Android.bp
+++ b/Android.bp
@@ -597,6 +597,7 @@
"&& $(location soong_zip) -jar -o $(out) -C $(genDir)/$(in) -D $(genDir)/$(in)",
srcs: [
+ ":ipconnectivity-proto-src",
"core/proto/**/*.proto",
"libs/incident/**/*.proto",
],
@@ -707,6 +708,7 @@
java_library_host {
name: "platformprotos",
srcs: [
+ ":ipconnectivity-proto-src",
"cmds/am/proto/instrumentation_data.proto",
"cmds/statsd/src/**/*.proto",
"core/proto/**/*.proto",
@@ -735,6 +737,7 @@
],
sdk_version: "9",
srcs: [
+ ":ipconnectivity-proto-src",
"core/proto/**/*.proto",
"libs/incident/proto/android/os/**/*.proto",
],
@@ -749,6 +752,7 @@
},
srcs: [
+ ":ipconnectivity-proto-src",
"core/proto/**/*.proto",
"libs/incident/proto/android/os/**/*.proto",
],
@@ -779,6 +783,7 @@
],
srcs: [
+ ":ipconnectivity-proto-src",
"core/proto/**/*.proto",
],
}
diff --git a/core/proto/android/os/incident.proto b/core/proto/android/os/incident.proto
index 8f9c041..1482a3b 100644
--- a/core/proto/android/os/incident.proto
+++ b/core/proto/android/os/incident.proto
@@ -56,6 +56,7 @@
import "frameworks/base/core/proto/android/util/log.proto";
import "frameworks/base/core/proto/android/privacy.proto";
import "frameworks/base/core/proto/android/section.proto";
+import "frameworks/base/proto/src/ipconnectivity.proto";
package android.os;
@@ -475,6 +476,11 @@
(section).args = "cpuinfo --proto"
];
+ optional .clearcut.connectivity.IpConnectivityLog ip_connectivity_metrics = 3049 [
+ (section).type = SECTION_DUMPSYS,
+ (section).args = "connmetrics --proto"
+ ];
+
// Reserved for OEMs.
extensions 50000 to 100000;
}
diff --git a/proto/Android.bp b/proto/Android.bp
index 7cf6ce7..01a72ea 100644
--- a/proto/Android.bp
+++ b/proto/Android.bp
@@ -32,3 +32,8 @@
name: "system-messages-proto-src",
srcs: ["src/system_messages.proto"],
}
+
+filegroup {
+ name: "ipconnectivity-proto-src",
+ srcs: ["src/ipconnectivity.proto"],
+}
diff --git a/services/core/java/com/android/server/connectivity/DefaultNetworkMetrics.java b/services/core/java/com/android/server/connectivity/DefaultNetworkMetrics.java
index 96a202f..299cb66 100644
--- a/services/core/java/com/android/server/connectivity/DefaultNetworkMetrics.java
+++ b/services/core/java/com/android/server/connectivity/DefaultNetworkMetrics.java
@@ -81,9 +81,12 @@
printEvent(localTimeMs, pw, mCurrentDefaultNetwork);
}
- public synchronized void listEventsAsProto(PrintWriter pw) {
+ /**
+ * Convert events in the ring buffer to protos and add to the given list
+ */
+ public synchronized void listEventsAsProto(List<IpConnectivityEvent> out) {
for (DefaultNetworkEvent ev : mEventsLog.toArray()) {
- pw.print(IpConnectivityEventBuilder.toProto(ev));
+ out.add(IpConnectivityEventBuilder.toProto(ev));
}
}
diff --git a/services/core/java/com/android/server/connectivity/IpConnectivityMetrics.java b/services/core/java/com/android/server/connectivity/IpConnectivityMetrics.java
index 33f6ed5..1337a93 100644
--- a/services/core/java/com/android/server/connectivity/IpConnectivityMetrics.java
+++ b/services/core/java/com/android/server/connectivity/IpConnectivityMetrics.java
@@ -41,7 +41,9 @@
import com.android.server.connectivity.metrics.nano.IpConnectivityLogClass.IpConnectivityEvent;
import java.io.FileDescriptor;
+import java.io.FileOutputStream;
import java.io.IOException;
+import java.io.OutputStream;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Arrays;
@@ -239,18 +241,37 @@
mDefaultNetworkMetrics.listEvents(pw);
}
+ private List<IpConnectivityEvent> listEventsAsProtos() {
+ final List<IpConnectivityEvent> events = IpConnectivityEventBuilder.toProto(getEvents());
+ if (mNetdListener != null) {
+ mNetdListener.listAsProtos(events);
+ }
+ mDefaultNetworkMetrics.listEventsAsProto(events);
+ return events;
+ }
+
/*
* Print the content of the rolling event buffer in text proto format.
*/
- private void cmdListAsProto(PrintWriter pw) {
- final List<ConnectivityMetricsEvent> events = getEvents();
- for (IpConnectivityEvent ev : IpConnectivityEventBuilder.toProto(events)) {
- pw.print(ev.toString());
+ private void cmdListAsTextProto(PrintWriter pw) {
+ listEventsAsProtos().forEach(e -> pw.print(e.toString()));
+ }
+
+ /*
+ * Write the content of the rolling event buffer in proto wire format to the given OutputStream.
+ */
+ private void cmdListAsBinaryProto(OutputStream out) {
+ final int dropped;
+ synchronized (mLock) {
+ dropped = mDropped;
}
- if (mNetdListener != null) {
- mNetdListener.listAsProtos(pw);
+ try {
+ byte[] data = IpConnectivityEventBuilder.serialize(dropped, listEventsAsProtos());
+ out.write(data);
+ out.flush();
+ } catch (IOException e) {
+ Log.e(TAG, "could not serialize events", e);
}
- mDefaultNetworkMetrics.listEventsAsProto(pw);
}
/*
@@ -267,6 +288,9 @@
static final String CMD_FLUSH = "flush";
// Dump the rolling buffer of metrics event in human readable proto text format.
static final String CMD_PROTO = "proto";
+ // Dump the rolling buffer of metrics event in proto wire format. See usage() of
+ // frameworks/native/cmds/dumpsys/dumpsys.cpp for details.
+ static final String CMD_PROTO_BIN = "--proto";
// Dump the rolling buffer of metrics event and pretty print events using a human readable
// format. Also print network dns/connect statistics and default network event time series.
static final String CMD_LIST = "list";
@@ -291,7 +315,10 @@
cmdFlush(pw);
return;
case CMD_PROTO:
- cmdListAsProto(pw);
+ cmdListAsTextProto(pw);
+ return;
+ case CMD_PROTO_BIN:
+ cmdListAsBinaryProto(new FileOutputStream(fd));
return;
case CMD_LIST:
default:
diff --git a/services/core/java/com/android/server/connectivity/NetdEventListenerService.java b/services/core/java/com/android/server/connectivity/NetdEventListenerService.java
index dbc339b..0d31051 100644
--- a/services/core/java/com/android/server/connectivity/NetdEventListenerService.java
+++ b/services/core/java/com/android/server/connectivity/NetdEventListenerService.java
@@ -366,15 +366,18 @@
}
}
- public synchronized void listAsProtos(PrintWriter pw) {
+ /**
+ * Convert events in the buffer to protos and add to the given list
+ */
+ public synchronized void listAsProtos(List<IpConnectivityEvent> out) {
for (int i = 0; i < mNetworkMetrics.size(); i++) {
- pw.print(IpConnectivityEventBuilder.toProto(mNetworkMetrics.valueAt(i).connectMetrics));
+ out.add(IpConnectivityEventBuilder.toProto(mNetworkMetrics.valueAt(i).connectMetrics));
}
for (int i = 0; i < mNetworkMetrics.size(); i++) {
- pw.print(IpConnectivityEventBuilder.toProto(mNetworkMetrics.valueAt(i).dnsMetrics));
+ out.add(IpConnectivityEventBuilder.toProto(mNetworkMetrics.valueAt(i).dnsMetrics));
}
for (int i = 0; i < mWakeupStats.size(); i++) {
- pw.print(IpConnectivityEventBuilder.toProto(mWakeupStats.valueAt(i)));
+ out.add(IpConnectivityEventBuilder.toProto(mWakeupStats.valueAt(i)));
}
}