跳转到正文
YGJoon
返回

Android Kotlin 日志监控与可观测性

编辑文章

可观测性组件

维度工具目标
日志Timber、Logger、Logcat记录调试与业务轨迹
崩溃Firebase Crashlytics、Sentry捕获崩溃与非致命异常
性能Firebase Performance、Macrobenchmark监控启动、网络、帧率
业务指标自建埋点、Analytics SDK分析用户行为

日志体系

Kotlin 封装

object AppLogger {
    fun init() {
        if (BuildConfig.DEBUG) {
            Timber.plant(Timber.DebugTree())
        } else {
            Timber.plant(ReleaseTree())
        }
    }

    fun d(message: String, vararg args: Any?) = Timber.d(message, *args)
    fun e(throwable: Throwable, message: String, vararg args: Any?) = Timber.e(throwable, message, *args)
}

class ReleaseTree : Timber.Tree() {
    override fun log(priority: Int, tag: String?, message: String, t: Throwable?) {
        if (priority >= Log.ERROR) {
            Crashlytics.log(priority, tag, message)
            t?.let { Crashlytics.recordException(it) }
        }
    }
}

日志脱敏

fun String.maskMiddle(): String {
    return if (length > 7) replaceRange(3, length - 4, "***") else this
}

AppLogger.d("phone=%s", phone.maskMiddle())

崩溃监控

class App : Application() {
    override fun onCreate() {
        super.onCreate()
        FirebaseApp.initializeApp(this)
        AppLogger.init()
    }
}
val crashHandler = CoroutineExceptionHandler { _, throwable ->
    Crashlytics.recordException(throwable)
}

viewModelScope.launch(crashHandler) { ... }

性能指标

class MetricInterceptor : Interceptor {
    override fun intercept(chain: Interceptor.Chain): Response {
        val start = SystemClock.elapsedRealtime()
        return try {
            chain.proceed(chain.request())
        } finally {
            val cost = SystemClock.elapsedRealtime() - start
            Metrics.logNetwork(chain.request().url.toString(), cost)
        }
    }
}

事件追踪与关联

val traceId = UUID.randomUUID().toString()
AppLogger.d("traceId=%s start login", traceId)

Crashlytics.setCustomKey("traceId", traceId)

Monitoring 仪表板

{
  "alerts": [
    {
      "metric": "app_startup_time",
      "condition": "> 3000",
      "notify": ["lark-webhook-url"]
    }
  ]
}

本地调试技巧

常见问题

问题原因解决方案
日志过多调试日志在 Release 未关闭根据 BuildConfig 控制日志级别
崩溃无 Trace混淆未保留符号表上传符号文件,保留 Crashlytics 映射
指标不准确采集点不统一统一埋点规范与时钟,避免重复上报

总结

可观测性是保障应用质量的关键。通过构建标准化的日志、崩溃与性能监控体系,结合自动化报警与仪表板,可快速发现问题、定位根因,支撑稳定迭代。Kotlin 提供的封装能力可让这些工具更易于使用与维护。


编辑文章
分享这篇文章:

上一篇
Android Kotlin 架构组件与多模块协同
下一篇
Android Kotlin 数据类型与空安全