diff options
| author | 2018-09-06 00:39:57 +0000 | |
|---|---|---|
| committer | 2018-09-06 10:32:01 -0700 | |
| commit | 86dc9dba06aa74601732bc7daa7961aa47c4e5ca (patch) | |
| tree | 73232d2db4960e0556cd3418fdaeed933b44f56d | |
| parent | 601622ab5c5465a31cc9ace86f89530fc390bba4 (diff) | |
Revert "Revert "DiskStats Westworld Migration""
This reverts commit 6188aa32946f6372f912ccc9281956ca38a8a264.
Reason for revert: ag/4819964 has now been submitted. undoing the roll back.
Test: revert
Test: manually verified output is the same as diskstats.
Change-Id: I9a3292f66e1e28661e1d29f3befd002073b681c1
| -rw-r--r-- | cmds/statsd/src/atoms.proto | 85 | ||||
| -rw-r--r-- | cmds/statsd/src/external/StatsPullerManager.cpp | 29 | ||||
| -rw-r--r-- | core/java/android/os/StatsLogEventWrapper.java | 9 | ||||
| -rw-r--r-- | services/core/java/com/android/server/stats/StatsCompanionService.java | 217 |
4 files changed, 323 insertions, 17 deletions
diff --git a/cmds/statsd/src/atoms.proto b/cmds/statsd/src/atoms.proto index 2ecfbe733bca..27b44423c1eb 100644 --- a/cmds/statsd/src/atoms.proto +++ b/cmds/statsd/src/atoms.proto @@ -153,13 +153,17 @@ message Atom { SystemUptime system_uptime = 10015; CpuActiveTime cpu_active_time = 10016; CpuClusterTime cpu_cluster_time = 10017; - DiskSpace disk_space = 10018; + DiskSpace disk_space = 10018 [deprecated=true]; RemainingBatteryCapacity remaining_battery_capacity = 10019; FullBatteryCapacity full_battery_capacity = 10020; Temperature temperature = 10021; BinderCalls binder_calls = 10022; BinderCallsExceptions binder_calls_exceptions = 10023; LooperStats looper_stats = 10024; + DiskStats disk_stats = 10025; + DirectoryUsage directory_usage = 10026; + AppSize app_size = 10027; + CategorySize category_size = 10028; } // DO NOT USE field numbers above 100,000 in AOSP. Field numbers above @@ -2251,3 +2255,82 @@ message LooperStats { // recorded_total_cpu_micros / recorded_message_count * call_count. optional int64 recorded_total_cpu_micros = 9; } + +/** + * Pulls disk information, such as write speed and latency. + */ +message DiskStats { + // Time taken to open, write 512B to, and close a file. + // -1 if error performing the check. + optional int64 data_write_latency_millis = 1; + + optional bool file_based_encryption = 2; + + // Recent disk write speed in kB/s. + // -1 if error querying storageed. + // 0 if data is unavailable. + optional int32 recent_disk_write_speed = 3; +} + + +/** + * Free and total bytes of the Data, Cache, and System partition. + */ +message DirectoryUsage { + enum Directory { + UNKNOWN = 0; + DATA = 1; + CACHE = 2; + SYSTEM = 3; + } + optional Directory directory = 1; + optional int64 free_bytes = 2; + optional int64 total_bytes = 3; +} + + +/** + * Size of an application: apk size, data size, and cache size. + * Reads from a cached file produced daily by DiskStatsLoggingService.java. + * Information is only reported for apps with the primary user (user 0). + * Sizes are aggregated by package name. + */ +message AppSize { + // Including uids will involve modifying diskstats logic. + optional string package_name = 1; + // App size in bytes. -1 if unavailable. + optional int64 app_size_bytes = 2; + // App data size in bytes. -1 if unavailable. + optional int64 app_data_size_bytes = 3; + // App cache size in bytes. -1 if unavailable. + optional int64 app_cache_size_bytes = 4; + // Time that the cache file was produced. + // Uses System.currentTimeMillis(), which is wall clock time. + optional int64 cache_time_millis = 5; +} + + +/** + * Size of a particular category. Eg: photos, videos. + * Reads from a cached file produced daily by DiskStatsLoggingService.java. + */ +message CategorySize { + enum Category { + UNKNOWN = 0; + APP_SIZE = 1; + APP_DATA_SIZE = 2; + APP_CACHE_SIZE = 3; + PHOTOS = 4; + VIDEOS = 5; + AUDIO = 6; + DOWNLOADS = 7; + SYSTEM = 8; + OTHER = 9; + } + optional Category category = 1; + // Category size in bytes. + optional int64 size_bytes = 2; + // Time that the cache file was produced. + // Uses System.currentTimeMillis(), which is wall clock time. + optional int64 cache_time_millis = 3; +} diff --git a/cmds/statsd/src/external/StatsPullerManager.cpp b/cmds/statsd/src/external/StatsPullerManager.cpp index 28718823bb32..dbc13dc36ea7 100644 --- a/cmds/statsd/src/external/StatsPullerManager.cpp +++ b/cmds/statsd/src/external/StatsPullerManager.cpp @@ -149,9 +149,6 @@ const std::map<int, PullAtomInfo> StatsPullerManager::kAllPullAtomInfo = { // system_uptime {android::util::SYSTEM_UPTIME, {{}, {}, 1 * NS_PER_SEC, new StatsCompanionServicePuller(android::util::SYSTEM_UPTIME)}}, - // disk_space - {android::util::DISK_SPACE, - {{}, {}, 1 * NS_PER_SEC, new StatsCompanionServicePuller(android::util::DISK_SPACE)}}, // remaining_battery_capacity {android::util::REMAINING_BATTERY_CAPACITY, {{}, @@ -189,7 +186,31 @@ const std::map<int, PullAtomInfo> StatsPullerManager::kAllPullAtomInfo = { {{5, 6, 7, 8, 9}, {2, 3, 4}, 1 * NS_PER_SEC, - new StatsCompanionServicePuller(android::util::LOOPER_STATS)}} + new StatsCompanionServicePuller(android::util::LOOPER_STATS)}}, + // Disk Stats + {android::util::DISK_STATS, + {{}, + {}, + 1 * NS_PER_SEC, + new StatsCompanionServicePuller(android::util::DISK_STATS)}}, + // Directory usage + {android::util::DIRECTORY_USAGE, + {{}, + {}, + 1 * NS_PER_SEC, + new StatsCompanionServicePuller(android::util::DIRECTORY_USAGE)}}, + // Size of app's code, data, and cache + {android::util::APP_SIZE, + {{}, + {}, + 1 * NS_PER_SEC, + new StatsCompanionServicePuller(android::util::APP_SIZE)}}, + // Size of specific categories of files. Eg. Music. + {android::util::CATEGORY_SIZE, + {{}, + {}, + 1 * NS_PER_SEC, + new StatsCompanionServicePuller(android::util::CATEGORY_SIZE)}}, }; StatsPullerManager::StatsPullerManager() : mNextPullTimeNs(NO_ALARM_UPDATE) { diff --git a/core/java/android/os/StatsLogEventWrapper.java b/core/java/android/os/StatsLogEventWrapper.java index 7b3ea57ba0e9..b13bcac699ed 100644 --- a/core/java/android/os/StatsLogEventWrapper.java +++ b/core/java/android/os/StatsLogEventWrapper.java @@ -127,6 +127,15 @@ public final class StatsLogEventWrapper implements Parcelable { } /** + * Adds a boolean by adding either a 1 or 0 to the output. + */ + public void writeBoolean(boolean val) { + int toWrite = val ? 1 : 0; + mStorage.write(EVENT_TYPE_INT); + write4Bytes(toWrite); + } + + /** * Writes the stored fields to a byte array. Will first write a new-line character to denote * END_LIST before writing contents to byte array. */ diff --git a/services/core/java/com/android/server/stats/StatsCompanionService.java b/services/core/java/com/android/server/stats/StatsCompanionService.java index b922e40a5d38..6f9d8033cd88 100644 --- a/services/core/java/com/android/server/stats/StatsCompanionService.java +++ b/services/core/java/com/android/server/stats/StatsCompanionService.java @@ -43,6 +43,7 @@ import android.os.FileUtils; import android.os.IBinder; import android.os.IStatsCompanionService; import android.os.IStatsManager; +import android.os.IStoraged; import android.os.Parcelable; import android.os.Process; import android.os.RemoteException; @@ -54,6 +55,7 @@ import android.os.SynchronousResultReceiver; import android.os.SystemClock; import android.os.UserHandle; import android.os.UserManager; +import android.os.storage.StorageManager; import android.telephony.ModemActivityInfo; import android.telephony.TelephonyManager; import android.util.ArrayMap; @@ -76,9 +78,19 @@ import com.android.internal.util.DumpUtils; import com.android.server.BinderCallsStatsService; import com.android.server.LocalServices; import com.android.server.SystemService; +import com.android.server.storage.DiskStatsFileLogger; +import com.android.server.storage.DiskStatsLoggingService; + +import libcore.io.IoUtils; + +import org.json.JSONArray; +import org.json.JSONException; +import org.json.JSONObject; import java.io.File; import java.io.FileDescriptor; +import java.io.FileOutputStream; +import java.io.IOException; import java.io.PrintWriter; import java.util.ArrayList; import java.util.Arrays; @@ -861,14 +873,6 @@ public class StatsCompanionService extends IStatsCompanionService.Stub { pulledData.add(e); } - private void pullDiskSpace(int tagId, List<StatsLogEventWrapper> pulledData) { - StatsLogEventWrapper e = new StatsLogEventWrapper(SystemClock.elapsedRealtimeNanos(), tagId, 3); - e.writeLong(mStatFsData.getAvailableBytes()); - e.writeLong(mStatFsSystem.getAvailableBytes()); - e.writeLong(mStatFsTemp.getAvailableBytes()); - pulledData.add(e); - } - private void pullSystemUpTime(int tagId, List<StatsLogEventWrapper> pulledData) { StatsLogEventWrapper e = new StatsLogEventWrapper(SystemClock.elapsedRealtimeNanos(), tagId, 1); e.writeLong(SystemClock.uptimeMillis()); @@ -962,6 +966,183 @@ public class StatsCompanionService extends IStatsCompanionService.Stub { } } + private void pullDiskStats(int tagId, List<StatsLogEventWrapper> pulledData) { + // Run a quick-and-dirty performance test: write 512 bytes + byte[] junk = new byte[512]; + for (int i = 0; i < junk.length; i++) junk[i] = (byte) i; // Write nonzero bytes + + File tmp = new File(Environment.getDataDirectory(), "system/statsdperftest.tmp"); + FileOutputStream fos = null; + IOException error = null; + + long before = SystemClock.elapsedRealtime(); + try { + fos = new FileOutputStream(tmp); + fos.write(junk); + } catch (IOException e) { + error = e; + } finally { + try { + if (fos != null) fos.close(); + } catch (IOException e) { + // Do nothing. + } + } + + long latency = SystemClock.elapsedRealtime() - before; + if (tmp.exists()) tmp.delete(); + + if (error != null) { + Slog.e(TAG, "Error performing diskstats latency test"); + latency = -1; + } + // File based encryption. + boolean fileBased = StorageManager.isFileEncryptedNativeOnly(); + + //Recent disk write speed. Binder call to storaged. + int writeSpeed = -1; + try { + IBinder binder = ServiceManager.getService("storaged"); + if (binder == null) { + Slog.e(TAG, "storaged not found"); + } + IStoraged storaged = IStoraged.Stub.asInterface(binder); + writeSpeed = storaged.getRecentPerf(); + } catch (RemoteException e) { + Slog.e(TAG, "storaged not found"); + } + + // Add info pulledData. + long elapsedNanos = SystemClock.elapsedRealtimeNanos(); + StatsLogEventWrapper e = new StatsLogEventWrapper(elapsedNanos, tagId, 3 /* fields */); + e.writeLong(latency); + e.writeBoolean(fileBased); + e.writeInt(writeSpeed); + pulledData.add(e); + } + + private void pullDirectoryUsage(int tagId, List<StatsLogEventWrapper> pulledData) { + long elapsedNanos = SystemClock.elapsedRealtimeNanos(); + StatFs statFsData = new StatFs(Environment.getDataDirectory().getAbsolutePath()); + StatFs statFsSystem = new StatFs(Environment.getRootDirectory().getAbsolutePath()); + StatFs statFsCache = new StatFs(Environment.getDownloadCacheDirectory().getAbsolutePath()); + + StatsLogEventWrapper e = new StatsLogEventWrapper(elapsedNanos, tagId, 3 /* fields */); + e.writeInt(StatsLog.DIRECTORY_USAGE__DIRECTORY__DATA); + e.writeLong(statFsData.getAvailableBytes()); + e.writeLong(statFsData.getTotalBytes()); + pulledData.add(e); + + e = new StatsLogEventWrapper(elapsedNanos, tagId, 3 /* fields */); + e.writeInt(StatsLog.DIRECTORY_USAGE__DIRECTORY__CACHE); + e.writeLong(statFsCache.getAvailableBytes()); + e.writeLong(statFsCache.getTotalBytes()); + pulledData.add(e); + + e = new StatsLogEventWrapper(elapsedNanos, tagId, 3 /* fields */); + e.writeInt(StatsLog.DIRECTORY_USAGE__DIRECTORY__SYSTEM); + e.writeLong(statFsSystem.getAvailableBytes()); + e.writeLong(statFsSystem.getTotalBytes()); + pulledData.add(e); + } + + private void pullAppSize(int tagId, List<StatsLogEventWrapper> pulledData) { + long elapsedNanos = SystemClock.elapsedRealtimeNanos(); + try { + String jsonStr = IoUtils.readFileAsString(DiskStatsLoggingService.DUMPSYS_CACHE_PATH); + JSONObject json = new JSONObject(jsonStr); + long cache_time = json.optLong(DiskStatsFileLogger.LAST_QUERY_TIMESTAMP_KEY, -1L); + JSONArray pkg_names = json.getJSONArray(DiskStatsFileLogger.PACKAGE_NAMES_KEY); + JSONArray app_sizes = json.getJSONArray(DiskStatsFileLogger.APP_SIZES_KEY); + JSONArray app_data_sizes = json.getJSONArray(DiskStatsFileLogger.APP_DATA_KEY); + JSONArray app_cache_sizes = json.getJSONArray(DiskStatsFileLogger.APP_CACHES_KEY); + // Sanity check: Ensure all 4 lists have the same length. + int length = pkg_names.length(); + if (app_sizes.length() != length || app_data_sizes.length() != length + || app_cache_sizes.length() != length) { + Slog.e(TAG, "formatting error in diskstats cache file!"); + return; + } + for (int i = 0; i < length; i++) { + StatsLogEventWrapper e = + new StatsLogEventWrapper(elapsedNanos, tagId, 5 /* fields */); + e.writeString(pkg_names.getString(i)); + e.writeLong(app_sizes.optLong(i, -1L)); + e.writeLong(app_data_sizes.optLong(i, -1L)); + e.writeLong(app_cache_sizes.optLong(i, -1L)); + e.writeLong(cache_time); + pulledData.add(e); + } + } catch (IOException | JSONException e) { + Slog.e(TAG, "exception reading diskstats cache file", e); + } + } + + private void pullCategorySize(int tagId, List<StatsLogEventWrapper> pulledData) { + long elapsedNanos = SystemClock.elapsedRealtimeNanos(); + try { + String jsonStr = IoUtils.readFileAsString(DiskStatsLoggingService.DUMPSYS_CACHE_PATH); + JSONObject json = new JSONObject(jsonStr); + long cacheTime = json.optLong(DiskStatsFileLogger.LAST_QUERY_TIMESTAMP_KEY, -1L); + + StatsLogEventWrapper e = new StatsLogEventWrapper(elapsedNanos, tagId, 3 /* fields */); + e.writeInt(StatsLog.CATEGORY_SIZE__CATEGORY__APP_SIZE); + e.writeLong(json.optLong(DiskStatsFileLogger.APP_SIZE_AGG_KEY, -1L)); + e.writeLong(cacheTime); + pulledData.add(e); + + e = new StatsLogEventWrapper(elapsedNanos, tagId, 3 /* fields */); + e.writeInt(StatsLog.CATEGORY_SIZE__CATEGORY__APP_DATA_SIZE); + e.writeLong(json.optLong(DiskStatsFileLogger.APP_DATA_SIZE_AGG_KEY, -1L)); + e.writeLong(cacheTime); + pulledData.add(e); + + e = new StatsLogEventWrapper(elapsedNanos, tagId, 3 /* fields */); + e.writeInt(StatsLog.CATEGORY_SIZE__CATEGORY__APP_CACHE_SIZE); + e.writeLong(json.optLong(DiskStatsFileLogger.APP_CACHE_AGG_KEY, -1L)); + e.writeLong(cacheTime); + pulledData.add(e); + + e = new StatsLogEventWrapper(elapsedNanos, tagId, 3 /* fields */); + e.writeInt(StatsLog.CATEGORY_SIZE__CATEGORY__PHOTOS); + e.writeLong(json.optLong(DiskStatsFileLogger.PHOTOS_KEY, -1L)); + e.writeLong(cacheTime); + pulledData.add(e); + + e = new StatsLogEventWrapper(elapsedNanos, tagId, 3 /* fields */); + e.writeInt(StatsLog.CATEGORY_SIZE__CATEGORY__VIDEOS); + e.writeLong(json.optLong(DiskStatsFileLogger.VIDEOS_KEY, -1L)); + e.writeLong(cacheTime); + pulledData.add(e); + + e = new StatsLogEventWrapper(elapsedNanos, tagId, 3 /* fields */); + e.writeInt(StatsLog.CATEGORY_SIZE__CATEGORY__AUDIO); + e.writeLong(json.optLong(DiskStatsFileLogger.AUDIO_KEY, -1L)); + e.writeLong(cacheTime); + pulledData.add(e); + + e = new StatsLogEventWrapper(elapsedNanos, tagId, 3 /* fields */); + e.writeInt(StatsLog.CATEGORY_SIZE__CATEGORY__DOWNLOADS); + e.writeLong(json.optLong(DiskStatsFileLogger.DOWNLOADS_KEY, -1L)); + e.writeLong(cacheTime); + pulledData.add(e); + + e = new StatsLogEventWrapper(elapsedNanos, tagId, 3 /* fields */); + e.writeInt(StatsLog.CATEGORY_SIZE__CATEGORY__SYSTEM); + e.writeLong(json.optLong(DiskStatsFileLogger.SYSTEM_KEY, -1L)); + e.writeLong(cacheTime); + pulledData.add(e); + + e = new StatsLogEventWrapper(elapsedNanos, tagId, 3 /* fields */); + e.writeInt(StatsLog.CATEGORY_SIZE__CATEGORY__OTHER); + e.writeLong(json.optLong(DiskStatsFileLogger.MISC_KEY, -1L)); + e.writeLong(cacheTime); + pulledData.add(e); + } catch (IOException | JSONException e) { + Slog.e(TAG, "exception reading diskstats cache file", e); + } + } + /** * Pulls various data. */ @@ -1036,10 +1217,6 @@ public class StatsCompanionService extends IStatsCompanionService.Stub { pullSystemElapsedRealtime(tagId, ret); break; } - case StatsLog.DISK_SPACE: { - pullDiskSpace(tagId, ret); - break; - } case StatsLog.PROCESS_MEMORY_STATE: { pullProcessMemoryState(tagId, ret); break; @@ -1056,6 +1233,22 @@ public class StatsCompanionService extends IStatsCompanionService.Stub { pullLooperStats(tagId, ret); break; } + case StatsLog.DISK_STATS: { + pullDiskStats(tagId, ret); + break; + } + case StatsLog.DIRECTORY_USAGE: { + pullDirectoryUsage(tagId, ret); + break; + } + case StatsLog.APP_SIZE: { + pullAppSize(tagId, ret); + break; + } + case StatsLog.CATEGORY_SIZE: { + pullCategorySize(tagId, ret); + break; + } default: Slog.w(TAG, "No such tagId data as " + tagId); return null; |