如何让Log.kt中的KotlinLogging Logger使用调用方类名作为日志名
实现统一Logger并自动使用调用方名称
核心思路
直接定义val logger会固定绑定Log.kt的类名,因为初始化时就确定了栈帧信息。要动态获取调用方的名称,需要用函数延迟生成Logger实例——每次调用函数时解析当前调用栈,跳过自身函数的栈帧后,提取真正调用者的类名,以此作为Logger的名称。
代码实现
Log.kt
import mu.KotlinLogging // 顶层函数,每次调用时动态生成调用方对应的Logger fun logger() = KotlinLogging.logger { val stackTrace = Thread.currentThread().stackTrace // 索引2对应调用logger()的位置:0是getStackTrace(),1是当前logger()函数本身 val callerClassName = stackTrace[2].className callerClassName }
调用示例(Main.kt)
fun main() { // 调用函数获取当前调用方的Logger val logger = logger() logger.info("Hello world") // 输出:Main: Hello world // 其他类中调用的效果 val service = UserService() service.doSomething() } class UserService { fun doSomething() { logger().info("Doing something") // 输出:UserService: Doing something } }
原理说明
Thread.currentThread().stackTrace会返回当前线程的栈帧数组,通过跳过logger()函数自身的栈帧,就能定位到实际调用者的栈帧信息。- 从栈帧中提取
className作为Logger的名称,确保日志输出的名称与调用方类名一致。 - 这种方式无需在每个类中重复声明Logger实例,仅通过调用
logger()函数即可,大幅减少冗余代码。
注意事项
- 栈帧索引需根据实际情况微调:如果后续KotlinLogging内部实现变更,可能需要调整
stackTrace的索引值。 - 栈帧解析存在轻微性能开销,在绝大多数业务场景下可忽略不计。
内容的提问来源于stack exchange,提问作者Danny
相关产品推荐
相关产品推荐

