46

Does anyone know how I could get IIS to log POST data or the entire HTTP request?

1

6 Answers 6

43

The IIS logs only record querystring and header information without any POST data.

If you're using IIS7, you can enabled Failed Request Tracing for status code 200. That will record all of the data and you can select which type of data to include.

In either IIS6 or 7, you can use Application_BeginRequest in global.asax and create your own logging of POST data.

Or, in IIS7, you can write a HTTP Module with your own custom logging.

7
  • +1 - I like your answer far, far better than my own. I clearly need to read up on failed request tracing, since I obviously haven't used IIS7 as much as I should. Dec 4, 2009 at 11:52
  • How can you "select which type of data to include"? Aug 23, 2012 at 1:31
  • 1
    The last step of the wizard when creating a FRT rule allows you to select which data to include. It defaults to including everything. Aug 24, 2012 at 19:24
  • 1
    It doesn't appear (from that url Andyknas shared) that IIS "advanced logging" logs form posts. It offers an option for "client logging" , which would log posts of a particular sort, but not all form posts, which the OP seems to be requesting (and I was wondering about, myself.) Feb 16, 2019 at 0:17
  • 1
    How do you "enable Failed Request Tracing" in IIS?
    – Vincent
    Aug 19, 2021 at 22:35
10

In managed code you can use the Response.AppendToLog method.  This method will append data to the cs-uri-stem field -- the total length is up to 4100 characters (undocumented).  If you exceed that limit, then the value that would have been logged is replaced with "..."

For instance, adding something like this to your Global.asax file should do the trick (C#):

void Application_EndRequest(Object Sender, EventArgs e)
{
    if( "POST" == Request.HttpMethod )
    {
        byte[] bytes    = Request.BinaryRead(Request.TotalBytes);
        string s    = Encoding.UTF8.GetString(bytes);
        if (!String.IsNullOrEmpty(s))
        {
            int QueryStringLength = 0;
            if (0 < Request.QueryString.Count)
            {
                QueryStringLength = Request.ServerVariables["QUERY_STRING"].Length;
                Response.AppendToLog( "&" );
            }

            if (4100 > ( QueryStringLength + s.Length ) )
            {
                Response.AppendToLog(s);
            }
            else
            {
                // append only the first 4090 the limit is a total of 4100 char.
                Response.AppendToLog(s.Substring(0, ( 4090 - QueryStringLength )));
                // indicate buffer exceeded
                Response.AppendToLog("|||...|||");
                // TODO: if s.Length >; 4000 then log to separate file
            }
        }       
    }
}
 
3
  • 1
    As of this comment, the limit is not 4100, it's 4KB which is 4096. So this code needs to be modified slightly to log POST data >4KB correctly.
    – Steven V
    Jan 29, 2014 at 20:42
  • 2
    I had to add HttpContext.Current.Request.InputStream.Position = 0; before request.BinaryRead, otherwise it would return empty array
    – alex440
    May 14, 2014 at 9:40
  • using Application_BeginRequest also works without having to set InputStream.Position=0
    – Rocky
    Jun 18, 2021 at 17:48
5

While I appreciate that this is an old question, I found this code gave me exactly what I needed, a text file with the complete request headers and the response, put it into your global.asax.cs:

protected void Application_BeginRequest(Object Sender, EventArgs e)
{
    string uniqueid = DateTime.Now.Ticks.ToString();
    string logfile = String.Format("C:\\path\\to\\folder\\requests\\{0}.txt", uniqueid);
    Request.SaveAs(logfile, true);
}

This will create a text file for each and every request (including images) so be careful where you use it. I only used it to log specific post requests.

2

Try this in your web.config file to trace everything

<tracing>
  <traceFailedRequests>
    <remove path="*" />
    <add path="*">
      <traceAreas>
        <add provider="ASP" verbosity="Verbose" />
        <add provider="ASPNET" areas="Infrastructure,Module,Page,AppServices" verbosity="Verbose" />
        <add provider="ISAPI Extension" verbosity="Verbose" />
        <add provider="WWW Server" areas="Authentication,Security,Filter,StaticFile,CGI,Compression,Cache,RequestNotifications,Module,FastCGI,WebSocket,Rewrite" verbosity="Verbose" />
      </traceAreas>
      <failureDefinitions timeTaken="00:00:00" statusCodes="200-999" />
    </add>
  </traceFailedRequests>
</tracing>
1
  • But note that the FRT feature implicitly limits the number of log files it creates (which is a good thing), so you would need to change that, either in the UI or via config file entries--and with due caution for the volume of logs that would be created in even a modest web app. Feb 16, 2019 at 0:19
0

This looks encouraging, though I have not yet tried it:

https://www.codeproject.com/Tips/1213108/HttpModule-for-Logging-HTTP-POST-Data-in-IIS-Log

How does this differ from the other option offered here, with code in the global.asax.cs? That would only work for ASP.NET page requests, not other pages IIS might process (php, cgi, jsp, cfml). The link I shared is to a module that one could enable in IIS for any site (or at the server level) to process for any type of request.

-4

Try enabling the following in your IIS log settings:

Method (cs-method)

URI Stem (cs-uri-stem)

URI Query (cs-uri-query)

2
  • I've tried, haven't helped... :(
    – Budda
    Oct 20, 2010 at 21:21
  • 3
    Those settings will not include POST data
    – rob
    May 14, 2014 at 10:03

You must log in to answer this question.