From: Hugo Benichi Date: Tue, 23 Jan 2018 02:43:16 +0000 (+0900) Subject: Tcp socket metrics: implement INetdEventListener callback X-Git-Tag: android-x86-9.0-r1~241^2~2^2~8^2~10^2^2 X-Git-Url: http://git.osdn.net/view?a=commitdiff_plain;h=f90773cf4f47b93f98f361985c8c7663e79b3d5a;p=android-x86%2Fframeworks-base.git Tcp socket metrics: implement INetdEventListener callback 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 --- diff --git a/core/java/android/net/metrics/NetworkMetrics.java b/core/java/android/net/metrics/NetworkMetrics.java index 2b662a0c28e2..2425bba9e668 100644 --- a/core/java/android/net/metrics/NetworkMetrics.java +++ b/core/java/android/net/metrics/NetworkMetrics.java @@ -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); } diff --git a/services/core/java/com/android/server/connectivity/NetdEventListenerService.java b/services/core/java/com/android/server/connectivity/NetdEventListenerService.java index 25b52da3b9bb..e786bed53d20 100644 --- a/services/core/java/com/android/server/connectivity/NetdEventListenerService.java +++ b/services/core/java/com/android/server/connectivity/NetdEventListenerService.java @@ -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);