【问题标题】:Create Logger on Package Level Without Class在没有类的包级别上创建记录器
【发布时间】:2025-11-30 14:55:03
【问题描述】:

我有一个 kotlin 文件,其中包含几个包级函数并且没有任何类。我想在这个类中添加日志记录,但很难找到一种优雅的方式来给记录器一个标识符。

这是一个例子

package com.example.myproject.my_package

import org.slf4j.LoggerFactory


private val log = LoggerFactory.getLogger("com.example.myproject.my_package")

fun bla(term: String) {
   log.info("invoked with $term")
}

有非常好的最佳实践来使用类来找到一个好的标识符:link 1link 2。如果没有类怎么办?

我想避免手动编写标识符并在包名称更改时对其进行调整。有没有办法在kotlin中获取包名?

【问题讨论】:

  • *函数是实用函数时很好。但逻辑应该位于class(或object)中。
  • 为什么?面向对象编程只是开发代码的一种方式,还有其他范式是 kotlin 非常适合的。
  • 这不是因为 OOP 范式。 (顺便说一下,object 代表的 Singleton 是一种过程模式。)这是因为你的函数被收集在一个文件中,这不是一个全功能范围——它在编程语言中没有表示形式。跨度>
  • @FrankSchmitt 完美,就像一个魅力!

标签: logging kotlin


【解决方案1】:

这一行应该可以完成这项工作:

private val log = LoggerFactory.getLogger(object{}::class.java.`package`.name)

对象什么都不做,但是 kotlin 会创建一个类来保存代码。然后,您可以访问类、包、包名。

注意使用反引号,因为package 是保留关键字。在java中这不是问题,因为真正的方法是getPackage()。 kotlin 的较短语法通过直接访问现在与保留关键字冲突的属性来转换此方法调用。

【讨论】:

  • 很好的答案,谢谢。最后,我采用了弗兰克评论给出的解决方案。如果你对这种额外的依赖没问题,他的解决方案会更加优雅。
  • 当然,我更关注您的确切问题“有没有办法在 kotlin 中获取包名?”而不是我自己会做的。
【解决方案2】:

您可以像这样为生成的类创建*记录器:

private val logger = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass())

或者对于这样的包:

private val logger = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass().`package`.name)

这样做的好处是不需要创建额外的类文件,但它至少需要 Java 7。我已经创建了一个库来帮助解决这个问题以及更多内容,地址为 https://github.com/kxtra/kxtra-slf4j

【讨论】:

  • 更好的答案。好的信息,应该设置为接受。