views:

105

answers:

5
try
{
   // Code
}
catch (Exception ex)
{
   Logger.Log("Message", ex);
   throw;
}

In the case of a library, should I even log the exception? Should I just throw it and allow the application to log it? My concern is that if I log the exception in the library, there will be many duplicates (because the library layer will log it, the application layer will log it, and anything in between), but if I don't log it in the library, it'll be hard to track down bugs. Is there a best practices for this?

+1  A: 

You should log it as well as throw it so that the application has this available for it to log. Particularly if its a library, you should log it, as you shouldn't assume that application will definitely log it!(it may or may not).

Mahesh Velaga
+2  A: 

I would not log an exception that I wasn't going to do anything with - ie, if it's just passing through an exception handler as in your example. As you already mentioned, this adds a lot of noise that isn't necessarily helpful. Better to log it at the point where you are actually doing something about it, or, in the case of a library, at the boundary where it transitions into the user's code.

That said, I always try to log at the point where I am throwing the exception and the condition that triggered the exception. This is much more useful to pin down the reason for the exception; plus, if the condition that you encounter is bad enough to warrant throwing an exception, I would say it also warrants spending the processor time logging out the 'why'.

Timo Geusch
+1  A: 

I tend to prefer leaving the logging up to the highest level client, or allow the client to enable/disable the logging potentially by providing a TextWriter to the library to which the library should log its errors/output in case it's running in an environment where it doesn't have permission to write to its usual log.

The reason I prefer to log at higher levels is that the higher levels have more context information, and may know more appropriate ways to report/log these errors. Since exceptions have all the stack trace information in them anyway these days, I don't think you gain much by logging immediately when the exception occurs. You do have to be careful about exceptions that get converted into other kinds of exceptions, though, so do consistently use InnerException if you are converting exceptions as they are being handled, in order to keep all the information about the source of an error.

Edit: Of course this philosophy only works in environments where my other philosophy is followed: never ignore exceptions. If the client or some intermediate layer is throwing exceptions away, then you have other problems and will probably need to at least default your exception log to some output that is generated even if the client is irresponsible.

BlueMonkMN
+1  A: 

Log exceptions could also be a method to debug a application.

streetparade
+1  A: 

Use log4net. Seriously.

By using such a standard and ubiquitous library you get guidance from people who have spent a long time thinking about this very problem. The solution is that most logging libraries have several levels of logging.

In log4net for example I can do

ILog log = LogManager.GetLogger("some logger");
log.Debug("some debugging info");
log.Info("some message meaningful in the domain");
log.Warn("something might be occurring that merits your attention");
log.Error("Everything just went to hell")

The application administrator can then set different levels of logging that he is interested in seeing. It is possible to even allow him to change this configuration at runtime. As a matter of fact, with a robust logging library like log4net you can direct different logging levels from different sources to different appenders. For example you can have a rolling file with all logging messages for the last week stored on the hard-disk, all info, warning, and error messages that do not originate in your data-access layer pushed into a database, and all Errors sent to you via Email.

I think what you are describing falls pretty clearly under the "debug" log level.

You can of course implement logging levels on your own but if anyone using your library is interested in seeing all debugging information, they will have to learn your system, in addition to whatever one they're using. Better to standardize.

So best-practices:

  1. Use different logging levels.
  2. Don't roll your own logging framework, use log4net (which really is in this day and age fairly standard) or at the very least Microsoft's entlib logging block.
George Mauer