Recover from Throwable in FileRotator, dump.

In rewriteSingle(), catch Throwable to rollback to backup file,
instead of just IOException. Also add dumpAll() to pack up contents
for later debugging, and use it when encountering bad stats.

Bug: 6467868
Change-Id: Ic8e287cf5a235706811a304a88d71d11d3a79cd4
This commit is contained in:
Jeff Sharkey
2012-05-09 13:33:52 -07:00
parent 24a69bbd60
commit 585bc91d22
2 changed files with 39 additions and 2 deletions

View File

@@ -26,6 +26,7 @@ import android.net.NetworkStats.NonMonotonicObserver;
import android.net.NetworkStatsHistory;
import android.net.NetworkTemplate;
import android.net.TrafficStats;
import android.os.DropBoxManager;
import android.util.Log;
import android.util.MathUtils;
import android.util.Slog;
@@ -34,6 +35,7 @@ import com.android.internal.util.FileRotator;
import com.android.internal.util.IndentingPrintWriter;
import com.google.android.collect.Sets;
import java.io.ByteArrayOutputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.IOException;
@@ -43,6 +45,8 @@ import java.lang.ref.WeakReference;
import java.util.HashSet;
import java.util.Map;
import libcore.io.IoUtils;
/**
* Logic to record deltas between periodic {@link NetworkStats} snapshots into
* {@link NetworkStatsHistory} that belong to {@link NetworkStatsCollection}.
@@ -56,8 +60,14 @@ public class NetworkStatsRecorder {
private static final boolean LOGD = false;
private static final boolean LOGV = false;
private static final String TAG_NETSTATS_DUMP = "netstats_dump";
/** Dump before deleting in {@link #recoverFromWtf()}. */
private static final boolean DUMP_BEFORE_DELETE = true;
private final FileRotator mRotator;
private final NonMonotonicObserver<String> mObserver;
private final DropBoxManager mDropBox;
private final String mCookie;
private final long mBucketDuration;
@@ -74,9 +84,10 @@ public class NetworkStatsRecorder {
private WeakReference<NetworkStatsCollection> mComplete;
public NetworkStatsRecorder(FileRotator rotator, NonMonotonicObserver<String> observer,
String cookie, long bucketDuration, boolean onlyTags) {
DropBoxManager dropBox, String cookie, long bucketDuration, boolean onlyTags) {
mRotator = checkNotNull(rotator, "missing FileRotator");
mObserver = checkNotNull(observer, "missing NonMonotonicObserver");
mDropBox = checkNotNull(dropBox, "missing DropBoxManager");
mCookie = cookie;
mBucketDuration = bucketDuration;
@@ -122,6 +133,7 @@ public class NetworkStatsRecorder {
mComplete = new WeakReference<NetworkStatsCollection>(complete);
} catch (IOException e) {
Log.wtf(TAG, "problem completely reading network stats", e);
recoverFromWtf();
}
}
return complete;
@@ -212,6 +224,7 @@ public class NetworkStatsRecorder {
mPending.reset();
} catch (IOException e) {
Log.wtf(TAG, "problem persisting pending stats", e);
recoverFromWtf();
}
}
}
@@ -226,6 +239,7 @@ public class NetworkStatsRecorder {
mRotator.rewriteAll(new RemoveUidRewriter(mBucketDuration, uid));
} catch (IOException e) {
Log.wtf(TAG, "problem removing UID " + uid, e);
recoverFromWtf();
}
// clear UID from current stats snapshot
@@ -355,4 +369,25 @@ public class NetworkStatsRecorder {
mSinceBoot.dump(pw);
}
}
/**
* Recover from {@link FileRotator} failure by dumping state to
* {@link DropBoxManager} and deleting contents.
*/
private void recoverFromWtf() {
if (DUMP_BEFORE_DELETE) {
final ByteArrayOutputStream os = new ByteArrayOutputStream();
try {
mRotator.dumpAll(os);
} catch (IOException e) {
// ignore partial contents
os.reset();
} finally {
IoUtils.closeQuietly(os);
}
mDropBox.addData(TAG_NETSTATS_DUMP, os.toByteArray(), 0);
}
mRotator.deleteAll();
}
}

View File

@@ -338,9 +338,11 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
private NetworkStatsRecorder buildRecorder(
String prefix, NetworkStatsSettings.Config config, boolean includeTags) {
final DropBoxManager dropBox = (DropBoxManager) mContext.getSystemService(
Context.DROPBOX_SERVICE);
return new NetworkStatsRecorder(new FileRotator(
mBaseDir, prefix, config.rotateAgeMillis, config.deleteAgeMillis),
mNonMonotonicObserver, prefix, config.bucketDuration, includeTags);
mNonMonotonicObserver, dropBox, prefix, config.bucketDuration, includeTags);
}
private void shutdownLocked() {