When using tools.logging and java.util.logging (JUL in short), by default we get logs prefixed like this:
Oct 23, 2023 2:14:47 PM clojure.tools.logging$eval3668$fn__3671 invoke
Notice that class and method name logged are something completely unhelpful.
The solution recommended by the tools.logging library is that the user should change log appender output format to not print out class and method and to print out the logger name, which is the Clojure namespace name.
That is a possible solution when the authors of the app doing the logging and the author of code that configures JUL are the same person, i.e. the logging is configured and done at app level.
Use Case
I would say that the far more common use case of tools.logging is the use by a library author, who doesn't know which logging solution the end user is using. And at the same time, the end user is unaware of this logging being present in their dependency tree. In this case someone builds a Clojure app and they might have a 100 dependencies. Suddenly they start getting messages as described above in their stderr.
They might want to:
- redirect that to a file
- suppress the messages
- want to know which dependency is generating them
All of these tasks require that the user recognizes that it's JUL logging they are looking at and then configuring the JUL to output logger name to find out the namespace which is doing the logging. They might also want to keep the format with the method name for any Java code they have.
Approach
Use LogRecord class to force classname to Clojure namespace. Example code:
(cond-> (doto (LogRecord. level# ~msg)
(.setLoggerName ~ns)
(.setMessage ~msg)
(.setParameters (object-array ~params))
(.setSourceClassName ~ns))
~e (doto (.setThrown ~e)))
Benefits
Replaces clojure.tools.logging$eval3668$fn__3671 invoke
in output with my.lib.namespace
. The former string has 0 informational value, the latter enables us to know where to look for the log statement performed.
Improves performance. If .setSourceClassName
is called, then the logging system won't use reflection to determine caller class and method. That involves walking the stack trace and it's slow.
Even with default/no configuration of JUL it gives a hint about where to look for who is making all these messages in stderr, if user is not aware of this logging library/mechanism.
I can produce a PR to affect this change if needed.