Androidアプリを開発する上で賢いLogの出力方法(とその確認の仕方)
今までずっとLog.d("test",”デバッグメッセージだよ”);
みたいな感じでLogを出力し、Logcatで確認しながらプログラミングしていたのですが、とあるサンプルを見ていた時にこんなコードに出くわしました。
private static final String TAG = "DigitalWatchFaceConfig";
if (Log.isLoggable(TAG, Log.DEBUG)) {
Log.d(TAG, "onConnected: " + connectionHint);
}
プログラムを実行しても、このログはlogcatに出力されません。
「なんでだ?」と思って調べているうちに、この方法はAndroidアプリ開発していく上で賢い選択なのだなということが分かってきました。
ベストプラクティスなのかどうかまでは分かりませんが、少なくともいきなりLog.d()
で出力したり、アプリ内でprivate boolean isDebug = true;
みたいにしてデバッグログを出力させるよりは賢いなと思いました。
参考サイト
[Log.isLoggable – API Refference](https://developer.android.com/reference/android/util/Log.html#isLoggable(java.lang.String, int))
ログの出力はアプリのパフォーマンスに影響します。少なくともStringオブジェクトを作ってそれを出力するわけですからね。
リリース時にはLog出力する部分を全部削除するのが一番いいのでしょうが、さすがにそれは手間が大きすぎます。それにリリースしたからといって開発が終わるわけでもなく、メンテのためにまた1からLogを出力するように直すのはあまりにも馬鹿らしいです。
Logを使わず開発するのはそもそも無理です。
Log.isLoggableによるチェックは、端末に設定されているログ出力レベルを判定しています。デフォルトでは全てのタグについてINFOが設定されています。
つまり最初のコードのようなLog.DEBUGでチェックをかけるとfalseが返ってくるのでログが出力されません。
ではどうやってログが出力されるようにすればいいのかというと、ターミナルでadb shell setprop
コマンドを使います。
adb shell stop
adb shell setprop log.tag.設定したいタグ名 ログレベル
adb shell start
最初の例のログを出力させようと思ったらadb shell setprop log.tag.DigitalWatchFaceService DEBUG
とターミナルから打ち込んでやればOKです。(ちなみにadb shellで端末にログインしてからであれば、いきなりsetprop
から初めてOKです)
タグごとのログ出力レベルを確認するには、adb shell getprop log.tag.タグ名
を使います。何も設定していない状態であれば空白が返って来ます。setpropで設定してやると、現在設定されているログ出力レベルが返って来ます。
VERBOSE > DEBUG > INFO > WARN > ERROR > ASSERTとなっています。デフォルトではINFOになっているので、isLoggable()
はINFO,WARN,ERROR,ASSERTでtrueを返します。
setpropでVERBOSEを設定するとあらゆるレベルでtrueが返るようになります。setprop SUPPRESSとすると逆にあらゆるレベルでfalseが返るようになります。
ちなみに設定する端末が開発専用であれば問題ないでしょうが、日常的に使っている端末の場合はログ出力レベルをINFOに戻すのを忘れないようにしましょう。(パフォーマンスに影響するため)
別に忘れても再起動すれば元に戻る(設定が消える)ので気にしなくてもいいかもしれません。
ちなみに「再起動の度に設定するのは面倒くさい」という場合には、/data/local.prop
で設定することもできるようですが、どうやって設定するのかは分かりません。多分root権限ないとできないんじゃないかと思います。(やってみたけどPermission deniedって言われました)
リリース予定がないならいきなりLog.d()
でも構わないのでしょうが、リリースを視野に入れているアプリならこういった方法でログを出力するように設定しておくとユーザに優しいと思います。