Archive for the ‘IIS’ Category

What’s that IIS Process ID again?

Sunday, August 18th, 2013

First off, I’ll admit that it has been some time since my last post. I’ve moved into a new role at work that has much less emphasis on day-to-day development. However, I’ll still plan on posting interesting tidbits from time to time as I encounter them – just as I always have!

This one came up during a recent sprint of coding in which I was debugging a SharePoint 2013 farm solution (I know – apps are the way to go now!) with Visual Studio 2012. Let me say, since first starting development in MOSS 2007, this is a totally different and much smoother experience. I switched back-and-forth between using Visual Studio’s “Play” button – also known as “Start Debugging” – and a more traditional Build, Deploy, Attach to Process method.

When looking to attach to IIS, it’s always a gamble as to which w3wp.exe process to attach. However, this can be avoid by using the appcmd.exe utility. There is a nifty set of parameters that will allow you to view the currently running w3wp processes, their process IDs, and the names of the associated application pools. It’s just the right amount of information.

Enjoy and happy debugging!

IIS Termination during Visual Studio Debugging

Thursday, January 26th, 2012

What a familiar situation: You are debugging a SharePoint solution (or any ASP.NET code) and have Visual Studio attached to IIS. As you are stepping through your code, checking variables and getting a lot done, all of the sudden you are presented with the following message:

The web server process that was being debugged has been terminated by Internet Information Services (IIS). This can be avoided by configuring Application Pool ping settings in IIS. See help for further details.

It typically occurs within two minutes of Visual Studio pausing on a breakpoint. It is possible to extend this timeframe and the error message gives the answer. The reason Visual Studio presents this message is because IIS is forcefully terminating the worker process being debugged. Why? Because IIS (by default) performs health monitoring pings against each of its worker processes to ensure they are still responding. If IIS does not receive a response from the worker process to one of these pings within a given timeframe, IIS forcefully terminates the worker process. When debugging in Visual Studio, the worker process is stopped while Visual Studio is paused on a breakpoint. Therefore, the worker process has no way to respond to a health monitoring ping. Therefore, the worker process gets terminated.

How does one stop this vicious cycle and allow debugging to continue unimpeded? As the error message states, modify the IIS settings for health monitoring pings! To do this on a particular application pool:

  1. Open IIS Manager.
  2. On the left in the Connections pane, click Application Pools. The list of all of the application pools in IIS will display in the middle section of the window.

  3. Select the particular application pool used for debugging and click Advanced Settings under Edit Application Settings on the right in the Actions pane.

  4. Modify the two Ping settings: Ping Maximum Response Time (seconds) and Ping Period (seconds). The Ping Period is the interval used by IIS to ping the worker process. The Ping Maximum Response Time is the amount of time IIS will wait for a ping response. If IIS doesn’t get a response after the maximum response time has elapsed, that is when the termination occurs. By default, the ping period is 30 seconds and the maximum response time in 90 seconds. These are great in normal situations, but only give you about two minutes for debugging! Therefore, I would suggest throwing a few extra zeros in there – I personally set my ping period to 3000 seconds (50 minutes) and my maximum response time to 9000 seconds (150 minutes or 2.5 hours). Those values give me plenty of time to debug without needing to worry about termination. Once you have modified these values, click OK.

  5. While I would recommend developers to modify the health monitoring ping settings on their local development servers, these modifications should never be made in a testing or production environment.

    Happy debugging!

Managing Customizations to ASP.NET & SharePoint Browser Definitions

Wednesday, November 2nd, 2011

This article’s purpose is to discuss the best practices around managing customizations to ASP.NET’s Browser Definitions. For more details around ASP.NET’s browser definition platform, please see the Browser Definition File Schema (browsers element) article on MSDN. A quick overview of ASP.NET Browser Definitions can be found in the side panel.

ASP.NET Browser Definition Overivew
In any IIS site, including SharePoint sites, Microsoft provides a highly configurable platform for defining the various capabilities and mobile adapters of a browser. To facilitate this, Microsoft uses what is called a Browser Definition File which is an XML-based file that defines browsers, what makes that browsers different from the rest (the Identification), and browser properties – capabilities and mobile adapters. Microsoft provides several definition files out-of-the-box with ASP.NET that define various browsers. Then, individual web applications can provide their own Browser Definition Files that will supplement or override the out-of-the-box files. ASP.NET uses this information to tailor page rendering based on the browser making the page request.

