在我的日志消息中,我需要插入生成消息的方法的名称。我查看了 Log4J 文档以及“M”和“l”转换字符,它们也有警告,例如“警告生成调用者位置信息非常慢,应该避免,除非执行速度不是问题”。所以我(至少)有两个选择:
log.info("myMethod: message");
,它会更快,但不那么优雅还有其他选项不会减慢我的代码速度吗?
谢谢!
我不确定您正在使用的 IDE,但如果您使用基于 Eclipse 的 IDE,您应该能够使用一些 Java 模板。这仍将使用方法名称作为字符串,但会节省您的键入时间。
我创建了一整套这样的模板:
li
logger.info("${cursor}");
等等
warn
、error
和debug
。
对于方法的开始和结束,或者只是将方法名称添加到每次注销 - 使用类似以下内容:
lie
logger.info("End: ${enclosing_method}${cursor}");
等等。
唯一的限制是您的记录器引用变量始终必须命名为
logger
。
现在您只需要输入 lie
并(如果您在模板创建时取消选中 自动插入 复选框,则可以选择按 ctrl+space。)
哈!
我大多数时候使用基本配置器,它默认为我提供方法名称。因此,从技术上讲,仅添加这一行代码和 import 语句是获得您所要求的内容的最快方法。
BasicConfigurator.configure();
如果有一种不慢的方式以编程方式检索此信息,log4j 会使用它 - 不幸的是没有,因为 JVM 的设计目的不是为了让运行时环境可以轻松使用这些信息。
这就是为什么大多数日志记录代码仅使用在调试级别检索此信息的模式,然后将所有调试调用包装在
if(logger.isDebugEnabled()) {
条件中,以便仅在程序处于调试模式时才检索信息。这种方法使您能够在调试时获得细粒度的运行时信息,而不会影响生产中代码的性能。
同样重要的是要记住,并非所有代码都是性能密集型的,如果您的代码在使用这些模式时运行和扩展良好,那么您不妨只使用它们。如果您开始遇到性能问题,那么您可以重新考虑。
顺便说一句,Groovy 语言(自版本 1.8 起)具有 AST 转换,可以自动将记录器(java.util、apache commons、log4j 或 slf4j 风格的)注入到您的类中,并且还会自动将所有日志记录调用包装在条件中编译时,以便它们仅在日志记录处于适当级别时运行。这意味着您可以执行我上面描述的操作,而无需显式编写条件代码,但当然只有在您编写 Groovy 时才可用。
对于任何在使用 log4j 和 slf4j 时寻找更新解决方案的人,我编写了一个 maven-plugin 来解决这个问题,同时也不会产生任何性能问题: https://github.com/PhilKes/slf4j-caller-info-maven-plugin
此插件在编译时将类名、方法名称和源代码行号注入到 SLF4J 日志语句中(请参阅配置)。 您需要做的就是将
callerInformation
MDC 参数添加到您的日志模式中,并将插件添加到您的 pom.xml
:
<plugin>
<groupId>io.github.philkes</groupId>
<artifactId>slf4j-caller-info-maven-plugin</artifactId>
<version>1.1.0</version>
<executions>
<execution>
<goals>
<goal>inject</goal>
</goals>
</execution>
</executions>
</plugin>