OSDN Git Service

Tcp socket metrics: implement INetdEventListener callback
authorHugo Benichi <hugobenichi@google.com>
Tue, 23 Jan 2018 02:43:16 +0000 (11:43 +0900)
committerHugo Benichi <hugobenichi@google.com>
Thu, 25 Jan 2018 04:26:43 +0000 (13:26 +0900)
This patch implements the new INetdEventListener.onTcpSocketStatsEvent
callback added in INetdEventListener.

For the time being, tcp socket stats are tracked inside TcpMetrics only
for dumpsys printing and bug report integration as a first step.

Bug: 64147860
Test: manually tested, watching output of
      $ adb shell dumpsys connmetrics
Change-Id: I10ab24c6da4bb654d9198a4d8d00ccdc972cc0d5

core/java/android/net/metrics/NetworkMetrics.java
services/core/java/com/android/server/connectivity/NetdEventListenerService.java

index 2b662a0..2425bba 100644 (file)
@@ -96,6 +96,13 @@ public class NetworkMetrics {
         }
     }
 
+    /** Accumulate a single netd sock_diag poll result reported by netd. */
+    public void addTcpStatsResult(int sent, int lost, int rttUs, int sentAckDiffMs) {
+        pendingSummary.tcpLossRate.count(lost, sent);
+        pendingSummary.roundTripTimeUs.count(rttUs);
+        pendingSummary.sentAckTimeDiffenceMs.count(sentAckDiffMs);
+    }
+
     /** Represents running sums for dns and connect average error counts and average latencies. */
     public static class Summary {
 
@@ -109,6 +116,13 @@ public class NetworkMetrics {
         public final Metrics connectLatencies = new Metrics();
         // Blocking and non blocking connect error rate measured in percentage points.
         public final Metrics connectErrorRate = new Metrics();
+        // TCP socket packet loss stats collected from Netlink sock_diag.
+        public final Metrics tcpLossRate = new Metrics();
+        // TCP averaged microsecond round-trip-time stats collected from Netlink sock_diag.
+        public final Metrics roundTripTimeUs = new Metrics();
+        // TCP stats collected from Netlink sock_diag that averages millisecond per-socket
+        // differences between last packet sent timestamp and last ack received timestamp.
+        public final Metrics sentAckTimeDiffenceMs = new Metrics();
 
         public Summary(int netId, long transports) {
             this.netId = netId;
@@ -120,6 +134,7 @@ public class NetworkMetrics {
             dnsErrorRate.merge(that.dnsErrorRate);
             connectLatencies.merge(that.connectLatencies);
             connectErrorRate.merge(that.connectErrorRate);
+            tcpLossRate.merge(that.tcpLossRate);
         }
 
         @Override
@@ -135,6 +150,10 @@ public class NetworkMetrics {
             j.add(String.format("connect avg=%dms max=%dms err=%.1f%% tot=%d",
                     (int) connectLatencies.average(), (int) connectLatencies.max,
                     100 * connectErrorRate.average(), connectErrorRate.count));
+            j.add(String.format("tcp avg_loss=%.1f%% total_sent=%d total_lost=%d",
+                    100 * tcpLossRate.average(), tcpLossRate.count, (int) tcpLossRate.sum));
+            j.add(String.format("tcp rtt=%dms", (int) (roundTripTimeUs.average() / 1000)));
+            j.add(String.format("tcp sent-ack_diff=%dms", (int) sentAckTimeDiffenceMs.average()));
             return j.toString();
         }
     }
@@ -152,7 +171,11 @@ public class NetworkMetrics {
         }
 
         void count(double value) {
-            count++;
+            count(value, 1);
+        }
+
+        void count(double value, int subcount) {
+            count += subcount;
             sum += value;
             max = Math.max(max, value);
         }
index 25b52da..e786bed 100644 (file)
@@ -252,6 +252,29 @@ public class NetdEventListenerService extends INetdEventListener.Stub {
         addWakeupEvent(event);
     }
 
+    @Override
+    public synchronized void onTcpSocketStatsEvent(int[] networkIds,
+            int[] sentPackets, int[] lostPackets, int[] rttsUs, int[] sentAckDiffsMs) {
+        if (networkIds.length != sentPackets.length
+                || networkIds.length != lostPackets.length
+                || networkIds.length != rttsUs.length
+                || networkIds.length != sentAckDiffsMs.length) {
+            Log.e(TAG, "Mismatched lengths of TCP socket stats data arrays");
+            return;
+        }
+
+        long timestamp = System.currentTimeMillis();
+        for (int i = 0; i < networkIds.length; i++) {
+            int netId = networkIds[i];
+            int sent = sentPackets[i];
+            int lost = lostPackets[i];
+            int rttUs = rttsUs[i];
+            int sentAckDiffMs = sentAckDiffsMs[i];
+            getMetricsForNetwork(timestamp, netId)
+                    .addTcpStatsResult(sent, lost, rttUs, sentAckDiffMs);
+        }
+    }
+
     private void addWakeupEvent(WakeupEvent event) {
         String iface = event.iface;
         mWakeupEvents.append(event);