カスタムロガーでログ出力を拡張し、デバッグ設定を置き換える
Hotwire Native は従来の Logcat 直出力と単一の debugLoggingEnabled スイッチから、プラグイン可能なロガーシステムへと移行し、アプリ側でログの取得・フィルタリング・転送が可能になりました。
背景
従来 Hotwire は Android の Logcat に直接ログを書き込み、デバッグ出力はブール値 debugLoggingEnabled でオンオフを切り替えるだけでした。これにより、アプリがライブラリのログをキャプチャして独自のロギングフレームワークやクラッシュレポートに流す手段がなく、ログの粒度調整も不可能でした。結果として、デバッグ情報の取得が制限され、運用上の可観測性が低下していました。
技術的な変更
HotwireLogger インターフェースと HotwireLogLevel 列挙型が新規追加され、ログレベルで出力を制御できる汎用的なロギング API が提供されました。
interface HotwireLogger {
var logLevel: HotwireLogLevel
fun v(tag: String, msg: () -> String)
fun d(tag: String, msg: () -> String)
fun i(tag: String, msg: () -> String)
fun w(tag: String, msg: () -> String)
fun e(tag: String, throwable: Throwable?, msg: () -> String)
}
DefaultHotwireLogger が実装として追加され、Logcat へ出力しつつ logLevel に応じてメッセージをフィルタリングします。レイジー評価 (() -> String) により不要な文字列生成が回避されます。
internal object DefaultHotwireLogger : HotwireLogger {
override var logLevel = HotwireLogLevel.NONE
override fun v(tag: String, msg: () -> String) { if (logLevel.priority <= HotwireLogLevel.VERBOSE.priority) Log.v(tag, msg()) }
override fun d(tag: String, msg: () -> String) { if (logLevel.priority <= HotwireLogLevel.DEBUG.priority) Log.d(tag, msg()) }
// i, w, e ... 同様に実装
}
HotwireConfig に logger: HotwireLogger プロパティが導入され、従来の debugLoggingEnabled が削除されました。デフォルトは DefaultHotwireLogger です。
var logger: HotwireLogger = DefaultHotwireLogger
// 旧: var debugLoggingEnabled = false
コアとナビゲーションのロガー実装 (CoreLog.kt, NavigationLog.kt) が Hotwire.config.logger 経由に置き換えられ、logEvent 系メソッドは logDebug·logVerbose へ統一されました。HTTP 通信のログは HotwireHttpLogger が OkHttp のインターセプタに注入され、常時有効化されます。
internal class HotwireHttpLogger : HttpLoggingInterceptor.Logger {
override fun log(message: String) { Hotwire.config.logger.d(DEFAULT_TAG) { message } }
}
コードベース全体で logEvent → logDebug / logVerbose への置換が行われ、各コンポーネントは同一インターフェース経由でログを出力します。これにより、ロギングロジックが一元化され、設定変更が全体に波及します。
設計判断
logger プロパティを単一化し、旧来のブールフラグを廃止した判断は、設定 API のシンプルさと拡張性を両立させる狙いがありました。デフォルト実装を保持しつつ、アプリ側で任意のロガーを注入できるため、後方互換性が保たれています。
インターフェースを介した依存性注入は、クリーンアーキテクチャの原則に沿い、テストやモジュール分離を容易にします。デモアプリの DemoApplication.kt ではビルドタイプに応じて Hotwire.config.logger.logLevel を設定し、実際の利用方法が示されています。
HotwireLogLevel とラムダベースのメッセージ提供は、ログレベル制御とオーバーヘッド削減という二つの設計目標を同時に満たす選択です。ログレベルが NONE のときは全ての出力が抑制され、パフォーマンスに影響しません。