Sunday, March 27, 2011

Analyze the use of a ASP.NET webservice

Hi,

long time ago I wrote webservice that is still in use. Now I plan to refacture it. The webservice is full of most likely unused functions and I have no idea how it is used by the clients. In order to strip away the unused functions I need to analyze the function calls and data of currently installed webservice.

Is there a (free/opensource) tool that will enable me to log all activities of the webservice.

The ideal output of the tool I'm looking for could be a database containing all the called functions and a list of the data that was send to it for each call.

Solution

With the help of Martins answer I created this HttpModule which does exactly what I wanted:

public class LoggingModule : IHttpModule
{
    void IHttpModule.Init(HttpApplication context)
    {
        context.BeginRequest += new EventHandler(BeginRequest);
    }

    private void BeginRequest(object sender, EventArgs e)
    {   
        TryAppendLog("Content-Type");
        TryAppendLog("SOAPAction");
    }

    void TryAppendLog(string key)
    {
        string value = HttpContext.Current.Request.Headers[key];
        if (string.IsNullOrEmpty(value)) { return; }            
        HttpContext.Current.Response
            .AppendToLog(string.Format("{0}: {1} ", key, value));           
    }

    #region IHttpModule Member
    public void Dispose() { }
    #endregion
}
From stackoverflow
  • You can potentially write your own IHttpHandler that would log all the information and then delegate the call to appropriate .NET HTTP Handler, but that wouldn't be a simple task.

    And a word on terminology. "Refactoring" is not about changing external behavior, so if refactoring is really what you're heading for, I'd recommend to keep the public contract (interface) of the web service intact. Instead, roll out a new version of the same service with only core functionality.

  • You can enable logging in the IIS, they can get very detailed depending on your choices.
    There are tools made specifically for analyzing IIS logs.

    Martin : AFAIK there is no way to record post data by using the logging of IIS, or is there?
    Kobi : Well, no that I know of. These logs can tell you who uses your methods and how much, but if you want to log the whole data, you will need more than that.
    Martin : If you talk to a webservice it is the function name which amongst others is written into the post data and thats the thing I'm intrested in.
  • Depending a little bit on your load/criticality and similar constraints you could also probably just route the traffic through as Soap Proxy like SoapUI to capture and analyze traffic for a period of time. If you set up the proxy and re-route at the firewall level it should be transparent for end-users.

    I have not tried this for a system with heavy load; be warned.

  • As Kobi wrote, you can find the required information in the IIS log files (i.e. in c:\WINDOWS\system32\LogFiles\W3SVC1).

    If you want to log the usage into a database, you could write a simple HttpModule, which checks every request, and logs it into the DB if it is a call to your web service. E.g. here's the relevant parts of a very simple HttpModule, which logs calls to mywebservice.asmx:

    public class MyWebServiceDiagnosticsModule : IHttpModule
    {
        public MyWebServiceDiagnosticsModule ()
        {
        }
        void IHttpModule.Init(HttpApplication context)
        {
         context.BeginRequest += new EventHandler(BeginRequest);
        }
        private void BeginRequest(object sender, EventArgs e)
        {
         HttpContext ctx = HttpContext.Current;
         string url = ctx.Request.Url.ToString().ToLower();
         if (url.Contains("mywebservice.asmx"))
         {
             LogMethodCall(url); // parse URL and write to DB
         }
        }
    }
    
    Martin : I tried to use the HttpModule but after reading the post data found inside HttpContext.Current.Request.InputStream every request to this webservice failed. I assume that the Stream can only be read once.
    M4N : Do you have to read the stream? Can't you get everything you need out of the URL or the request header? E.g. to get the web method that is being called, you can use this: string webMethod = ctx.Request.Headers["SOAPAction"];
    Martin : yep, that did the job - thanks

0 comments:

Post a Comment