mattak's blog

気の向くままに書く

AndroidのLogを改良しよう1

Androidのログって...

  • 機能が貧弱.
  • 仕込むのめんどい.
  • 出し分けの指定もめんどい.
  • 毎回Logクラスのwrapperを各アプリで用意したくない.
  • ...

ということを前々から強く思っていたけど、いい感じのライブラリがないので自分でつくる. MavenCentralデビューを目標にしようと思う.

ログが必要な場面

ログが必要な場面を整理してみる

  • printfデバック
  • errorの記録.

すぐに思いつくのはこの2つ. よくprintfデバックを仕込むポイントを考える.

  • 関数の冒頭. (引数を確認したい)
  • 分岐の前後 (どの分岐に入ったかを確認したい)
  • 関数の末尾 (ちゃんと関数が完了しているか確認したい)
  • ループの冒頭 (ループ内の状態を知りたい)
  • IO付近 (どのファイルを読んだか? / どのURLにアクセスしたか? / ...)

ぱっと思いつくのはこのくらい.

Androidでlogcatをみる場面は、

  1. クラッシュしたとき.
  2. どの部分で処理がとまったかわからないとき.
  3. きちんと動いているか確認するとき.

この3つが多いと思う.

Logcatの不満点

表示

普通にGUIで表示したときのlogcatの不満.

  • 情報量が多すぎる. (対象のログがすぐ消えて追えなくなる / 自分のアプリに関係ない情報多すぎる)
  • GUI起動でいらいら (eclipse / android studio / ddms / ...)
  • ぱっと見で必要な情報がわからない.
  • filterが貧弱. grepしづらい.
  • ログの出し分けができない. globalなタグを利用するしかない.
  • ログのON/OFFができない
  • ログを出したファイルと行数がわからない.

GUIだとストレスしかたまらないので、adb logcatでいつもみている. CUIで便利になること.

  • unixのコマンドと組み合わせ
    • egrepで正規表現でログフィルタ. (情報量の削減)
    • teeでログみながら記録. (見逃し防止)
    • perlのonelinerで色づけ. stacktraceの抽出.
    • egrep -C10 対象の情報周辺のログを抽出.
    • egrep, awk, sed...を組み合わせてstacktrace部分のみ抽出

egrep / tee / perlの組み合わせだけでもほんとに快適になる. ただgrepしても情報が整理されてなかったり、一貫性がなかったりで見る側にやさしくないことがある。 表示に関しては、adb logcat をwrapするようなutilコマンドがあればそれだけでよさそう.

出力

  • タグ指定が面倒.
    • Log.d(TAG, "hoge")とかいちいちTAGをファイルごとに定義するのめんどすぎる.
  • formatが使えない.
    • Log.d(TAG, String.format("%s is OK", stringValue)) みたいな機能のwrapperをいちいちつくりたくない
  • ログのON/OFFが任意の条件で行えない.
    • set propとかでタグごとレベル指定とかしたくない.
    • BuildConfig.DEBUGとか、Releaseでも使いたい状況はたたある.
    • 自分でそのくらい制御したいよ.
  • ファイル/メソッド/行数が出力されない. どこではいたログか一瞬でわからない.
  • フォーマットが統一されない.
    • 表示上のログが複数人で開発していると差分多すぎる.
  • channel的な機能がない.
    • 任意に指定できるアプリ間でglobalなtagだと適切につかいわけられる人は皆無なんじゃないだろうか?
  • そもそも仕込むのがめんどい.
    • いちいち人手で書かなくていい箇所がたくさんある. javaのannotationとかでソースコード汚さず自動で仕込んでほしい.

ぱっとおもいつくだけでもこれだけある. 出力に関しては大きく改良できそうだ.

設計方針

以上の不満、利用環境をふまえた上で設計指針をたてる.

  • 簡単にしこめること
  • みやすく表示できること
  • ログを失わないこと

これらを最優先の達成指針として、他はある程度のところで妥協していく.

プロジェクトでは、ログの出力、ログの表示の両面で実装をおこなう.

とりあえず今日はこんなところ. プロジェクトの名前は、ちょっと考え中。。