Monday, December 8, 2014

Logs are like onions

Or, What underlying implementation is using?

Today I want to change the logging configuration of a Clojure program. Where is that configuration located? Changing the obvious resources/ doesn't seem to change the program's behavior.

The program uses, but that's a wrapper around four different underlying implementations. Each of those implementations has its own ideas about configuration. How can I find out which one it uses?

Add a println to your program[1] to output this:
In my case the output is:

This is clojure logging's first choice of factories. If it can instantiate this, it'll use it. Now I can google slf4j and find that it... is also a facade on top of multiple logging implementations.

Digging into the slf4j source code reveals this trick:
(class (org.slf4j.LoggerFactory/getILoggerFactory)) 
which prints:
so hey! I am using log4j after all! Now why doesn't it pick up resources/
Crawling through the log4j 1.2 (slf4j seems to use this version) source code suggests this[2]:
(org.apache.log4j.helpers.Loader/getResource "")
which gives me
#<URL file:/Users/jessitron/.../resources/>

So hey, I finally have a way to trace where logging configuration comes from! 

In the end, my guess of resources/ was correct. I forgot to rebuild the uberjar that I was running. The uberjar found the properties file in itself:
Bet I'd have realized that a few hours earlier if I were pairing today. And then I wouldn't have made this lovely post.

[1] or run it in the cider REPL in emacs, in your namespace
[2] actually it checks for log4j.xml first; if that's found it'll choose the xml file over the .properties.

No comments:

Post a Comment