ASP.NET allows for multiple files that all have the same schema. There are two sets of files that ASP.NET parses:

  1. Predefined Browser Definition Files – This set of files is specific to the version of the .NET Framework being used in the web application and contains the out-of-the-box ASP.NET browser definition files.
    %SystemRoot%\Microsoft.NET\Framework\
      version\CONFIG\Browsers
  2. Application-Level Browser Definition Files – This set of files is specific to each web application and contains the web application specific browser definition files.
    App_Browsers directory within the web application’s web root folder (e.g. inetpub or inetpub\wss\VirtualDirectories\80)

Each individual browser is defined using a <browser> tag. Within this tag, there are several other allowed tags that define how a browser is uniquely identified and what unique attributes should be defined for that browser. Browser definitions follow an inheritance hierarchy. New definitions must define a parent definition or existing definitions can be modified using the definition’s ID.

ASP.NET loads each browser definition file by concatenating them – each browser file contains a series of browser tags. The predefined files are processed first based on the ASP.NET version being used followed by the application-level files. Within each file location, ASP.NET seemingly processes each file in alphabetical order by file name. This means that if there are multiple definitions for the same browser, it seems that the definition in the last file will take precedence.

SharePoint chose to implement two browser definition files that are deployed locally to each SharePoint web application’s App_Browsers directory. This is important as SharePoint deploys its custom browser definitions in the same way that other applications using SharePoint or ASP.NET should deploy them – as separate .browser files deployed to the application-level App_Browsers directory. These two files, which may look familiar, are:

  • compat.browser, and
  • compat.moss.browser (If using SharePoint Server editions)

As the Browser Definition File Schema article in MSDN stresses, the predefined files that ship with the .NET Framework should never be modified – ever! This is because they could be overwritten by updates, patches, or service packs; causing any customizations to be lost.

As an extension to this rule, never modify the application-level browser definition files that ship with SharePoint. Why? The same reason as with the predefined files. Future SharePoint updates, patches, or service packs could overwrite these files; causing any customizations to be lost.

So what is left if customizations are required? Thanks to the architecture of these browser definition files, Microsoft allows an application to define its own browser definition files. This is relatively straightforward, but it does require knowledge of the browser definition files you will be overriding. I will cover three scenarios:

  1. Adding an entirely new browser definition
  2. Appending information to an existing browser definition
  3. Modifying an existing browser definition

As far as I know, there is no way to remove a browser definition. However, I’m not sure there would be a need or desire to do so.

Adding an entirely new browser definition
To add a new browser definition, add the definition’s browser element to a new browser definition file. Deploy this file locally into each web application’s App_Browsers folder. This new file’s definition(s) will be combined with the other predefined and application-level definitions.

Appending information to an existing browser definition
To append capabilities, mobile adapters, or other information to an existing browser definition, add a new browser tag to a new browser definition file that uses refID to reference the existing browser’s ID. Add the new information within this browser tag. This definition will be combined with the existing browser’s definition, which could be in another file, and append the new information.

Modifying an existing browser definition
To modify a capability, mobile adapter, or other information already defined as part of an existing browser definition, there are a few options. The first would be to use a similar process to appending information. It is possible to define browser definitions in a new file, using refID to reference the existing browser’s ID, and define the same information with different values. The second would be to implement a new browser, with no additional identification, with the parent browser set to the browser that should be modified.

For example, if the IE browser should be modified to be treated as a mobile device, then the following browser definitions could be used:

  • Option 1:
    <browser refID="ie">
        <capabilities>
            <capability name="isMobileDevice" value="true" />
        </capabilities>
    </browser>
  • Option 2:
    <browser id="ieMobile" parentID="ie">
        <capabilities>
            <capability name="isMobileDevice" value="true" />
        </capabilities>
    </browser>

However, note that if multiple browser definitions exist that reference the same browser ID and each has a different definition of the same information, then the last definition in the last file alphabetically in the application-level will be used.

For example, assume Option 1 was implemented in both MyApp1.browser & MyApp2.browser and that each of those browser files was deployed to the application-level App_Browsers folder. MyApp1 defines IsMobileDevice=True and MyApp2 defines IsMobileDevice=False. Since MyApp2 comes last alphabetically, it will take precedence and IsMobileDevice will be False. This underscores the need for applications to consider the environment’s existing customizations when developing custom browser definitions. In this example, the MyApp2 team, presumably deploying after MyApp1, should have seen MyApp1’s existing customization and implemented a new child browser (Option 2) to avoid a conflict or change MyApp1’s customization. The MyApp2 team would need to be aware that either way that is chosen for implementation will affect the entire web application, so they should consult the MyApp1 team!

Summary
To properly manage customizations to the browser definitions that ship with ASP.NET and SharePoint, applications being deployed to a SharePoint environment should make use of their own browser definition files that are deployed to the application-level App_Browsers folder. However, if the environment is planning on host multiple sets of customizations or applications that will require changes to the browser definitions, I would encourage a single file for each web application to ensure that applications changes are developed properly and do not conflict with each other.

