日志标准 (kotlin-logging)
在 Kotlin 生态中,直接使用 android.util.Log 或后端的 System.out 并非最佳实践。kotlin-logging 是一个轻量级的日志门面(Facade),它支持 Kotlin Multiplatform (KMP),并能以极低的开销提供结构化、惰性求值的日志能力。
为什么需要它?
- 性能优化:支持 Lambda 惰性求值。如果日志级别低于当前配置(如在生产环境关闭 DEBUG),Lambda 内的字符串拼接完全不会执行。
- KMP 支持:一套代码同时运行在 Android (Logcat)、JVM (SLF4J)、JS 和 Native 上。
- 减少样板:无需手动输入 TAG,自动根据类名生成。
依赖配置
该库采用门面模式,因此通常需要引入“核心库”和“实现库”。
kotlin
dependencies {
// 1. 引入 kotlin-logging 核心门面
implementation("io.github.oshai:kotlin-logging-jvm:5.1.0")
// 2. 引入具体的日志实现 (Android 推荐 slf4j-android)
implementation("org.slf4j:slf4j-android:1.7.36")
}kotlin
commonMain {
dependencies {
implementation("io.github.oshai:kotlin-logging:5.1.0")
}
}基础用法
最常见的方式是创建一个顶层或伴生对象的 Logger。
kotlin
import io.github.oshai.kotlinlogging.KotlinLogging
// 自动获取当前类名作为 TAG
private val logger = KotlinLogging.logger {}
class UserManager {
fun login(userId: String) {
// ⭐️ 惰性求值:如果 info 级别未开启,字符串模板不会被计算
logger.info { "User $userId logged in at ${System.currentTimeMillis()}" }
try {
processLogin()
} catch (e: Exception) {
// 携带异常堆栈
logger.error(e) { "Login failed for user $userId" }
}
}
}Android 平台适配
在 Android 上,默认的 kotlin-logging 需要配合 SLF4J 实现才能输出到 Logcat。
推荐方案:slf4j-android
引入 org.slf4j:slf4j-android 后,日志会自动转发到 Logcat。
- TAG 限制:旧版 Android 对 TAG 长度限制为 23 字符,
slf4j-android会自动截断。 - 级别映射:
logger.trace->Log.vlogger.debug->Log.dlogger.info->Log.ilogger.warn->Log.wlogger.error->Log.e
核心工程准则
- 禁止直接使用 Log.d:在业务逻辑层(非 UI 层),严禁直接依赖 Android SDK 的
android.util.Log。这会破坏代码的可测试性(单元测试不依赖 Android 环境)和跨平台能力。 - 利用惰性求值:永远使用
{ "Msg $param" }的 Lambda 写法,而不是直接传入字符串。这在处理复杂对象toString()时能节省大量 CPU。 - 统一 TAG 规范:默认使用
KotlinLogging.logger {}即可,不要手动硬编码 TAG 字符串,除非有特殊的过滤需求。