AndroidアプリでロギングするといえばPureeかなと思います。 かなり安定しているしいい感じに動く。 ただコードベースがJavaなので、たま〜に不具合でた時などに追っかけるのが結構たいへんだったり、 Gsonに依存しているので、別のJsonライブラリ使ってる場合ちょっとな〜ってなったりすることがあります。
かねてから何らかの形で書き直しできないかな〜と思いつつ時間が取れなかったんですが、
コルーチンベースでpureeやってみっか
— 八木 (@sys1yagi) 2019年5月17日
ということでついに手を出してみたところ、結構スッと出来上がったのでリリースします。 LocoはLog Coroutineの略です。
https://github.com/sys1yagi/loco
構造
Locoは次のような構造を持ちます。
- Smasher: ログをシリアライズする // ここだけ料理つながりな命名。ただ直感的ではない気がするので追々Serializerに変わるかも
- Store: シリアライズしたログを一旦永続化する
- Sender: シリアライズしたログを送信する
- SendingScheduler: 送信間隔などを決める
それぞれInterfaceなので好きな実装ができます。
セットアップ
まだjcenterに公開されてない*1のでbintrayのrepositoryをrootのbuild.gradleに追加する必要があります。
allprojects {
repositories {
maven { url "https://dl.bintray.com/sys1yagi/maven" }
}
}
あとはdependenciesに必要なものを追加するだけです。 予めAndroidで使えるSmasherとStoreを用意してあります。
dependencies { // core implementation 'com.sys1yagi.loco:loco-core:1.0.0' // Gsonでシリアライズする。filterを追加して加工ができる implementation 'com.sys1yagi.loco:loco-smasher-filterable-gson:1.0.0' // SQLiteでログを保存する implementation 'com.sys1yagi.loco:loco-store-android-sqlite:1.0.0' }
この他にも便利モジュールができたら随時追加していきます。汎用性がありそうなものはPRもらえると嬉しいです。
使う
詳しくはsampleを見ていただきたいですが、概ね次のような感じでセットアップします。
class SampleApplication : Application() { override fun onCreate() { Loco.start( LocoConfig( store = LocoAndroidSqliteStore(), // loco-store-android-sqlite smasher = FilterableGsonSmasher(Gson()), // loco-smasher-filterable-gson senders = NetworkSender(), scheduler = IntervalSendingScheduler(5000L) // 5000msおきに送信する ) { // SenderとLocoLogをマッピングする logToSender[NetworkSender::class] = listOf( ClickLog::class, // LocoLogを実装したクラスたち ScreenLog::class ) } ) } } // SendingSchedulerは今の所自前で用意しとく必要があります class IntervalSendingScheduler(val interval: Long) : SendingScheduler { override suspend fun schedule( latestResults: List<Pair<Sender, SendingResult>>, config: LocoConfig, offer: () -> Unit ) { delay(interval) offer() } } data class ClickLog( val value: String ) : LocoLog data class ScreenLog( val screenName: String ) : LocoLog
あとはどこからでもLogを送信できます。
class MainActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) Loco.send(ScreenLog(this::class.java.simpleName)) setContentView(R.layout.activity_main) // ... } }
終わりに
まだ1.0.0で機能が不足してたり不具合あるかもしれないのでいろいろ触ってみてissue作ったりPRもらえると嬉しいです。
https://github.com/sys1yagi/loco
*1:申請中です