Never modify any browser definition file not directly managed by the application being deployed. To implement the changes to existing browsers within the application browser definition files, it is best to use the refID attribute of the browser tag.

When deploying, changes to the App_Browsers folder should automatically be picked up by IIS and not require any sort of application pool recycle or IISReset.

Expanding Warm Up Script Triggers

Wednesday, September 7th, 2011

This post is a follow up to a post I wrote a few months ago around triggering a warm up script for SharePoint to execute only when a specific application pool is recycled. You may want to read that post before this one: “Application Pool”-Specific Warm Up Scripts


After using what I recommended in the previous post, I realized there were still issues with this approach. To step back and explain the larger picture, I had a scenario where I needed to execute a warm up script whenever the application pool was freshly started. The script is responsible for filling application-level cache. Therefore, I want to execute the script any time the application pool will be freshly started. This means not just when it is recycled, but also in instances like server reboots. I have previously described how to do this using the Windows Task Scheduler to trigger the script to execute based on certain events being logged.

Side Note: I did brainstorm ideas to trigger execution when the application pool started, instead of triggering when the application pool recycled, etc. Regrettably, I was unable to find any Windows events that are logged when the application pool starts. Therefore, that paradigm could not be leveraged. However, one could feasibly create a custom extension to the OOTB SharePoint HttpApplication class (SPHttpApplication) and add logic to one of the class’ methods or events to trigger the warm up script.

This method would be a bit expensive in terms of the need for extra custom development, impacts to the entire web application due to the need to customize the IIS web application’s HttpApplication class, extra deployment steps, interoperability issues with other global.asax customizations, etc. Evaluate this carefully before proceeding with the suggestion above.

As it would be too difficult to trigger when the application pool is started (see the Side Note), I needed to continue triggering the event based on what would occur immediately prior to the application pool being started. I found three things that need to be used:

  1. Server Start/Reboot
  2. IIS Reset
  3. Application Pool Recycle

Server Start/Reboot
Whenever the server is started, one may wish to trigger the warm up script. If the server will take requests or the script will perform a function desired soon after the server is started, then this trigger can be used. Fortunately, the Windows Task Scheduler allows one to add a trigger that will begin the task At startup. Therefore, one can easily add this trigger!

IIS Reset
Whenever IIS is reset, then all of the application pools will be shut down. If requests will come shortly after resetting IIS, it would make sense to use this as a trigger for the warm up script. After analyzing all of the events that the IISreset utility could log, the only one that applies to the situation of needing to track the application pool’s pending start would be when IIS is freshly started: ID 3201. All of the other events described above pertain to states where the warm up script would not need to be executed.

To add event 3201 as a trigger to the task scheduler, you can use the following settings:

  • Begin the task: On an event
  • Log: System
  • Source: IIS-IISReset
  • Event ID: 3201

Note that, per the TechNet links below, Microsoft no longer supports using the IISreset utility in IIS 7.0 & 7.5.

IISreset Event Reference for Windows Server 2008 / IIS 7.0
http://technet.microsoft.com/en-us/library/cc735265(WS.10).aspx

IISreset Event Reference for Windows Server 2008 R2 / IIS 7.5
http://technet.microsoft.com/en-us/library/dd364067(WS.10).aspx

Application Pool Recycle
This is the key event that need to be tracked. The application pool’s recycle settings in IIS are quite extensive! Each reason for recycling produces a different event. This is the major area I realized that I was lacking from the previous post.

IIS logs an event when the application pool recycles

  • (5074) automatically on a regular time interval,
  • (5075) automatically when a defined number of requests have been fulfilled,
  • (5076) automatically at specific times,
  • (5077) automatically when a defined amount of virtual memory is used or exceeded by the worker process,
  • (5078) automatically when an ISAPI extension reports an unhealthy condition,
  • (5079) manually by an administrator,
  • (5080) automatically upon making configuration changes,
  • (5081) automatically due to detected problems with the IIS configuration store,
  • (5117) automatically when a defined amount of private memory is used or exceeded by the worker process, or,
  • (5186) automatically when inactive.

Parameters for automatic recycles can be configured in the IIS Manager. After considering each event, if the warm up script needs to perform any function that should always be in place while the application pool is running, then each of these events should have a trigger set against it.

The good news is that we can use the notion from the previous post to configure the trigger. (“Application Pool”-Specific Warm Up Scripts) One simply needs to include all of the extra IDs in the event filter.

