tags:

views:

241

answers:

2

I'm building a web application using WCF that will be consumed by other applications as a service. Our app will be installed on a farm of web services and load balanced for scalability purposes. Occasionally we run into problems specific to one web server and we'd like to be able to determine from the response which web server the request was processed by and possibly timing information as well. For example, this request was processed by WebServer01 and the request took 200ms to finish.

The first solution that came to mind was to build an ISAPI filter to add an HTTP header that stores this information in the response. This strikes me as the kind of thing somebody must have done before. Is there a better way to do this or an off-the-shelf ISAPI filter that I can use for this?

Thanks in advance

A: 

WCF offers much nicer extension points than ISAPI filters. You could e.g. create a client side message inspector that gets called just before the message goes out to the server, and then also gets called when the response comes back, and thus you could fairly easily measure the time needed for a service call from a client perspective.

Check out the IClientMessageInspector interface - that might be what you're looking for. Also see this excellent blog entry on how to use this interface.

Marc

marc_s
Thanks Marc. I can definitely suggest this to our client apps, but given the number and variety of them, I was hoping for something that could be implemented on the back-end.
Andrew Burke
Andrew - there's of course also a server-side equivalent - the IDispatchMessageInspector - which can inspect messages as they arrive at the server and jsut before the response is sent back.
marc_s
A: 

I don't have a ready-made solution for you but I can point you towards IHttpModule. See code in Instrument and Monitor Your ASP.NET Apps Using WMI and MOM 2005 for example.

    private DateTime startTime;

    private void context_BeginRequest(object sender, EventArgs e)
    {
        startTime = DateTime.Now;
    }

    private void context_EndRequest(object sender, EventArgs e)
    {
        // Increment corresponding counter
        string ipAddress = HttpContext.Current.Request.
            ServerVariables["REMOTE_ADDR"];
        if (HttpContext.Current.Request.IsAuthenticated)
            authenticatedUsers.Add(ipAddress);
        else
            anonymousUsers.Add(ipAddress);
        // Fire excessively long request event if necessary
        int duration = (int) DateTime.Now.Subtract(
            startTime).TotalMilliseconds;
        if (duration > excessivelyLongRequestThreshold)
        {
            string requestPath=HttpContext.Current.Request.Path;
            new AspNetExcessivelyLongRequestEvent(applicationName,
                duration,requestPath).Fire();
        }
    }
eed3si9n