visible true

技術的なメモを書く

Android向けロギングライブラリ「Loco」をリリースしました。

AndroidアプリでロギングするといえばPureeかなと思います。 かなり安定しているしいい感じに動く。 ただコードベースがJavaなので、たま〜に不具合でた時などに追っかけるのが結構たいへんだったり、 Gsonに依存しているので、別のJsonライブラリ使ってる場合ちょっとな〜ってなったりすることがあります。

かねてから何らかの形で書き直しできないかな〜と思いつつ時間が取れなかったんですが、

ということでついに手を出してみたところ、結構スッと出来上がったのでリリースします。 LocoはLog Coroutineの略です。

https://github.com/sys1yagi/loco

構造

Locoは次のような構造を持ちます。

  • Smasher: ログをシリアライズする // ここだけ料理つながりな命名。ただ直感的ではない気がするので追々Serializerに変わるかも
  • Store: シリアライズしたログを一旦永続化する
  • Sender: シリアライズしたログを送信する
  • SendingScheduler: 送信間隔などを決める

それぞれInterfaceなので好きな実装ができます。

f:id:sys1yagi:20190519185303p:plain

セットアップ

まだ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:申請中です