Friday, December 28, 2012

Diagnostic Logging

"Which logging framework should I use?" isn't the first question you should be asking in relation to diagnostic logs. Consider these instead: 

  • Can you debug your application using only the logs without a debugger attached?
  • Is there so much noise and useless information in the logs that you are searching for a needle in a haystack?
  • If you refactor your code, does your logging reflect the new code layout / workflow allowing you to pinpoint the cause of the problems easily?
  • Do you treat your logs like a user interface? Do you regularly review them for usefulness and usability?
  • Are your logs a security risk?
  • Can you correlate logs to business events or user actions (e.g. correlation ID)?
  • Have you tested the performance and scalability of your logs to ensure they have a negligible impact on your systems?
  • Do your logs have unintended side-effects on your application? (for example, forcing participation in a distributed transaction, or even deadlocks under heavy load)
Once you're confident that you're able to answer the above questions satisfactorily, the original question about which logging framework to use: It depends on your technology and your needs. Whatever those turn out to be, here's the list of features I usually look for:

  • Filtering/Targeting: Based on category or log source, I can filter the log output or target log output from different components to different places.
  • Pluggable sinks: Can I redirect log output to custom sinks and are there libraries of built-in sinks to choose from?
  • Can the framework gather extra contextual information so I don’t have to gather it when I want to log (e.g. thread id/name, class name, machine name, timestamp etc.)
  • Is the framework performant? Does it mostly evaluate to a no-op if I have logging verbosity turned down?
  • Can I dynamically change the logging verbosity in production in response to an event? I've seen some production systems direct all Debug info to an in-memory buffer and only dump that buffer to disk when an error level event happens (allowing you to see a bunch of debug info from *prior* to the error)
  • Can I adjust the formatting of the output? Are there built in formats compatible with log reading tools?
  • Do you actively manage the size of your logs? Rolling file and auto cleanup are useful.
Good logging practices have served me well over the years, but for every new system I build, I tend to use less and less logging - down to the point where I'm only logging macro level tasks that are going to change the internal state or configuration of the system in a major way. I find myself getting closer to the guidelines posted by Jeff Atwood.

No comments:

Post a Comment