当使用 tools.logging 和 java.util.logging (简称JUL) 时,默认情况下,我们得到的日志前面的内容如下:
Oct 23, 2023 2:14:47 PM clojure.tools.logging$eval3668$fn__3671 invoke
请注意,在日志中记录的类和方法名称非常有帮助。
tools.logging库推荐的解决方案是,用户应将日志追加器输出格式更改为不打印类和方法,并打印出记录器名称,即Clojure命名空间名。
这是一个可能的解决方案,当日志操作的应用程序的开发者和配置JUL的代码的开发者是同一个人时,即日志配置和执行都在应用程序级别。
用例
我会说,tools.logging的更常见用例是库作者的使用,他们不知道最终用户使用哪种日志解决方案。同时,最终用户对自己的依赖树中存在这种日志没有意识。在这种情况下,有人构建了一个Clojure应用程序,他们可能有一百个依赖项。突然,他们开始看到上面在stderr中描述的消息。
他们可能想要
- 将其重定向到文件
- 抑制消息
- 想要知道哪个依赖项生成了它们
这一切都要求用户识别他们正在查看的是JUL日志,并配置JUL以输出记录器名称,以便找到执行日志语句的命名空间。他们还可能希望在Java代码中保留带有方法名称的格式。
方法
使用LogRecord类强制将类名转换为Clojure命名空间。示例代码
(cond-> (doto (LogRecord. level# ~msg)
(.setLoggerName ~ns)
(.setMessage ~msg)
(.setParameters (object-array ~params))
(.setSourceClassName ~ns))
~e (doto (.setThrown ~e)))
好处
将输出中的clojure.tools.logging$eval3668$fn__3671 invoke
替换为my.lib.namespace
。前者字符串没有信息价值,后者使我们能够知道在哪里寻找执行日志语句的位置。
提高性能。如果调用.setSourceClassName
,则日志系统不会使用反射来确定调用者类和方法。这涉及遍历堆栈跟踪,这是缓慢的。
即使在默认/未配置的JUL中,也能为用户提供有关在stderr中生成所有这些消息的来源的提示,如果用户不了解此日志库/机制。
如果需要,我可以提供修改此更改的PR。