Example Event Filter for an example application pool SharePoint – 32767
Don’t forget to replace SharePoint – 32767 with your application pool’s name!
<QueryList>
  <Query Id="0" Path="System">
    <Select Path="System">
      *[System[Provider[@Name='Microsoft-Windows-WAS']
      and (EventID=5074 or EventID=5075 or EventID=5076 or EventID=5077 or EventID=5078
           or EventID=5079 or EventID=5080 or EventID=5081 or EventID=5117 or EventID=5186)]
      and EventData[Data[@Name="AppPoolID"]="SharePoint - 32767"]]
    </Select>
  </Query>
</QueryList>

Important Note: There are also settings in IIS to control if IIS generates recycle event log entries for each of the events listed above! For any warm up script triggers to function properly, ensure that all of the scnearios are set to generate events!

Application Pool Recycling Event Reference for Windows Server 2008 / IIS 7.0
http://technet.microsoft.com/en-us/library/cc735206(WS.10).aspx

Application Pool Recycling Event Reference for Windows Server 2008 R2 / IIS 7.5
http://technet.microsoft.com/en-us/library/dd349270(WS.10).aspx

Summary
In closing, don’t forget to include any necessary triggers to your own particular warm up script’s scheduled task in Windows so that it executes whenever desired! My suggestions are to include the server start/reboot, the IIS Reset event (3201), and the application pool recycle events (5074-5081, 5117, & 5186).

Thanks to Greg Rosati for providing the links to the event information on TechNet that led to the creation of this follow up post!

“Application Pool”-Specific Warm Up Scripts

Wednesday, June 29th, 2011

Thanks to Thomas Vuylsteke and his ADdict blog for providing the foundation of this post!
FIM 2010: Warm Up Your Portal (IIS)
Be sure to read this post first to get the foundation of how one can configure a scheduled task to execute a warm up script whenever IIS recycles an application pool or whenever IIS is reset.


I had a scenario recently where one of my clients needed a rather long running warm up script to execute upon the recycling of a particular application pool. Being a larger farm, there were several application pools and the client only desired the warm up script to run when one specific application pool was recycled. The Windows Task Scheduler allows tasks to be triggered for execution when specific events are logged. When an application pool is recycled (automatically or manually) or when IIS is reset, events are logged in the System event log. Those events can be used to trigger tasks to run a warm up script in the Windows Task Scheduler!

IIS Action Source Event ID
Application Pool Recycle (automatic) WAS 5076
Application Pool Recycle (manual) WAS 5079
IIS Reset IIS-IISReset 3201

One can implement triggers for a warm up script task on each one of these event IDs. However, the 5076 & 5079 events are logged for all application pools. Therefore, if either event is used for a trigger, it means that the task will execute once for every application pool recycle on that instance of IIS. This may or may not be desired; for my client, it was not desired.

I needed to inspect the 5076 & 5079 events to see if there was enough data to further filter the trigger so it would only match 5076 & 5079 events for a specific web application. In my example, I’m attempting to filter on a web application named “SharePoint – 32767” (the name of your application pool can be looked up in IIS Manager).

The following is an excerpt of the relevant sections of the 5079 event’s XML representation (the 5076 event logs similar data):
<Event xmlns="http://schemas.microsoft.com/win/2004/08/events/event">
  <System>
    <Provider Name="Microsoft-Windows-WAS"
              Guid="{524B5D04-133C-4A62-8362-64E8EDB9CE40}"
              EventSourceName="WAS" />
    <EventID Qualifiers="16384">5079</EventID>
    ...
  </System>
  <EventData>
    <Data Name="AppPoolID">SharePoint - 32767</Data>
    <Binary></Binary>
  </EventData>
</Event>

Fortunately, the application pool’s name is logged! One can use that data to filter the trigger even more. To do this within the trigger, select Custom on the event trigger window. Then click on New Event Filter…

Trigger on Custom Event Filter

Once in New Event Filter window, select the XML tab and check the box at the bottom to Edit query manually. Copy and paste the following – which will cover both the 5076 and 5079 events. Don’t forget to replace the SharePoint – 32767 name in the example below with your application pool’s name!
<QueryList>
  <Query Id="0" Path="System">
    <Select Path="System">
      *[System[Provider[@Name='Microsoft-Windows-WAS'] and (EventID=5076 or EventID=5079)]
      and EventData[Data[@Name="AppPoolID"]="SharePoint - 32767"]]
    </Select>
  </Query>
</QueryList>

This will cause the warm up script task to trigger on the 5076 & 5079 events, but only for a specific application pool!

Thanks again to Thomas Vuylsteke and his ADdict blog for providing the foundation of this post!