Support protofied dumpsys for NetStats

Bug 34228873
Test: manual tests with "incident_report netstats"

Change-Id: I359b364c64d9798fd4229018a905658d5d46ea5c
This commit is contained in:
Makoto Onuki
2017-01-13 10:23:30 -08:00
parent 601bc9b9a7
commit feb5df9814
6 changed files with 140 additions and 2 deletions

View File

@@ -24,8 +24,10 @@ import android.content.Context;
import android.net.wifi.WifiInfo; import android.net.wifi.WifiInfo;
import android.net.wifi.WifiManager; import android.net.wifi.WifiManager;
import android.os.Build; import android.os.Build;
import android.service.NetworkIdentityProto;
import android.telephony.TelephonyManager; import android.telephony.TelephonyManager;
import android.util.Slog; import android.util.Slog;
import android.util.proto.ProtoOutputStream;
import java.util.Objects; import java.util.Objects;
@@ -110,6 +112,23 @@ public class NetworkIdentity implements Comparable<NetworkIdentity> {
return builder.append("}").toString(); return builder.append("}").toString();
} }
public void writeToProto(ProtoOutputStream proto, long tag) {
final long start = proto.start(tag);
proto.write(NetworkIdentityProto.TYPE, mType);
// Not dumping mSubType, subtypes are no longer supported.
if (mSubscriberId != null) {
proto.write(NetworkIdentityProto.SUBSCRIBER_ID, scrubSubscriberId(mSubscriberId));
}
proto.write(NetworkIdentityProto.NETWORK_ID, mNetworkId);
proto.write(NetworkIdentityProto.ROAMING, mRoaming);
proto.write(NetworkIdentityProto.METERED, mMetered);
proto.end(start);
}
public int getType() { public int getType() {
return mType; return mType;
} }

View File

@@ -31,7 +31,10 @@ import static com.android.internal.util.ArrayUtils.total;
import android.os.Parcel; import android.os.Parcel;
import android.os.Parcelable; import android.os.Parcelable;
import android.service.NetworkStatsHistoryBucketProto;
import android.service.NetworkStatsHistoryProto;
import android.util.MathUtils; import android.util.MathUtils;
import android.util.proto.ProtoOutputStream;
import com.android.internal.util.IndentingPrintWriter; import com.android.internal.util.IndentingPrintWriter;
@@ -628,6 +631,33 @@ public class NetworkStatsHistory implements Parcelable {
} }
} }
public void writeToProto(ProtoOutputStream proto, long tag) {
final long start = proto.start(tag);
proto.write(NetworkStatsHistoryProto.BUCKET_DURATION_MS, bucketDuration);
for (int i = 0; i < bucketCount; i++) {
final long startBucket = proto.start(NetworkStatsHistoryProto.BUCKETS);
proto.write(NetworkStatsHistoryBucketProto.BUCKET_START_MS, bucketStart[i]);
writeToProto(proto, NetworkStatsHistoryBucketProto.RX_BYTES, rxBytes, i);
writeToProto(proto, NetworkStatsHistoryBucketProto.RX_PACKETS, rxPackets, i);
writeToProto(proto, NetworkStatsHistoryBucketProto.TX_BYTES, txBytes, i);
writeToProto(proto, NetworkStatsHistoryBucketProto.TX_PACKETS, txPackets, i);
writeToProto(proto, NetworkStatsHistoryBucketProto.OPERATIONS, operations, i);
proto.end(startBucket);
}
proto.end(start);
}
private static void writeToProto(ProtoOutputStream proto, long tag, long[] array, int index) {
if (array != null) {
proto.write(tag, array[index]);
}
}
@Override @Override
public String toString() { public String toString() {
final CharArrayWriter writer = new CharArrayWriter(); final CharArrayWriter writer = new CharArrayWriter();

View File

@@ -17,6 +17,8 @@
package com.android.server.net; package com.android.server.net;
import android.net.NetworkIdentity; import android.net.NetworkIdentity;
import android.service.NetworkIdentitySetProto;
import android.util.proto.ProtoOutputStream;
import java.io.DataInputStream; import java.io.DataInputStream;
import java.io.DataOutputStream; import java.io.DataOutputStream;
@@ -143,4 +145,14 @@ public class NetworkIdentitySet extends HashSet<NetworkIdentity> implements
final NetworkIdentity anotherIdent = another.iterator().next(); final NetworkIdentity anotherIdent = another.iterator().next();
return ident.compareTo(anotherIdent); return ident.compareTo(anotherIdent);
} }
public void writeToProto(ProtoOutputStream proto, long tag) {
final long start = proto.start(tag);
for (NetworkIdentity ident : this) {
ident.writeToProto(proto, NetworkIdentitySetProto.IDENTITIES);
}
proto.end(start);
}
} }

