This blog has moved to Medium

Subscribe via email


Posts tagged ‘Logging’

Pro tip – define your log repository as a Chrome Custom Search Engine

If you have a production app, you should be using some log repository (we use Splunk at Commerce Sciences).

Now, Splunk is great, but it’s causing us a bit of a headache – whenever we access it, we have to go through a few pages of login (not really needed), and a page requesting we upgrade to the latest version (we usually ignore it). All and all, it takes too much time and friction to search for logs.

Today, I had a cool idea – why not configure a Chrome Custom Search Engine and save us the trouble? It turns out it works and it’s awesome (it makes your log just a CTRL-L away). Just add a new Splunk search engine (read the help if you need), enter your favorite keyboard shortcut (I went with “spl”, but you can use “log”) and as a URL enter

http://yoursplunkserver.com/en-US/app/search/flashtimeline?q=search%20%s

That’s it – you just made your logs a whole lot more accessible. If you try this on another log repository other than Splunk, please post your own URL as a comment. Enjoy!

Avoid expensive ToString() calls in log4net

premature optimization is the root of all evil.” (Donald Knuth)

And, if I might add: “ugly optimization is not so great either”.

We have some classes with rather expensive ToString() methods in our code base. When used in logs (specifically, log4net), we incured the performance penality even when the logging level (Debug/Info/Warn/…) was too low, and the log wasn’t even printed. In other words, ToString() was called before the log method, in order to build the single string that is the input parameter to Logger.Log().

Our ugly optimization was to add checks before every log line, as in:

if (logger.IsDebugEnabled)
   logger.Debug("Calling " + someObjectWithExpensiveToString);

A better solution, which I just tested to work, is to use the …Format() family of methods. This way, you pass objects and not strings, which are then only converted to strings if there is a need.

logger.DebugFormat("Calling {0}", someObjectWithExpensiveToString);

The following test assures me it actually works:

ILog logger = LogManager.GetLogger("Foo");
ToStringCounter counter = new ToStringCounter();
Assert.AreEqual(0, counter.ToStrings);
Assert.IsFalse(logger.IsDebugEnabled);
 
logger.DebugFormat("Expecting zero ToString() calls: {0}", counter);
Assert.AreEqual(0, counter.ToStrings);

Where ToStringCounter is simply a class that counts the number of calls to its ToString() method.