Code to logging ratio? [closed]

What is the ideal code to logging ratio? I'm not used to writing logs as most of the applications I've developed have not had much logging.

Recently though I've changed job, and I've noticed that you can't see the application code for the calls to log4net. I appreciate that this is useful but surely having too many debug statements is just as bad as not having any at all?

There are logging statements that tell you when every method starts and finishes and what they are returning. and when pretty much anything is done.

Would it not be easier to have some addon that used reflection to add the logging statements in at compile time so they didn't get in the way as you were trying to look at the code?

Also in these days of powerful IDEs and remote debugging is that much logging really nescisary?


Solution 1:

Since log4net does a great job at not clogging up the resources, I tend to be a little verbose on logging because when you have to change to debug mode, the more info you have, the better. Here's what I typically log:

DEBUG Level

  • Any parameters passed into the method
  • Any row counts from result sets I retrieve
  • Any datarows that may contain suspicious data when being passed down to the method
  • Any "generated" file paths, connection strings, or other values that could get mungled up when being "pieced together" by the environment.

INFO Level

  • The start and end of the method
  • The start and end of any major loops
  • The start of any major case/switch statements

ERROR Level

  • Handled exceptions
  • Invalid login attempts (if security is an issue)
  • Bad data that I have intercepted forreporting

FATAL Level

  • Unhandled exceptions.

Also having a lot of logging details prevents me from asking the user what they were doing when they got the error message. I can easily piece it together.

Solution 2:

Complete log files are amazingly useful. Consider a situation where your application is deployed somewhere like a bank. You can't go in there and debug it by hand and they sure aren't going to send you their data. What you can get is a complete log which can point you to where the problem occured. Having a number of log levels is very helpful. Normally the application would run in a mode such that it only reports on fatal errors or serious errors. When you need to debug it a user can switch on the debug or trace output and get far more information.

The sort of logging you're seeing does seem excessive but I can't really say it is for certain without knowing more about the application and where it might be deployed.

Solution 3:

Also in these days of powerful IDEs and remote debugging is that much logging really nescisary?

Yes, absolutely, although the mistake that many unskilled developers make is to try to fix bugs using the wrong method, usually tending towards logging when they should be debugging. There is a place for each, but there are at least a few areas where logging will almost always be necessary:

  • For examining problems in realtime code, where pausing with the debugger would effect the result of the calculation (granted, logging will have a slight impact on timing in a realtime process like this, but how much depends greatly on the software)
  • For builds sent to beta testers or other colleagues who may not have access to a debugger
  • For dumping data to disk that may not be easy to view within a debugger. For instance, certain IDE's which cannot correctly parse STL structures.
  • For getting a "feel" of the normal flow of your program
  • For making code more readable in addition to commenting, like so:
// Now open the data file
fp = fopen("data.bin", "rb");

The above comment could just as easily be placed in a logging call:

const char *kDataFile = "data.bin";
log("Now opening the data file %s", kDataFile);
fp = fopen(kDataFile, "rb");

That said, you are in some ways correct. Using the logging mechanism as a glorified stack-trace logger will generate very poor quality logfiles, as it doesn't provide a useful enough failure point for the developer to examine. So the key here is obviously the correct and prudent use of logging calls, which I think boils down to the developer's discretion. You need to consider that you're essentially making the logfiles for yourself; your users don't care about them and will usually grossly misinterpret their contents anyways, but you can use them to at least determine why your program misbehaved.

Also, it's quite rare that a logfile will point you to the direct source of a certain bug. In my experience, it usually provides some insight into how you can replicate a bug, and then either by the process of replicating it or debugging it, find the cause of the problem.