WCF Error Handling with log4net
In this blog post I will be going through how to do error handing with WCF by using attributes to log your errors.
There are multiple ways to do error handling in WCF as listed by Pedram Rezaei Blog.
The default way that WCF allows errors message to display is by setting IncludeExceptionDetailInFaults Property to true in web.config or on the service attribute but this is only recommended when you need to debug you development code not in your shipped/release code.
In Web.config file
In the web.config file of the WCF service the includeExceptionDetailFaults attribute set it to true. With this action every endpoint associated to WCF service will send managed exception information.
In Attribute
Another way is setting the IncludeExceptionDatailInFaults property to true using the ServiceBehaviorAttribute.
That is fine and dandy but it is definitely not recommended for production server, you don’t want an stack trace to show up when someone is viewing it on the webpage for this service.
The IErrorHandler interface
The basic form of error logging in WCF is to use the IErrorHandler interface, which enables developers to customize the default exception reporting and propagation, and provides for a hook for custom logging.
Another thing to note is we need to implement the IServiceBehavior also since installing our own custom implementation of IErrorHandler requires adding it to the desired dispatcher. Since we need to treat the extensions as custom service behaviors in order for it to work.
Rather than just calling Log4Net I create a class called Logger which decouples log4net so that one can use any logging framework by using a dependency injection framework. (Code not listed)
Back to building our own ErrorHandler, ServiceBehavior with Attribute, the code is listed below
Now one can just add an attribute to the WCF service code to log our error message to log4net or whatever logging framework that you may be using.
There is also another way by using the web.config and adding the error logging to all the services listed by Stever B in his blog, but I find that does not give me the flexibility that I wanted, I may want to log some but not others etc.
Hope you enjoy this post.
This article is very helpfull.. Thank for posting such a nice stuff.
Thanks,
Kulwinder
No problem you are welcome.
This looks like a very nice way to do it, good job
I’m also using log4net (but without a wrapper..), and have a question:
– where do you initialize the logger? And wich Type do you supply?
– If I log inside HandleError, does log4net show the correct type?
One can initialize the logger by an IoC container (StructureMap, Ninject, Windsor, or a ServiceLocator etc etc) or just in code like in your Attribute
private static readonly ILog log = LogManager.GetLogger(
System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
and then if you wish to log it as an error just use
log.Error(“Service failed : ” + ex.Message);
inside your HandleError call, if you wish for it to be debug just call log.debug its up to you.
Ya, that’s great code, copied from msdn, minus the portions which actually do some error detection in the handling code itself.
http://msdn.microsoft.com/en-us/library/ms751439.aspx
Hi! Can you update you code as I’m not able to compile it. The first issue is in the ApplyDispatchBehavior()’s foreach loop: the variable channelDispatcherBase’s type is causing confusion. If I define it as a var, I cannot add ‘this’ to the Error Handlers. If I leave it defined as ChannelDispatcher, there is a warning about a cast. The second issue is in HandleError: Logger.LogException(error); I cannot find the LogException method in log4Net
What happens if you don’t use a var? Does that work?
Also the LogException is just a wrapper I wrote, you can use the Logger.Warn or Logger.Error or Fatal it is up to you on how you wish to log the information