Search code examples
wcfwcf-clientwcf-faults

Log WCF Errors on Client


My application calls a web-service using WCF. The call can fail for various reasons:

  • fault
  • timeout
  • connection lost
  • ...

I want to log all such errors. Instead of wrapping every call in a try-catch, I want to do this in one place for all web-service calls in the entire application.

Unfortunately, an IClientMessageInspector does not get called for timeouts and connection failures. Is there a WCF extensibility point that I can use to centrally take note of all exceptions?

Notice, that I do not just want to log errors as text like WCF Tracing does it. I want to log:

  • ServiceName
  • MethodName
  • Duration
  • Exception.ToString()

I am open to workarounds.


Solution

  • I am not aware of an extensibility point, but I can provide a workaround that we have used. Basically, we created a "proxy" that all service calls were made through. Below is the proxy and an example of its use.

    /// <summary>
    /// Proxy for executing generic service methods
    /// </summary>
    public class ServiceProxy
    {
        /// <summary>
        /// Execute service method and get return value
        /// </summary>
        /// <typeparam name="C">Type of service</typeparam>
        /// <typeparam name="T">Type of return value</typeparam>
        /// <param name="action">Delegate for implementing the service method</param>
        /// <returns>Object of type T</returns>
        public static T Execute<C, T>(Func<C, T> action) where C : class, ICommunicationObject, new()
        {
            C svc = null;
    
            T result = default(T);
    
            try
            {
                svc = new C();
    
                result = action.Invoke(svc);
    
                svc.Close();
            }
            catch (FaultException ex)
            {
                // Logging goes here
                // Service Name: svc.GetType().Name
                // Method Name: action.Method.Name
                // Duration: You could note the time before/after the service call and calculate the difference
                // Exception: ex.Reason.ToString()
    
                if (svc != null)
                {
                    svc.Abort();
                }
    
                throw;
            }
            catch (Exception ex)
            {
                // Logging goes here
    
                if (svc != null)
                {
                    svc.Abort();
                }
    
                throw;
            }
    
            return result;
        }
    }
    

    And an example of its use:

    var result = ServiceProxy.Execute<MyServiceClient, MyReturnType>
    (
        svc => svc.GetSomething(someId)
    );