KMP 日志库的正确打开方式:惰性输出 + 可落盘 + 可扩展格式化

92 阅读3分钟

KMP 日志库的正确打开方式:惰性输出 + 可落盘 + 可扩展格式化

KMP 项目里,日志经常被低估: Android 有成熟方案,iOS 侧可能只有 println,共享层难以统一。 但项目一旦线上化,日志真正的价值从“能打印”变成了: 性能可控、格式一致、可落盘、可分析。

本文分享一套 KMP 日志工程化思路: 惰性输出 + 可落盘 + 多格式化 + 可扩展性 并介绍我最近开源的轻量 KMP 日志库 kmp-logcat 来落地这些能力。

GitHub 地址:github.com/Airsaid/kmp…

———

1. 为什么日志必须“惰性输出”

很多日志写法本质上是“先算再判断”:

Log.d("TAG", "user = ${user.toJson()}")

即使日志最终不输出,字符串拼接、序列化都已经发生。 当日志频率高或对象复杂时,这会变成隐性性能损耗。

正确方式是惰性输出:

logcat { "user = ${user.toJson()}" }

只有在 logger 已安装且优先级允许时,{} 内部才会执行。 这对线上日志、频繁日志尤其关键。

———

2. KMP 日志到底要解决什么问题?

跨平台项目对日志的“真实需求”,通常包括:

  • 统一风格:Android / iOS 输出格式一致,便于定位问题
  • 磁盘落盘:线上问题可回溯
  • 可扩展:不同业务定制格式、输出策略
  • 可控性能:惰性输出避免无效计算

———

3. 方案概览(核心能力)

kmp-logcat 的核心能力:

  • 惰性输出(避免无效开销)
  • 自动 Tag 推断(默认类名)
  • 多格式化策略
    • 平台风格输出(Android / iOS)
    • Pretty 格式化(带边框、线程信息、调用栈)
    • 无格式输出(直接透传)
  • 磁盘落盘
    • 缓冲写入
    • 文件轮转
    • 时间清理
    • 动态大小限制

———

4. 快速上手(跨平台)

安装平台 Logger

Android:

  val formatStrategy = AndroidLogcatFormatStrategy.Builder<AndroidLogcatLogStrategy>()
    .logStrategy(AndroidLogcatLogStrategy())
    .build()

  AndroidLogcatLogger.install(
    minPriority = LogPriority.DEBUG,
    formatStrategy = formatStrategy,
  )

iOS:

  val formatStrategy = IosLogcatFormatStrategy.Builder<IosLogcatLogStrategy>()
    .logStrategy(IosLogcatLogStrategy())
    .build()

  IosLogcatLogger.install(
    minPriority = LogPriority.DEBUG,
    formatStrategy = formatStrategy,
  )

———

日常日志

  logcat { "Default log" }
  logcat(LogPriority.INFO) { "Info log" }
  logcat(tag = "CustomTag") { "Custom tag log" }

异常输出:

  try {
    error("boom")
  } catch (t: Throwable) {
    logcat { t.asLog() }
  }

———

5. 磁盘落盘:线上问题“救命”能力

val diskStrategy = DiskLogStrategy.Builder()
    .logFileDirectory(logDirectory)
    .logFileGenerator(DefaultLogFileGenerator())
    .logFileMaxSize(1024L * 1024L * 100L)
    .logFileMaxTime(7L * 24L * 60L * 60L * 1000L)
    .logFileMaxSizeResolver(AvailableSpaceLogFileMaxSizeResolver())
    .logBufferMaxSize(10 * 1024)
    .build()

  val formatStrategy = NonFormatStrategy(diskStrategy)
  DiskLogger.installOnApp(LogPriority.WARN, formatStrategy)

特点:

  • 缓冲写入,降低 IO 抖动
  • 轮转 + 清理,避免无限增长
  • 可根据空间动态限制

———

6. 什么时候值得引入?

  • KMP 项目需要统一日志方案
  • 线上问题需要可回溯日志
  • 日志输出频繁,性能敏感
  • 需要扩展输出策略或格式

———

7. 为什么不直接用 Timber/Kermit?

  • Timber:Android-only
  • Kermit:跨平台不错,但惰性/格式化/落盘扩展能力有限

kmp-logcat 的目标是: 把 Android 端成熟的日志思路带到 KMP,同时保持跨平台一致性。

———

结语

日志不是“调试工具”,而是“稳定性工具”。 一套靠谱的 KMP 日志方案能明显提升线上问题定位效率。

如果你正在做 KMP 项目,欢迎试用并反馈:

  • 你更在意性能?
  • 还是更在意格式?
  • 或者更在意落盘与分析?

欢迎交流和 PR。 GitHub 地址:github.com/Airsaid/kmp…