<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0">
<channel>
<title>Clojure Q&amp;A - Recent questions tagged improvement</title>
<link>https://ask.clojure.org/index.php/tag/improvement</link>
<description></description>
<item>
<title>Using namespace as log originating class for JUL</title>
<link>https://ask.clojure.org/index.php/13427/using-namespace-as-log-originating-class-for-jul</link>
<description>&lt;p&gt;When using tools.logging and java.util.logging (JUL in short), by default we get logs prefixed like this:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Oct 23, 2023 2:14:47 PM clojure.tools.logging$eval3668$fn__3671 invoke
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Notice that class and method name logged are something completely unhelpful.&lt;/p&gt;
&lt;p&gt;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.&lt;/p&gt;
&lt;p&gt;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.&lt;/p&gt;
&lt;h3&gt;Use Case&lt;/h3&gt;
&lt;p&gt;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. &lt;/p&gt;
&lt;p&gt;They might want to:&lt;br&gt;
- redirect that to a file&lt;br&gt;
- suppress the messages&lt;br&gt;
- want to know which dependency is generating them&lt;/p&gt;
&lt;p&gt;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. &lt;strong&gt;They might also want to keep the format with the method name for any Java code they have.&lt;/strong&gt; &lt;/p&gt;
&lt;h3&gt;Approach&lt;/h3&gt;
&lt;p&gt;Use LogRecord class to force classname to Clojure namespace. Example code:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;(cond-&amp;gt; (doto (LogRecord. level# ~msg)
                      (.setLoggerName ~ns)
                      (.setMessage ~msg)
                      (.setParameters (object-array ~params))
                      (.setSourceClassName ~ns))
              ~e (doto (.setThrown ~e)))
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Benefits&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Replaces  &lt;code&gt;clojure.tools.logging$eval3668$fn__3671 invoke&lt;/code&gt; in output with &lt;code&gt;my.lib.namespace&lt;/code&gt;. The former string has 0 informational value, the latter enables us to know where to look for the log statement performed.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Improves performance. If &lt;code&gt;.setSourceClassName&lt;/code&gt; 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.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;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.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;I can produce a PR to affect this change if needed.&lt;/p&gt;
</description>
<category>tools.logging</category>
<guid isPermaLink="true">https://ask.clojure.org/index.php/13427/using-namespace-as-log-originating-class-for-jul</guid>
<pubDate>Sun, 05 Nov 2023 14:03:39 +0000</pubDate>
</item>
<item>
<title>Would it make sense to have a flag to cache protocol implementation lookups?</title>
<link>https://ask.clojure.org/index.php/11801/would-make-sense-have-cache-protocol-implementation-lookups</link>
<description>&lt;p&gt;In recent conversation I learned that some developers avoid and discourage the use of &lt;code&gt;satisfies?&lt;/code&gt; because of performance concerns. I was told to &quot;just look at the implementation, you will sweat bullets&quot;.&lt;/p&gt;
&lt;p&gt;The implementation in this case is in &lt;code&gt;find-protocol-impl&lt;/code&gt; which has to check metadata, traverse the inheritance chain as well as implemented interfaces.&lt;/p&gt;
&lt;p&gt;The part of finding a protocol implementation for a specific class seems emminently cacheable, except for the fact that one can extend the protocol later on.&lt;/p&gt;
&lt;p&gt;Would it make sense to cache this, and have &lt;code&gt;extend-*&lt;/code&gt; invalidate the cache? Or alternatively to have a flag (e.g. &lt;code&gt;-J-Dclojure.cache-protocols=true&lt;/code&gt;) for use in production where you know all protocol implementations will be loaded before lookups happen?&lt;/p&gt;
</description>
<category>Protocols</category>
<guid isPermaLink="true">https://ask.clojure.org/index.php/11801/would-make-sense-have-cache-protocol-implementation-lookups</guid>
<pubDate>Mon, 25 Apr 2022 13:02:50 +0000</pubDate>
</item>
</channel>
</rss>