エミュレーターでも実機でもデバッガが使えるので、ログ出力の意義をあまり感じない。
実機でアプリを実際に使ったとしても、ダウンロードされたアプリが出したログを開発者が確認できるわけでもないのであまり意味がないかもしれない。
実機でアプリを実際に使ったとしても、ダウンロードされたアプリが出したログを開発者が確認できるわけでもないのであまり意味がないかもしれない。
どうせやるならばアプリで例外をキャッチした時点で、ダイアログを表示し開発者にトレース情報をメールなどで送りつけるよう促すのが効果的なのではないだろうか。うーん……ログの意義はやはり感じ取れない。
とはいえ、ログはアプリケーションの基本なので一応は動作を確認し、情報をまとめておく。
情報源
全ての本家の情報。英語です。
http://developer.android.com/tools/debugging/debugging-log.html
http://developer.android.com/reference/android/util/Log.html
http://developer.android.com/reference/android/util/Log.html
ログレベル
DEBUGログは開発時のみ出力されるログです。実際のアプリに必要のない開発用のログはDEBUGレベルで出力しましょう。
ログレベルの解釈は人によって微妙に変わってきます。
以下に、一般的なログレベルの分け方を優先度順に表にします。
以下に、一般的なログレベルの分け方を優先度順に表にします。
ASSERT | ERRORよりも更に高いレベルのエラー。使いどころが分からない |
ERROR | 通常のエラー。アプリケーションの特定の機能が使えない状態や、特定の操作がエラーによりキャンセルされた場合など |
WARN | 警告。アプリケーションは利用できるがERRORを起こす可能性があったり、操作が完了されたものの不備がある可能性など |
INFO | 単なる情報。起動、停止などを記録したりする。アプリケーションの動作に悪影響を及ぼすことはない |
DEBUG | デバッグ情報。開発時のみに使用するログ |
VERBOSE | 詳細な情報を出力する。開発時のみに使用するログ |
VERBOSEはDEBUGログよりも更に低いレベルで、開発時以外のコンパイルからは除外される。DEBUGはコンパイルに含まれるが、機器のログ出力レベルがデフォルトではINFOのため設定を変更しない限りは出力されない(ただし、ちゃんとisLoggableを評価してる場合に限る)。
ログ出力処理はアプリに非常に負荷がかかる。そのため不用なログ出力は控えるのが良い。
またif文でisLoggableを使用しログ出力の要否を確認することがshouldされている。isLoggableを評価しない場合、ログ出力レベルの設定に関わらずDEBUGログまで出力されてしまうようだ。
またif文でisLoggableを使用しログ出力の要否を確認することがshouldされている。isLoggableを評価しない場合、ログ出力レベルの設定に関わらずDEBUGログまで出力されてしまうようだ。
ログの確認方法
LogCat
Eclipseからログ出力を確認するにはLogCatを使用するのが便利。
Eclipseのメニューから「ウインドウ」>「ビューの表示」>「その他」>「Android」「LogCat」で開くことができる。
Eclipseのメニューから「ウインドウ」>「ビューの表示」>「その他」>「Android」「LogCat」で開くことができる。
ワークスペース内のプロジェクトが出力するログをLogCatで確認する場合は、設定の変更が必要。
Eclipseのメニューから「ウインドウ」>「設定」を開き、「Android」>「LogCat」を選択し、そこで「ワークスペース内のアプリケーションからのメッセージのために logcat をモニターする」にチェックを入れる。
優先度の設定は、その優先度以上のログが出力されるとLogCatビューへの表示を開始し、フィルターを追加し該当プロジェクトのみの分を表示する仕組み。最低の優先度「VERBOSE」を指定すれば良い。仮に「ASSERT」を選択すると「ERROR」や「DEBUG」のログ出力ではキャッチされず、一切ログが表示されなくなる。
Eclipseのメニューから「ウインドウ」>「設定」を開き、「Android」>「LogCat」を選択し、そこで「ワークスペース内のアプリケーションからのメッセージのために logcat をモニターする」にチェックを入れる。
優先度の設定は、その優先度以上のログが出力されるとLogCatビューへの表示を開始し、フィルターを追加し該当プロジェクトのみの分を表示する仕組み。最低の優先度「VERBOSE」を指定すれば良い。仮に「ASSERT」を選択すると「ERROR」や「DEBUG」のログ出力ではキャッチされず、一切ログが表示されなくなる。
他のホームページなどの情報によると、これとは違う情報が書かれている。バージョンによって変わってくるのだろうか。悩ましい。
コマンドラインからlogcat
コマンドラインから ADB を使用し logcat を実行する。
adb logcat
と実行するとログが流れるが、ここにはEclipseから実行したプロジェクトのログは表示されない。
正しくは、
adb -e logcat
もしくは
adb -d logcat
を使用する。「-e」が仮想Android端末、「-d」がUSB接続の実機。
また
また
adb devices adb -s XXXXXXX logcat
デバイスのシリアルを「devices」で確認し「-s」スイッチに続いてシリアルを指定することで、対象の端末分のみのログを表示することができる。
ログの出力方法
ログを出力するにはAndroid.util.Logクラスを使用する。
importするだけで使用可能になる。
importするだけで使用可能になる。
ログレベルごとにメソッドが用意されており、ASSERTを除き、それぞれのレベルの頭文字がメソッド名になっている。
ASSERTレベルの wtf は、どうやら”What a Terrible Failure !!”(なんて不様な失敗だ!)の略らしい。
ASSERTレベルの wtf は、どうやら”What a Terrible Failure !!”(なんて不様な失敗だ!)の略らしい。
ASSERT | wtf |
ERROR | e |
WARN | w |
INFO | i |
DEBUG | d |
VERBOSE | v |
ログ出力メソッドを呼ぶときに必ず指定するタグだが、これはどれがログを出力したのか識別する文字列で、半角23文字以内で任意に設定する。
それぞれのメソッドには、
- タグとメッセージを指定する
- タグとメッセージと例外オブジェクトを指定する
2種類が用意されている。
またwtfには、タグと例外オブジェクトを指定するものもある。
またwtfには、タグと例外オブジェクトを指定するものもある。
以前は日本語のログを出すと LogCat で文字化けしたらしいが、自分の環境では大丈夫だった。
例
String logtag = "HelloAndroid"; Log.i(logtag, "This is INFO メッセージ"); Log.d(logtag, "This is DEBUG メッセージ"); if( Log.isLoggable(logtag, Log.DEBUG) ) { Log.d(logtag, "This is DEBUG メッセージ if isLoggable(DEBUG) = TRUE"); }
このコードを、特に設定を変更していない仮想Android端末で実行すると、上の2つだけが出力される。
デフォルトのログレベルはINFO。だが上のDEBUGメッセージは、ログレベルのチェックをしていないので出力される。
下のDEBUGメッセージは、ログレベルのチェックをしているので正しく出力が抑止される。
デフォルトのログレベルはINFO。だが上のDEBUGメッセージは、ログレベルのチェックをしていないので出力される。
下のDEBUGメッセージは、ログレベルのチェックをしているので正しく出力が抑止される。
いちいちif分で囲むのも面倒なので、Logをラップしたクラスを作れば良さそうだ。
DEBUGログに関しては、isLoggableで評価するより、定数を評価する形にしたほうがコンパイル時にコードごと除去されるので、そっちの方が動作は軽くなりそうだが、未確認。
DEBUGログに関しては、isLoggableで評価するより、定数を評価する形にしたほうがコンパイル時にコードごと除去されるので、そっちの方が動作は軽くなりそうだが、未確認。
添付ファイル