views:

223

answers:

2

I'm running an ASP.NET WebService on IIS 6.0 that shows a lot of HTTP 500 (probably just exceptions from the WebService) inside the log at %systemroot%\System32\LogFiles\W3SVC1 on a customers site.

Is it possible to log the content of those HTTP responses and there requests without modifying the WebService using IIS or a plug-in for IIS?

I thought of using Wireshark or Fiddler to sniff on the HTTP traffic but I would prefer to just turn on an option inside IIS to make him log the communication (this should not be to hard since it is logging the requested URLs anyway)

A: 

Create an HTTPModule and configure it in your ASP.NET configuration. You don't need to modify the existing Web Service's code (you needn't even have the sources), you just configure the HTTPModule in your Web.config.

In the HTTPModule, listen for events such as BeginRequest and EndRequest and you should be able to log the input to, and output from, the web service.

If you need to trap exceptions thrown in the web service, you could capture the Error event as described here and here.

Update:

According to this page, you can't use the Error event approach with web services as web service errors don't get routed to the Error event. Microsoft suggests that you use SOAP Extensions to log web service errors.

Vinay Sajip
This approach sounds a lot like elmah (see http://code.google.com/p/elmah) which AFAIK only works with normal web-sites but not with a WebService since the HTTPModule is unable to capture errors coming from a WebService.
Martin
It looks like the link to `SOAP Extensions` in your update is not working - this seems to be the correct one: http://msdn.microsoft.com/en-us/magazine/cc164007.aspx
Martin
A: 

We've done this before using log4net. Here are the high level steps:

Create a log4net section in your web.config

<configuration>
  <configSections>
    <section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler,log4net" />
  </configSections>

and...

...
</system.web>
  <log4net>
    <appender name="RollingLogFileAppender" type="log4net.Appender.RollingFileAppender,log4net">
      <param name="File" value="c:\mysvc.log" />
      <param name="AppendToFile" value="true" />
      <param name="MaxSizeRollBackups" value="10" />
      <param name="MaximumFileSize" value="1000000" />
      <param name="RollingStyle" value="Size" />
      <param name="StaticLogFileName" value="true" />
      <layout type="log4net.Layout.PatternLayout,log4net">
        <param name="ConversionPattern" value="%d [%t] %-5p %c - %m%n" />
      </layout>
    </appender>
    <!-- Setup the root category, add the appenders and set the default priority -->
    <root>
      <level value="DEBUG" />
      <!--<priority value="DEBUG" />-->
      <appender-ref ref="RollingLogFileAppender" />
    </root>
  </log4net>

...

In your Global.asax.cs call the log4net Configure()

protected void Application_Start(Object sender, EventArgs e)
{
            log4net.Config.DOMConfigurator.Configure();
}

At the top of your web service .cs file, declare an instance of a log4net ILog

public class MyService : System.Web.Services.WebService {
{
   private static readonly ILog log = LogManager.GetLogger(typeof(MyService));

In your web service methods, trap exceptions and log them

[WebMethod]
public void DoSomething()
{
  try
  {
     // business logic
  }
  catch(Exception ex)
  {
     log.Error("Something bad happened", ex);
     throw;
  }
}

After these steps, in the example above any exceptions will appear in c:\mysvc.log

mjmarsh
This would involve modifying the WebService which I want to avoid (see my original question).
Martin