dumpsysとは
Androidのsystem serviceの状態を出力するコマンド。
オプション無しだと全サービスの情報を出力してくれる。
dumpsys -l
で対応するserviceの一覧を取得し、dumpsys SERVICE
で特定のserviceの情報だけ出力することも可能。
dumpsys自体はserviceに対してdump要求を投げるだけで、実際の情報出力はservice側でおこなう。
この作りのおかげで柔軟にdumpsysを拡張できる。
逆に言えばdumpsysに対応するserviceはシステムごとに異なる。
以前"cpuinfo"を取り上げたので、今回はストレージデバイス使用量の情報を取得する"storaged"の中身を見る。
ソースコードおよび動作確認の環境は以下のとおり。
- Android: android-8.1.0_r1.0, Oreo, API 27
- Linux kernel: android-4.4-o-release
dumpsys storaged
dumpsys storaged
は、UIDごとのストレージデバイス使用量統計を出力する。
定期的(デフォルト一時間ごと)に/proc/uid_io/stats
を収集し、
充電中かどうかに応じて分類したうえで変化量を出力する。
shellからの実行であれば、root権限は不要。
(直接serviceを使う場合は、"android.permission.DUMP"が必要。)
まずは出力例。
起動直後など十分にデータが収集されていない場合は何も出力されないかもしれない。
その場合は、後述の--force
オプションを指定するとよい。
$ adb shell dumpsys storaged
1567214981,1567215005 <------- タイムスタンプ(開始,終了)
shared:android.uid.shell 1105920 0 0 0 0 0 0 0 <------- UIDごとのディスク使用量
1047 405504 0 0 0 0 0 0 0
0 98934784 8777728 0 0 0 0 0 0
1041 471040 0 0 0 0 0 0 0
shared:android.uid.phone 1929216 0 0 0 0 0 0 0
1046 118784 0 0 0 0 0 0 0
1013 847872 0 0 0 0 0 0 0
1036 4096 0 0 0 0 0 0 0
1040 1069056 0 0 0 0 0 0 0
shared:android.uid.system 634400768 2273280 0 0 0 0 0 0
,1567215093 <------- タイムスタンプ(,終了)
com.google.android.sdksetup 163840 0 0 0 0 0 0 0
shared:android.media 0 0 1449984 10014720 0 0 0 0
0 6856192 12464128 0 0 0 0 0 0
shared:com.google.android.apps.maps 0 0 31870976 323584 0 0 0 0
com.google.android.apps.nexuslauncher 8339456 6082560 3010560 4096 0 0 0 0
com.android.contacts 0 0 2224128 0 0 0 0 0
いつからいつまでの使用量なのかを示すタイムスタンプの後に、
各UIDごとのストレージデバイス使用量が出力される。
タイムスタンプ行
1567214981,1567215005 <------- タイムスタンプ(開始,終了)
,1567215093 <------- タイムスタンプ(,終了)
終了時刻しか書いていない場合、開始時刻は一つ前の終了時刻となる。
タイムスタンプの内容はUNIXタイム。つまり単位は秒。
dateコマンドを使えば、従来の時間に変更可能。
$ date -d @1567214981
Sat Aug 31 01:29:41 GMT 2019
ストレージデバイス使用量行
shared:android.uid.shell 1105920 0 0 0 0 0 0 0
1047 405504 0 0 0 0 0 0 0
各項目の意味は以下の通り。
- UID or UIDに対応する名前
- 非充電 かつ FOREGROUND の読み出し [Byte]
- 非充電 かつ FOREGROUND の書き込み [Byte]
- 非充電 かつ BACKGROUND の読み出し [Byte]
- 非充電 かつ BACKGROUND の書き込み [Byte]
- 充電中 かつ FOREGROUND の読み出し [Byte]
- 充電中 かつ FOREGROUND の書き込み [Byte]
- 充電中 かつ BACKGROUND の読み出し [Byte]
- 充電中 かつ BACKGROUND の書き込み [Byte]
オプション
-
--hours <HOURS>
- HOURSはdouble型
- 直近のHOURS時間以降の統計情報のみ出力する。
-
--time_window <TIME_WINDOW>
- TIME_WINDOWはint型
-
/proc/uid_io/stats
を収集する時間間隔を設定する(単位は秒) - ただし、
DEFAULT_PERIODIC_CHORES_INTERVAL_UID_IO_LIMIT (300)
以上でなければならない。 - 初期値は、
ro.storaged.uid_io.interval
。 -
ro.storaged.uid_io.interval
が設定されていない場合はDEFAULT_PERIODIC_CHORES_INTERVAL_UID_IO ( 3600 )
。つまり1時間。
-
--threshold <THRESHOLD>
- THRESHOLDはuint型
- IOの総量がTHRESHOLD byte以上のUIDのみ出力するようにする。
-
--force
- 強制的に現時点までのストレージデバイス使用量を出力する。
ドキュメントもヘルプも見つからなかった。。。
実装
storaged
自体がストレージデバイス使用量を収集するためのサービスということもあり、
実装はだいぶシンプルで読みやすい。
system/core/storaged/storaged_service.cppのStoraged::dump()がdumpsys storaged
に対応する。
前述のオプションなども、ここを見ればわかる。
status_t Storaged::dump(int fd, const Vector<String16>& args) {
...
const std::map<uint64_t, struct uid_records>& records =
storaged->get_uid_records(hours, threshold, force_report);
for (const auto& it : records) {
if (last_ts != it.second.start_ts) {
dprintf(fd, "%llu", (unsigned long long)it.second.start_ts);
}
dprintf(fd, ",%llu\n", (unsigned long long)it.first);
last_ts = it.first;
for (const auto& record : it.second.entries) {
dprintf(fd, "%s %ju %ju %ju %ju %ju %ju %ju %ju\n",
record.name.c_str(),
record.ios.bytes[READ][FOREGROUND][CHARGER_OFF],
record.ios.bytes[WRITE][FOREGROUND][CHARGER_OFF],
record.ios.bytes[READ][BACKGROUND][CHARGER_OFF],
record.ios.bytes[WRITE][BACKGROUND][CHARGER_OFF],
record.ios.bytes[READ][FOREGROUND][CHARGER_ON],
record.ios.bytes[WRITE][FOREGROUND][CHARGER_ON],
record.ios.bytes[READ][BACKGROUND][CHARGER_ON],
record.ios.bytes[WRITE][BACKGROUND][CHARGER_ON]);
}
}
...
return NO_ERROR;
}
/proc/uid_io/stats
dumpsys storaged
の基となるprocfs
。
Androidで独自に追加されている。
出力はぱっと見dumpsys storaged
と似ているが、中身は全然違うので要注意。
さらに、公式ページの説明も間違っている(2019/8/31時点)ので注意。
参照にはroot権限が必要。
$ cat /proc/uid_io/stats
0 69488496 57508693 176613888 71938048 0 0 0 0 37 0
10074 0 0 0 0 478411 2454202 8970240 3514368 0 259
1021 523337 3579 2101248 0 0 0 0 0 0 0
10019 13994 828 163840 0 10502 1521 0 0 0 0
...
- UID
- FOREGROUND かつ read system call [Byte]
- FOREGROUND かつ write system call [Byte]
- FOREGROUND かつ storage deviceからの読み出し [Byte]
- FOREGROUND かつ storage deviceへの書き込み [Byte]
- BACKGROUND かつ read system call [Byte]
- BACKGROUND かつ write system call [Byte]
- BACKGROUND かつ storage deviceからの読み出し [Byte]
- BACKGROUND かつ storage deviceへの書き込み [Byte]
- FOREGROUND かつ fsync system call [回数]
- BACKGROUND かつ fsync system call [回数]
実装は以下。
static int uid_io_show(struct seq_file *m, void *v)
{
struct uid_entry *uid_entry;
unsigned long bkt;
rt_mutex_lock(&uid_lock);
update_io_stats_all_locked();
hash_for_each(hash_table, bkt, uid_entry, hash) {
seq_printf(m, "%d %llu %llu %llu %llu %llu %llu %llu %llu %llu %llu\n",
uid_entry->uid,
uid_entry->io[UID_STATE_FOREGROUND].rchar,
uid_entry->io[UID_STATE_FOREGROUND].wchar,
uid_entry->io[UID_STATE_FOREGROUND].read_bytes,
uid_entry->io[UID_STATE_FOREGROUND].write_bytes,
uid_entry->io[UID_STATE_BACKGROUND].rchar,
uid_entry->io[UID_STATE_BACKGROUND].wchar,
uid_entry->io[UID_STATE_BACKGROUND].read_bytes,
uid_entry->io[UID_STATE_BACKGROUND].write_bytes,
uid_entry->io[UID_STATE_FOREGROUND].fsync,
uid_entry->io[UID_STATE_BACKGROUND].fsync);
show_io_uid_tasks(m, uid_entry);
}
rt_mutex_unlock(&uid_lock);
return 0;
}
おまけ:UIDごとの累積使用量が知りたいときはstoraged -u
/pro/uid_io/stats
だとUIDで出力されるので、わかりづらい。
dumpsys storaged
はUIDがpackage名なのでわかりやすいが、累積使用量を知るためには処理が必要。
という場合はstoraged -u
を使えばいい。
デーモンプロセスを実行するのは抵抗があるかも知れないが、
UIDをpackage名に変換して、/proc/uid_io/stats
相当の情報を出力してくれる。
ヘッダをつけてくれるのも地味にありがたい。
# storaged -u
name/uid fg_rchar fg_wchar fg_rbytes fg_wbytes bg_rchar bg_wchar bg_rbytes bg_wbytes fg_fsync bg_fsync
shared:com.google.uid.shared 333142 4077 159744 16384 119379524 25551230 139603968 67715072 0 2766
com.google.android.googlequicksearchbox 1552289 1046016 1654784 237568 2588581 6417348 65368064 6144000 3 223
shared:com.google.android.apps.maps 0 0 0 0 917109 59377 62382080 90112 0 15
com.android.chrome 1944 213 0 0 1645705 1542720 38596608 18350080 0 61
com.google.android.inputmethod.latin 1944 213 0 0 1740052 1965819 43499520 524288 0 12
com.google.android.dialer 1944 203 0 0 17437687 30775961 13991936 25989120 0 47
com.google.android.apps.photos 0 0 0 0 2109896 849853 31760384 880640 0 4
参考
- dumpsys
-
storaged
- 注:
/proc/uid_io/stats
のフォーマットに関する記述は誤り(2019/8/31時点)
- 注:
- Androidソースコード検索サービス
- android-8.1.0_r1.0
- Linux kernel android-4.4-o-release