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…