We were also experiencing this bug but we were using an asset management library (Cassette). After an extensive investigation of this issue, we’ve found that the root cause of this issue is with a combination of ASP.NET, IIS, and Cassette. I’m not sure if this is your problem (using the Headers
API rather than the Cache
API), but the pattern seems to be the same.
Bug # 1
Cassette sets the Vary: Accept-Encoding
header as part of its response to a bundle since it can encode the content with gzip/deflate:
- BundleRequestHandler: https://github.com/andrewdavey/cassette/blob/a2d9870eb0dc3585ef3dd542287595bc6162a21a/src/Cassette.Aspnet/BundleRequestHandler.cs#L78
- HttpResponseUtil: https://github.com/andrewdavey/cassette/blob/a2d9870eb0dc3585ef3dd542287595bc6162a21a/src/Cassette.Aspnet/HttpResponseUtil.cs#L45
However, the ASP.NET output cache will always return the response that was cached first. For example, if the first request has Accept-Encoding: gzip
and Cassette returns gzipped content, the ASP.NET output cache will cache the URL as Content-Encoding: gzip
. The next request to the same URL but with a different acceptable encoding (e.g. Accept-Encoding: deflate
) will return the cached response with Content-Encoding: gzip
.
This bug is caused by Cassette using the HttpResponseBase.Cache
API to set the output cache settings (e.g. Cache-Control: public
) but using the HttpResponseBase.Headers
API to set the Vary: Accept-Encoding
header. The problem is that the ASP.NET OutputCacheModule
is not aware of response headers; it only works via the Cache
API. That is, it expects the developer to use an invisibly tightly-coupled API rather than just standard HTTP.
Bug # 2
When using IIS 7.5 (Windows Server 2008 R2), bug # 1 can cause a separate issue with the IIS kernel and user caches. For example, once a bundle is successfully cached with Content-Encoding: gzip
, it’s possible to see it in the IIS kernel cache with netsh http show cachestate
. It shows a response with 200 status code and content encoding of «gzip». If the next request has a different acceptable encoding (e.g.
Accept-Encoding: deflate
) and an If-None-Match
header that matches the bundle’s hash, the request into IIS’s kernel and user mode caches will be considered a miss. Thus, causing the request to be handled by Cassette which returns a 304:
- BundleRequestHandler: https://github.com/andrewdavey/cassette/blob/a2d9870eb0dc3585ef3dd542287595bc6162a21a/src/Cassette.Aspnet/BundleRequestHandler.cs#L44
However, once IIS’s kernel and user modes process the response, they will see that the response for the URL has changed and the cache should be updated. If the IIS kernel cache is checked with netsh http show cachestate
again, the cached 200 response is replaced with a 304 response. All subsequent requests to the bundle, regardless of Accept-Encoding
and If-None-Match
will return a 304 response. We saw the devastating effects of this bug where all users were served a 304 for our core script because of a random request that had an unexpected Accept-Encoding
and If-None-Match
.
The problem seems to be that the IIS kernel and user mode caches are not able to vary based on the Accept-Encoding
header. As evidence of this, by using the Cache
API with the workaround below, the IIS kernel and user mode caches seem to be always skipped (only the ASP.NET output cache is used). This can be confirmed by checking that netsh http show cachestate
is empty with the workaround below. ASP.NET communicates with the IIS worker directly to selectively enable or disable the IIS kernel and user mode caches per-request.
We were not able to reproduce this bug on newer versions of IIS (e.g. IIS Express 10). However, bug # 1 was still reproducible.
Our original fix for this bug was to disable IIS kernel/user mode caching only for Cassette requests like others mentioned. By doing so, we uncovered bug # 1 when deploying an extra layer of caching in front of our web servers. The reason that the query string hack worked is because the OutputCacheModule
will record a cache miss if the Cache
API has not been used to vary based on the QueryString
and if the request has a QueryString
.
Workaround
We’ve been planning to move away from Cassette anyways, so rather than maintaining our own fork of Cassette (or trying to get a PR merged), we opted to use an HTTP module to work around this issue.
public class FixCassetteContentEncodingOutputCacheBugModule : IHttpModule
{
public void Init(HttpApplication context)
{
context.PostRequestHandlerExecute += Context_PostRequestHandlerExecute;
}
private void Context_PostRequestHandlerExecute(object sender, EventArgs e)
{
var httpContext = HttpContext.Current;
if (httpContext == null)
{
return;
}
var request = httpContext.Request;
var response = httpContext.Response;
if (request.HttpMethod != "GET")
{
return;
}
var path = request.Path;
if (!path.StartsWith("/cassette.axd", StringComparison.InvariantCultureIgnoreCase))
{
return;
}
if (response.Headers["Vary"] == "Accept-Encoding")
{
httpContext.Response.Cache.VaryByHeaders.SetHeaders(new[] { "Accept-Encoding" });
}
}
public void Dispose()
{
}
}
I hope this helps someone 😄!
User153231335 posted
Hi,
I’ve been experiencing a number of cases where clients would receive loading errors at random, apparently. After some debugging I nailed the following example request down:
REQUEST
GET /xyz/SomeFlashFile.swf HTTP/1.1
GUID: 47e49e6e-8646-4cb5-a0c2-947d50b90a06
Host: xyz.com
RESPONSE
HTTP/1.1 304 Not Modified
Last-Modified: Mon, 25 Jan 2010 10:40:12 GMT
Accept-Ranges: bytes
ETag: «0eaec5aa9dca1:0»
Server: Microsoft-IIS/7.0
IPServer: WEB1
X-Powered-By: ASP.NET
Date: Mon, 01 Mar 2010 12:37:31 GMT
The client clearly has no cache of the local file, providing neither the if-modified-since or if-none-match request headers — yet, ARR responds with a 304 Not Modified response — causing the client to fail.
I setup FREB logging of response codes 200-500 on both the load balancer as well as all content servers and by setting a custom GUID in the request host headers, I should be able to catch the reply in the ARR FREB logs. However,
no FREB log was generated for the request/response, neither on the ARR load balancer nor on the content server.
An interesting thing to notice is the «IPServer: WEB1» header — this is set programmatically by our content server to trace which server handled the response originally — but WEB1 has no record of the request either.
Performing a «netsh http show cache» I can see that the SomeFlashFile.swf is sometimes cached:
URL: http://xyz.com/SomeFlashFile.swf
Status code: 304
HTTP verb: GET
Cache policy type: Time to live
Cache entry Time to Live (secs): 5
Creation time: 2010.1.25:10.40.12:0
Request queue name: DefaultAppPool
Headers length: 189
Content length: 0
Hit count: 1
Force disconnect after serving: FALSE
However, I can only assume this cached file should not be served to a client specifying it does not have the file cached locally? Also I’m guessing the reason I’m not seeing anything in the FREB logs is because this is handled
at kernel level and thus never reaches the IIS itself?
I seem to have fixed the problem by changing the «Memory cache duration» from the default value of 5 seconds to 0 seconds under the Caching settings of my farm. However, this feels
more like a workaround than a fix to me, unless I’m misunderstanding how the cache is used?
Note that I’m running Server 2008 x64 SP2 with IIS7 and ARR v1. Haven’t had a chance to upgrade to v2, but depending on the response I get to this issue, this may be enough of a reason to do so.
Thanks,
Mark S. Rasmussen
I am working on fixing a bug, and for testing purposes, I need a way to force my IIS server to return a 304 response code from a simple GET request. I do not have much experience working with IIS servers, so I am wondering if anyone has an idea on how I could do this. For testing and debugging purposes, the simplest manner would be appreciated so that I can constantly reproduce the behaviour.
Before learning that the server has to be IIS, I was able to do this using a perl script, in which I would create my own server and http::response and alter the header. But this method is no longer viable.
Any thoughts?
asked May 27, 2013 at 20:01
2
For Classic ASP
Since you mention classic ASP, here is how to return a 304. Just add a page under your website directory, and put in this code:
<%@ Language=VBScript %>
<%
Response.Status = "304 You have a 304 error"
%>
Then in the browser you can just request the above page (it should do a get request).
More info at the Response.Status page at MSDN.
For ASP.NET
If you need to use ASP.NET, you can use Visual Studio to add a new Web Forms page. When you do this there should be multiple files. You just need to find the file that ends in «aspx.cs» (or aspx.vb). Inside the Page_Load
function, just add the following line.
For C#:
Response.StatusCode = 304;
For VB:
Response.StatusCode = 304
More info at the Response.StatusCode page at MSDN.
answered May 28, 2013 at 14:56
chue xchue x
18.5k7 gold badges56 silver badges70 bronze badges
7
Question
What do the various IIS error codes mean?
Answer
IIS Status Codes
The following information was extracted from Microsoft KB article 318380.
Summary
When users try to access content on a server that is running Internet Information Services (IIS) through HTTP or File Transfer Protocol (FTP), IIS returns a numeric code that indicates the status of the request. This status code is recorded in the IIS log, and it may also be displayed in the Web browser or FTP client. The status code can indicate whether a particular request is successful or unsuccessful and can also reveal the exact reason why a request is unsuccessful.
Log File Locations
By default, IIS places its log files in %WINDIRSystem32Logfiles. This directory contains separate directories for each World Wide Web (WWW) and FTP site. By default, logs are created in the directories daily and are named with the date (for example, exYYMMDD.log).
HTTP
1xx — Informational
These status codes indicate a provisional response. The client should be prepared to receive one or more 1xx responses before receiving a regular response.
100 — Continue. | |
101 — Switching protocols. |
2xx — Success
This class of status codes indicates that the server successfully accepted the client request.
200 — OK. The client request has succeeded. | |
201 — Created. | |
202 — Accepted. | |
203 — Non-authoritative information. | |
204 — No content. | |
205 — Reset content. | |
206 — Partial content. |
3xx — Redirection
The client browser must take more action to fulfill the request. For example, the browser may have to request a different page on the server or repeat the request by using a proxy server.
301 — Moved Permanently | |
302 — Object moved. | |
304 — Not modified. | |
307 — Temporary redirect. |
4xx — Client Error
An error occurs, and the client appears to be at fault. For example, the client may request a page that does not exist, or the client may not provide valid authentication information.
400 — Bad request. | |||||||||||||||||||||||||||||||||||||||||
401 — Access denied. IIS defines a number of different 401 errors that indicate a more specific cause of the error. These specific error codes are displayed in the browser but are not displayed in the IIS log:
|
|||||||||||||||||||||||||||||||||||||||||
403 — Forbidden. IIS defines a number of different 403 errors that indicate a more specific cause of the error:
|
|||||||||||||||||||||||||||||||||||||||||
404 — Not found.
|
|||||||||||||||||||||||||||||||||||||||||
405 — HTTP verb used to access this page is not allowed (method not allowed.) | |||||||||||||||||||||||||||||||||||||||||
406 — Client browser does not accept the MIME type of the requested page. | |||||||||||||||||||||||||||||||||||||||||
407 — Proxy authentication required. | |||||||||||||||||||||||||||||||||||||||||
412 — Precondition failed. | |||||||||||||||||||||||||||||||||||||||||
413 – Request entity too large. | |||||||||||||||||||||||||||||||||||||||||
414 — Request-URI too long. | |||||||||||||||||||||||||||||||||||||||||
415 – Unsupported media type. | |||||||||||||||||||||||||||||||||||||||||
416 – Requested range not satisfiable. | |||||||||||||||||||||||||||||||||||||||||
417 – Execution failed. | |||||||||||||||||||||||||||||||||||||||||
423 – Locked error. |
5xx — Server Error
The server cannot complete the request because it encounters an error.
500 — Internal server error.
|
|||||||||||||
501 — Header values specify a configuration that is not implemented. | |||||||||||||
502 — Web server received an invalid response while acting as a gateway or proxy.
|
|||||||||||||
503 — Service unavailable. This error code is specific to IIS 6.0. | |||||||||||||
504 — Gateway timeout. | |||||||||||||
505 — HTTP version not supported. |
Common HTTP Status Codes and Their Causes
200 — Success. This status code indicates that IIS has successfully processed the request. | |||||
304 — Not Modified. The client requests a document that is already in its cache and the document has not been modified since it was cached. The client uses the cached copy of the document, instead of downloading it from the server. | |||||
401.1 — Logon failed. The logon attempt is unsuccessful, probably because of a user name or password that is not valid. | |||||
401.3 — Unauthorized due to ACL on resource. This indicates a problem with NTFS permissions. This error may occur even if the permissions are correct for the file that you are trying to access. For example, you see this error if the IUSR account does not have access to the C:WinntSystem32Inetsrv directory. For additional information about how to resolve this problem, click the following article number to view the article in the Microsoft Knowledge Base:
187506 (http://support.microsoft.com/kb/187506/) INFO: Basic NTFS permissions for IIS 4.0 |
|||||
403.1 — Execute access forbidden. The following are two common causes of this error message:
|
|||||
403.2 — Read access forbidden. Verify that you have set up IIS to allow Read access to the directory. Also, if you are using a default document, verify that the document exists. For additional information about how to resolve this problem, click the article number below to view the article in the Microsoft Knowledge Base:
247677 (http://support.microsoft.com/kb/247677/EN-US/) Error Message: 403.2 Forbidden: Read Access Forbidden |
|||||
403.3 — Write access forbidden. Verify that the IIS permissions and the NTFS permissions are set up to grant Write access to the directory.For additional information about how to resolve this problem, click the article number below to view the article in the Microsoft Knowledge Base:
248072 (http://support.microsoft.com/kb/248072/EN-US/) Error Message: 403.3 Forbidden: Write Access Forbidden |
|||||
403.4 — SSL required. Disable the Require secure channel option, or use HTTPS instead of HTTP to access the page. If you receive this error for a Web site that does not have a certificate installed, click the article number below to view the article in the Microsoft Knowledge Base:
224389 (http://support.microsoft.com/kb/224389/EN-US/) Err Msg: HTTP Error 403, 403.4, 403.5 Forbidden: SSL Required |
|||||
403.5 — SSL 128 required. Disable the Require 128-bit encryption option, or use a browser that supports 128-bit encryption to view the page. If you receive this error for a Web site that does not have a certificate installed, click the article number below to view the article in the Microsoft Knowledge Base:
224389 (http://support.microsoft.com/kb/224389/EN-US/) Err Msg: HTTP Error 403, 403.4, 403.5 Forbidden: SSL Required |
|||||
403.6 — IP address rejected. You have configured your server to deny access to your current IP address. For additional information about how to resolve this problem, click the article number below to view the article in the Microsoft Knowledge Base:
248043 (http://support.microsoft.com/kb/248043/EN-US/) Error Message: 403.6 — Forbidden: IP Address Rejected |
|||||
403.7 — Client certificate required. You have configured your server to require a certificate for client authentication, but you do not have a valid client certificate installed. For additional information, click the article numbers below to view the articles in the Microsoft Knowledge Base:
190004 (http://support.microsoft.com/kb/190004/EN-US/) Error 403.7 or ‘Connection to Server Could Not Be Established’ 186812 (http://support.microsoft.com/kb/186812/EN-US/) PRB: Error Message: 403.7 Forbidden: Client Certificate Required |
|||||
403.8 — Site access denied. You have set up a domain name restriction for the domain that you are using to access your server.For additional information about how to resolve this problem, click the article number below to view the article in the Microsoft Knowledge Base:
248032 (http://support.microsoft.com/kb/248032/EN-US/) Error Message: Forbidden: Site Access Denied 403.8 |
|||||
403.9 — Too many users. The number of users who are connected to the server exceeds the connection limit that you have set. For additional information about how to change this limit, click the article number below to view the article in the Microsoft Knowledge Base:
248074 (http://support.microsoft.com/kb/248074/EN-US/) Error Message: Access Forbidden: Too Many Users Are Connected 403.9 NOTE: Microsoft Windows 2000 Professional and Microsoft Windows XP Professional automatically impose a 10-connection limit on IIS. You cannot change this limit. |
|||||
403.12 — Mapper denied access. The page that you want to access requires a client certificate, but the user ID that is mapped to your client certificate has been denied access to the file. For additional information, click the article number below to view the article in the Microsoft Knowledge Base:
248075 (http://support.microsoft.com/kb/248075/EN-US/) Error: HTTP 403.12 — Access Forbidden: Mapper Denied Access |
|||||
404 — Not found. This error may occur if the file that you are trying to access has been moved or deleted. It can also occur if you try to access a file that has a restricted file name extension after you install the URLScan tool. In this case, you see «Rejected by URLScan» in the log file entry for that request. | |||||
500 — Internal server error. You see this error message for a wide variety of server-side errors. Your event viewer logs may contain more information about why this error occurs. Additionally, you can disable friendly HTTP error messages to receive a detailed description of the error. For additional information about how to disable friendly HTTP error messages, click the article number below to view the article in the Microsoft Knowledge Base:
294807 (http://support.microsoft.com/kb/294807/EN-US/) HOWTO: Disable Internet Explorer 5 ‘Show Friendly HTTP Error Messages’ Feature on the Server Side |
|||||
500.12 — Application restarting. This indicates that you tried to load an ASP page while IIS was in the process of restarting the application. This message should disappear when you refresh the page. If you refresh the page and the message appears again, it may be caused by antivirus software that is scanning your Global.asa file. For additional information, click the article number below to view the article in the Microsoft Knowledge Base:
248013 (http://support.microsoft.com/kb/248013/EN-US/) Err Msg: HTTP Error 500-12 Application Restarting |
|||||
500-100.ASP — ASP error. You receive this error message when you try to load an ASP page that has errors in the code. To obtain more specific information about the error, disable friendly HTTP error messages. By default, this error is only enabled on the default Web site.For additional information about how to see this error on non-default Web sites, click the article number below to view the article in the Microsoft Knowledge Base:
261200 (http://support.microsoft.com/kb/261200/EN-US/) HTTP 500 Error Message Displays Instead of ASP Error Message from 500-100.asp |
|||||
502 — Bad gateway. You receive this error message when you try to run a CGI script that does not return a valid set of HTTP headers. |
title | author | description | ms.date | ms.assetid | msc.legacyurl | msc.type |
---|---|---|---|---|---|---|
Troubleshooting IIS Performance Issues or Application Errors using LogParser |
rick-anderson |
This article describes the troubleshooting steps to identify performance issues by using Microsoft’s LogParser to analyze IIS logs. |
12/18/2012 |
0a84b2a8-5ac6-41f4-b631-c1345b2ddf33 |
/learn/troubleshoot/performance-issues/troubleshooting-iis-performance-issues-or-application-errors-using-logparser |
authoredcontent |
Troubleshooting IIS Performance Issues or Application Errors using LogParser
by Benjamin Perkins
Tools and knowledge used in this Troubleshooter
- Microsoft LogParser (https://www.microsoft.com/download/details.aspx?id=24659)
- Command Prompt
- A basic knowledge of IIS HTTP Status Codes is helpful (https://support.microsoft.com/kb/943891)
- A basic knowledge of SQL queries is helpful
Overview
This troubleshooter will help you analyze IIS log files in an effort to determine the cause when an application that is hosted on IIS is failing or experiencing performance issues. Before you begin, it is important to note that all fields IIS can log are not enabled by default. For example, Bytes Sent and Bytes Received are not selected, but they are very useful when troubleshooting a performance problem. Therefore, the best time to include these additional fields is before you are experiencing system problems. So if you haven’t already done so, select these additional fields, they will help you find solutions when problems happen.
The following blog which discusses how to perform this on IIS 7+:
Modifying IIS 7 log data in Windows 2008
Scenario
As a Systems Administrator you begin to hear reports from users of your system hosted on IIS that the response is slow. There is some mention that web browsers simply time out or stop responding completely when they are accessing your website.
You jump into action and recycle the worker process; all appears to be working again, as normal.
However, you cannot accept that as a solution and need to know why this happened, but don’t know where to start. You have no details from the users, such as error codes, screen shots and worse, you have no performance data to compare what just happened to normal performance. In many cases, other new issues take you away from any serious root cause analysis.
Microsoft’s LogParser is a good tool that is quick and easy to use. In many situations, the tool will help you quickly get to a deeper understanding of what happened on the server and may help you identify problems. You can take the information you gather with LogParser and pass it along to your database team, your network team or to your developers for more analysis.
Data Collection
By default, IIS log files are located in the following directories:
- IIS 7 and later:
%SystemDrive%inetpublogsLogFiles
- IIS 6 and earlier:
%WinDir%System32LogFiles
In this troubleshooter, I will be using IIS 8. Open the IIS Manager and select Sites, as shown in Figure 1. This will show you the ID of each website hosted on your server. You will need this ID to determine which W3SVC* directory to analyze.
Figure 1: Getting the ID of your web site
Open Windows Explorer and navigate to the directory that contains the IIS log files of the website that experienced the performance problem. Figure 2 shows how that might look like.
Figure 2: IIS Log file location
IIS log files can be quite large; for example, in Figure 2, the log file u_ex12101858.log is nearly 100MB in size. Because these log files may be huge and contain hundreds of thousands of individual log file entries, manually looking through each of these files for an error is not a good approach, and returns few results for the time that you invest.
This is when LogParser becomes an indispensable tool in your troubleshooting arsenal.
Data Analysis
Your first step is to determine which log files may contain errors. For example, if customers were complaining about performance on the 3rd of June, 2012, the log file might be u_ex120603.log, where:
- «12» is the abbreviated year for 2012
- «06» refers to the sixth month (June)
- «03» is the 3rd day of the month
Note: The above example assumes that IIS logging is configured to rotate log files on a daily basis, which is the default. If you have changed the settings for IIS to rotate log files on a different time interval, such as weekly or hourly, then the log files names would be different. For more information about the syntax for IIS log file names, see the IIS Log File Naming Syntax (https://support.microsoft.com/kb/242898
) article.
[!NOTE]
By default, the date and time in IIS logs are stored using GMT; you will need to take this into account when you are determining which logs contain errors. That being said, you can adjust the dates/times by using LogParser’sTO_LOCALTIME()
function, as illustrated in the following example:
[!NOTE]
[!code-sqlMain]
Once you have identified the IIS log files that contain errors, you should copy them to a location where they can be analyzed. This step is optional, but it is not recommended that you analyze your logs on your IIS server since your LogParser queries may take a long time to run, and if your log files are large then Log Parser may compete for system resources.
For example, you might copy your IIS logs to a folder on your personal computer where you have already copied the LogParser files, which is how I typically analyze my log files. Figure 3 shows an example of where I stored them to create this article.
Figure 3: IIS Logs files locally hosted for analysis using LogParser
After you have downloaded LogParser, you are ready to begin the analysis. The first query I run is shown in Figure 4. The results give you an overview of how IIS has been responding to the requests.
[!code-consoleMain]
Figure 4: LogParser Query (sc-status and sc-substatus)
The points of interest within the results are:
- The ratio between 200 and 304 HTTP status codes (successful requests)
- The number of 500 HTTP status codes (failed requests)
The significance for each of these status codes is explained below.
The Ratio Between HTTP 200 and 304 Status Codes (Analyzing Successful Requests)
The ratio between the 200 and 304 HTTP status codes is important because it shows how many requests are being retrieved from the clients’ cache instead of directly from the server. The results in Figure 4 show that there are 3,920,658 requests which resulted in an HTTP Status code of 200. This means that the requested file was served from the server each time. In contrast, there were 178,705 requests which resulted in a 304 HTTP status code. This means that the requested file was retrieved from the local cache. In other words, 95.5% of the requests are being handled from the server.
Caching can have some very positive impact on your system’s performance; see the details for both static and dynamic compression in the Configuring HTTP Compression in IIS 7 article.
HTTP 500 Status Codes (Analyzing Failed Requests)
HTTP 500 Status codes may indicate serious issues on your system. The level of impact that the root cause of an HTTP 500 error may have on your system can range from nothing to the crash of a worker process. Therefore, when you see these, you should execute the query shown in Figure 5 in order to find which requests resulted in a 500 HTTP Status code.
[!code-sqlMain]
Figure 5: LogParser Query (cs-uri-stem with a 500 sc-status)
These results show the path and the name of the file which, when requested, responded with an HTTP 500 Status code. This kind of information would be valuable to the development team. For example, the development team could look further into that specific code and search for code that executes without being contained in a try {...} catch {...}
code block, or they are executing large data queries which need to be optimized.
Let’s take this example a step further and focus on the top contributor for HTTP 500 Status codes. It would be interesting to know when these errors occurred, because this information can be used to check if dependencies were having any problems at the same time.
[!code-sqlMain]
Figure 6: LogParser Query (cs-uri-stem with a 500 sc-status)
The subset of results in Figure 6 restricts the date range of the issue. This information can be passed along to network, database, operating system administrators and the development teams to check if anything else was happening at that same time. For example: Were there any additional problems between 08:00 and 09:59:59 GMT and between 14:00:00 and 14:59:59 GMT?
The next set of LogParser queries utilize the following fields, which may give better insight into performance problems:
Field | Description | Enabled by default |
---|---|---|
time-taken | The length of time the action took, in milliseconds | Yes |
sc-bytes | The number of bytes sent by the server | No |
cs-bytes | The number of bytes the server received | No |
As mentioned before, take the time now to request the sc-bytes and cs-bytes fields be enabled or, if possible, enable them yourself. They provide some valuable insight into your system and its’ behavior. Take Figure 7, for example. You see that the average time is pretty good at a few hundred milliseconds. However, look at the maximum time-taken, that is way too much time.
[!code-consoleMain]
Figure 7: LogParser Query (MAX and AVG time-taken)
I know you are asking yourself already the next question that needs to be answered. Which request is taking so much time? Figure 8 shows the answer to that question. As you will notice, I have gone ahead and included the sc-bytes field in the LogParser query. Remember, sc-bytes represents the size of the file sent from the server back to the client.
[!code-sqlMain]
Figure 8: LogParser Query (MAX and AVG time-taken)
We would likely all agree that the time-taken for the requests exceeds a ‘normal’ response time. However, the size of the files is something which the administrator or developer would need to analyze to determine if the sizes are within an acceptable range.
The conclusion is that the GetDetailsView.aspx file has been throwing a number of 500 HTTP Status codes and has at some point taken a long time to complete, even though it was a relatively small file. You may want to look at the date and time when problems where occurring for this file, and examine the code in the file with any issues that occurred. (For example, the IIS logs contain a list of variables that were passed in the query string; you could check those values for bad data.)
The examples provided in figures 4 — 8 help gain an understanding around where the root cause of an issue may exist. It is likely, however, that this analysis has only rendered a better view of the situation which will lead to more questions and deeper analysis. If that’s the case you may want to create a representation of this data in a more presentable manner. The following section covers this in detail.
Reporting
Screenshots of a command window containing LogParser queries and their results may be fine during the analysis phase of a performance problem; however, if you need to go in front of managers or directors to explain what happened, it may not meet the mark.
[!NOTE]
In order to get charting to work via LogParser, you will need to install the Office Web Components. The following articles explain how to do this:
- Advanced Log Parser Charts Part 3 — Missing Office Web Components for Charting
- Charting with LogParser
Figure 9 shows the LogParser query to create a 3D pie chart containing the number of requests and their associated HTTP Status code. I removed status 200, as those are successful. What I am after here are the requests which are something other than OK.
[!code-sqlMain]
Figure 9: LogParser Query (Create a 3D pie chart)
The result of the query is illustrated in Figure 10. There are a number of additional parameters which you can pass to LogParser that affect the image. For example, legend, groupSize, config, etc… To get a complete list enter: LogParser -h -o:CHART for a list of all parameters. This command will also provide a list of the different chart types.
Figure 10: LogParser 3D pie chart
Another useful chart is the ratio between cached and actual requests. Recall from the Data Analysis section where I discussed that an HTTP Status code of 200 means that the requested files are retrieved from the server however, a 304 is retrieved from the client. Figure 11 shows the LogParser query for the creation of this chart. Notice that I used the -values parameter.
[!code-sqlMain]
Figure 11: LogParser Query (Create a 3D pie chart)
Although the difference between HTTP Status code 200 and 304 are clearly visible, I thought it may add some value to include the number of hits for each. Figure 12 illustrates the output of the previous LogParser query.
Figure 12: LogParser 3D pie chart
I think you are getting the picture now about how charting the IIS Logs using LogParser can help convey what is happening much better than a table of data. But before I stop, I want to show you one more example using the Column chart type. The LogParser query shown in Figure 13 produces a 3D Column chart showing the count of 500 HTTPS Status codes per hour.
[!code-sqlMain]
Figure 13: LogParser Query (Create a 3D column chart)
The resulting chart is illustrated in Figure 14.
Figure 14: LogParser 3D column chart
Creating charts using Excel and CSV
At the beginning of this section I mentioned that the installation of the Office Web Component (OWC) is a requirement if you want to use the LogParser charting capabilities. In your organization, there may be restrictions that prohibit this or you simply might not want to install it. If either is the case, then consider exporting the LogParser query result to a CSV file and import it into Excel.
Figure 15 shows the LogParser query that extracts the HTTP Status codes for all request which are not 200 to a CSV file.
[!code-sqlMain]
Figure 15: LogParser Query (Create a CSV file for import into Excel)
Notice in Figure 15 that I used the -o parameter so that LogParser creates the output in CSV format.
To import the CSV file into Excel so that a chart can be created from it, open Excel, navigate to the DATA tab and select From Text. Figure 16 shows what this looks like.
Figure 16: Import CSV file created by LogParser into Excel
Select the status.csv file created by the LogParser query and navigate through the import wizard. Import the ‘comma’ delimited CSV file and you will end up with the Status in column A and the number of occurrences for each status in column B. This assumes you executed the LogParser query shown in Figure 15. Lastly, select all the data from column A and B, including the headers and choose the type of Pie chart to create. Figure 17, illustrates how this may look.
Figure 17: Create a Pie chart using a CSV file
The end result is a Pie chart, Figure 18 that is similar to that shown previously in Figure 10. There are many options in regards to color, chart type, labels, etc. With a click of a button you can change the chart type from Pie to Bar or to Line. There are a lot of options for creating professional looking charts within Excel.
Figure 18: A Pie chart using a CSV file similar to Figure 10
There are so many options and possibilities for analyzing and presenting the results of that analysis using LogParser. For some additional tips and examples, check out these articles written by Robert McMurray. There is also a very useful help file and many prewritten scripts provided within the installation package of LogParser. The next section will discuss this and other topics in more detail.
Help
When you install LogParser 2.2 onto your machine, it installs by default into the C:Program Files (x86)Log Parser 2.2
directory. Navigate to that location and review the SamplesQueries and SamplesScripts directories for an abundant supply of prewritten code that will get you moving fast.
You will also realize a great benefit by reading through the contents within the LogParser.chm file.
Reducing the size of or splitting IIS log files
You may encounter a situation where the IIS log file is too big for LogParser to query. This is most likely on a 32-bit machine, but can happen on a 64-bit machine too. Nonetheless, if you experience ‘out of memory’ errors when running a LogParser query, consider executing the command shown in Figure 19. The query extracts some essential fields from a large IIS log file and places them into another, which results in a smaller log file.
[!code-consoleMain]
Figure 19: Reducing the size of an IIS log file (by removing fields)
In this example, I realized a file size reduction of about 45%. In many cases this may be enough, in others maybe not. It depends on the size of the original log file. If you find that you still need to reduce the size of the IIS log file, consider adding a date time constraint to the LogParser query as shown in Figure 20.
[!code-sqlMain]
Figure 20: Further reducing the size of an IIS log file by adding a WHERE clause
This is a valuable technique for reducing the file size, but it is also useful to remove unwanted entries from the IIS Log. For example, when beginning to troubleshoot an issue you realize that time-take, sc-bytes and cs-bytes were not being logged. You enabled them in IIS and want the query to only analyze those entries with the recently enabled fields. Use the where statement to extract the data from the IIS log file from the time in which those fields have been enabled. This is important when you use the AVG, MIN and MAX aggregates.
Conclusion
LogParser is a small but powerful tool to analyze a number of different system log types. This article focused on queries applicable to IIS Logs. When performance problems or errors are experienced in your IIS environment, it is sometimes difficult to know where to start.
LogParser can be used as a starting point, because a system administrator who has some SQL skills can quickly build some very sophisticated LogParser queries. These queries can be used to further the root cause analysis of the problem.
Useful Links
Here are the links which are referred to in this article, plus a few links with additional information.
- Microsoft LogParser: http://www.bing.com/search?q=logparser or https://www.microsoft.com/download/details.aspx?id=24659
- The HTTP status codes in IIS 7.0, IIS 7.5, and IIS 8.0
- Modifying IIS 7 log data in Windows 2008
- Modifying IIS 6 log data in Windows 2003
- Configuring HTTP Compression in IIS 7
- Charting with LogParser using OWC
- Robert McMurray’s Blogs on LogParser
- Microsoft Log Parser Toolkit: A Complete Toolkit for Microsoft’s Undocumented Log Analysis Tool