当使用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应用程序,可能有100个依赖。突然,他们在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来完成这一更改。