View File

@@ -34,9 +34,13 @@ import android.net.NetworkStatsHistory;
import android.net.NetworkTemplate; import android.net.NetworkTemplate;
import android.net.TrafficStats; import android.net.TrafficStats;
import android.os.Binder; import android.os.Binder;
import android.service.NetworkStatsCollectionKeyProto;
import android.service.NetworkStatsCollectionProto;
import android.service.NetworkStatsCollectionStatsProto;
import android.util.ArrayMap; import android.util.ArrayMap;
import android.util.AtomicFile; import android.util.AtomicFile;
import android.util.IntArray; import android.util.IntArray;
import android.util.proto.ProtoOutputStream;
import com.android.internal.util.ArrayUtils; import com.android.internal.util.ArrayUtils;
import com.android.internal.util.FileRotator; import com.android.internal.util.FileRotator;
@@ -532,12 +536,15 @@ public class NetworkStatsCollection implements FileRotator.Reader {
/ mBucketDuration); / mBucketDuration);
} }
public void dump(IndentingPrintWriter pw) { private ArrayList<Key> getSortedKeys() {
final ArrayList<Key> keys = Lists.newArrayList(); final ArrayList<Key> keys = Lists.newArrayList();
keys.addAll(mStats.keySet()); keys.addAll(mStats.keySet());
Collections.sort(keys); Collections.sort(keys);
return keys;
}
for (Key key : keys) { public void dump(IndentingPrintWriter pw) {
for (Key key : getSortedKeys()) {
pw.print("ident="); pw.print(key.ident.toString()); pw.print("ident="); pw.print(key.ident.toString());
pw.print(" uid="); pw.print(key.uid); pw.print(" uid="); pw.print(key.uid);
pw.print(" set="); pw.print(NetworkStats.setToString(key.set)); pw.print(" set="); pw.print(NetworkStats.setToString(key.set));
@@ -550,6 +557,29 @@ public class NetworkStatsCollection implements FileRotator.Reader {
} }
} }
public void writeToProto(ProtoOutputStream proto, long tag) {
final long start = proto.start(tag);
for (Key key : getSortedKeys()) {
final long startStats = proto.start(NetworkStatsCollectionProto.STATS);
// Key
final long startKey = proto.start(NetworkStatsCollectionStatsProto.KEY);
key.ident.writeToProto(proto, NetworkStatsCollectionKeyProto.IDENTITY);
proto.write(NetworkStatsCollectionKeyProto.UID, key.uid);
proto.write(NetworkStatsCollectionKeyProto.SET, key.set);
proto.write(NetworkStatsCollectionKeyProto.TAG, key.tag);
proto.end(startKey);
// Value
final NetworkStatsHistory history = mStats.get(key);
history.writeToProto(proto, NetworkStatsCollectionStatsProto.HISTORY);
proto.end(startStats);
}
proto.end(start);
}
public void dumpCheckin(PrintWriter pw, long start, long end) { public void dumpCheckin(PrintWriter pw, long start, long end) {
dumpCheckin(pw, start, end, NetworkTemplate.buildTemplateMobileWildcard(), "cell"); dumpCheckin(pw, start, end, NetworkTemplate.buildTemplateMobileWildcard(), "cell");
dumpCheckin(pw, start, end, NetworkTemplate.buildTemplateWifiWildcard(), "wifi"); dumpCheckin(pw, start, end, NetworkTemplate.buildTemplateWifiWildcard(), "wifi");

View File

@@ -29,9 +29,11 @@ import android.net.NetworkStatsHistory;
import android.net.NetworkTemplate; import android.net.NetworkTemplate;
import android.net.TrafficStats; import android.net.TrafficStats;
import android.os.DropBoxManager; import android.os.DropBoxManager;
import android.service.NetworkStatsRecorderProto;
import android.util.Log; import android.util.Log;
import android.util.MathUtils; import android.util.MathUtils;
import android.util.Slog; import android.util.Slog;
import android.util.proto.ProtoOutputStream;
import com.android.internal.net.VpnInfo; import com.android.internal.net.VpnInfo;
import com.android.internal.util.FileRotator; import com.android.internal.util.FileRotator;
@@ -465,6 +467,15 @@ public class NetworkStatsRecorder {
} }
} }
public void writeToProtoLocked(ProtoOutputStream proto, long tag) {
final long start = proto.start(tag);
if (mPending != null) {
proto.write(NetworkStatsRecorderProto.PENDING_TOTAL_BYTES, mPending.getTotalBytes());
}
getOrLoadCompleteLocked().writeToProto(proto, NetworkStatsRecorderProto.COMPLETE_HISTORY);
proto.end(start);
}
public void dumpCheckin(PrintWriter pw, long start, long end) { public void dumpCheckin(PrintWriter pw, long start, long end) {
// Only load and dump stats from the requested window // Only load and dump stats from the requested window
getOrLoadPartialLocked(start, end).dumpCheckin(pw, start, end); getOrLoadPartialLocked(start, end).dumpCheckin(pw, start, end);

View File

@@ -104,6 +104,8 @@ import android.os.SystemClock;
import android.os.UserHandle; import android.os.UserHandle;
import android.provider.Settings; import android.provider.Settings;
import android.provider.Settings.Global; import android.provider.Settings.Global;
import android.service.NetworkInterfaceProto;
import android.service.NetworkStatsServiceDumpProto;
import android.telephony.TelephonyManager; import android.telephony.TelephonyManager;
import android.text.format.DateUtils; import android.text.format.DateUtils;
import android.util.ArrayMap; import android.util.ArrayMap;
@@ -115,6 +117,7 @@ import android.util.NtpTrustedTime;
import android.util.Slog; import android.util.Slog;
import android.util.SparseIntArray; import android.util.SparseIntArray;
import android.util.TrustedTime; import android.util.TrustedTime;
import android.util.proto.ProtoOutputStream;
import com.android.internal.annotations.VisibleForTesting; import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.net.VpnInfo; import com.android.internal.net.VpnInfo;
@@ -1255,6 +1258,12 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
final IndentingPrintWriter pw = new IndentingPrintWriter(rawWriter, " "); final IndentingPrintWriter pw = new IndentingPrintWriter(rawWriter, " ");
synchronized (mStatsLock) { synchronized (mStatsLock) {
if (args.length > 0 && "--proto".equals(args[0])) {
// In this case ignore all other arguments.
dumpProto(fd);
return;
}
if (poll) { if (poll) {
performPollLocked(FLAG_PERSIST_ALL | FLAG_PERSIST_FORCE); performPollLocked(FLAG_PERSIST_ALL | FLAG_PERSIST_FORCE);
pw.println("Forced poll"); pw.println("Forced poll");
@@ -1327,6 +1336,33 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
} }
} }
private void dumpProto(FileDescriptor fd) {
final ProtoOutputStream proto = new ProtoOutputStream(fd);
// TODO Right now it writes all history. Should it limit to the "since-boot" log?
dumpInterfaces(proto, NetworkStatsServiceDumpProto.ACTIVE_INTERFACES, mActiveIfaces);
dumpInterfaces(proto, NetworkStatsServiceDumpProto.ACTIVE_UID_INTERFACES, mActiveUidIfaces);
mDevRecorder.writeToProtoLocked(proto, NetworkStatsServiceDumpProto.DEV_STATS);
mXtRecorder.writeToProtoLocked(proto, NetworkStatsServiceDumpProto.XT_STATS);
mUidRecorder.writeToProtoLocked(proto, NetworkStatsServiceDumpProto.UID_STATS);
mUidTagRecorder.writeToProtoLocked(proto, NetworkStatsServiceDumpProto.UID_TAG_STATS);
proto.flush();
}
private static void dumpInterfaces(ProtoOutputStream proto, long tag,
ArrayMap<String, NetworkIdentitySet> ifaces) {
for (int i = 0; i < ifaces.size(); i++) {
final long start = proto.start(tag);
proto.write(NetworkInterfaceProto.INTERFACE, ifaces.keyAt(i));
ifaces.valueAt(i).writeToProto(proto, NetworkInterfaceProto.IDENTITIES);
proto.end(start);
}
}
/** /**
* Return snapshot of current UID statistics, including any * Return snapshot of current UID statistics, including any
* {@link TrafficStats#UID_TETHERING} and {@link #mUidOperations} values. * {@link TrafficStats#UID_TETHERING} and {@link #mUidOperations} values.