背景
Java->Kotlin移行にあたり、JetBrainsがOSSとして開発しているAnkoLoggerを導入してみましたが、verboseやdebugログ出力してもAndroidStudioのlogcatに出力されませんでした。
原因を調べていると、AnkoLoggerの問題というよりは、標準Logクラスandroid.util.Log
の挙動をそもそも勘違いしていたことに気づきました。。
ログレベルと各ライブラリの挙動
今までの自分の認識だと、Log.d(TAG, "foo")
と書くと、ログレベルがdebug以下(つまりdebug, verbose)の場合にログ出力されて、いつも開発環境でverbose/debugログを見ているのはログレベルがverboseになっているからなのかな、と何となく思っていました。
結論から言うと、↑の認識は間違いで、デフォルトのログレベルはinfoでした。
ではなぜverbose/debugログが出力されているかというと、Log.d(TAG, "foo")
と書いても実はログレベルに関わらずログ出力される仕様のようです。
ログレベルの判定は別メソッドで行う必要があり、出し分けるには以下のようにif文で制御する必要があります。(ちなみにログレベルはタグ毎に設定されています)
if ( Log.isLoggable(TAG, DEBUG) ) Log.d(TAG, "foo");
何でこんな冗長な仕様になっているんだろう。。
一方のAnkoLoggerですが、
debug("foo") // タグはデフォルトで呼び出し元のActivity名
と書くと、内部でログレベルを判定してくれるので、利用する側はif文を書かなくてもログレベルに従って出力されます。個人的には断然こちらの方が直感的です。
GithubのIssueにも同じ疑問があがっていたので、標準Logクラスの仕様を勘違いしていたのは自分だけではないはず。
まとめ
改めて整理すると、
- 標準のLogクラス
-
Log.isLoggable
で明示的に制御しないと、本番(ログレベル:info)でも全てのログを出力するので、パフォーマンス低下につながる -
Log.isLoggable
で明示的に制御しないと、何もしなくてもlogcatでログを確認できるのである意味開発時は楽 - 正しい使い方はこちら
- 他にもProGuardでreleaseビルドだけログを出さないようにする方法もあるようです
-
- AnkoLogger
- 本番(ログレベル:info)ではinfo以上のログしか出力されないので、無駄なパフォーマンス低下がない
- 開発時にadb等でログレベルを変更しないとlogcatでログが見れないのでちょっと面倒。ex.
$ adb shell setprop log.tag.MainActivity VERBOSE
コードのわかりやすさとセキュリティを考えると、個人的にはAnkoLoggerを使っておこうと思います。
Javaを使っている場合や無駄な依存ライブラリを入れたくない場合は、AnkoLoggerライクな標準Logのラッパークラスを作るのもアリかと思います。