Logging ASP.NET Application Shutdown Events
page 1 of 2
Published: 14 Dec 2005
Unedited - Community Contributed
Abstract
In this article, Scott demonstrates how to log ASP.NET application shutdown events.
by Scott Guthrie
Feedback
Average Rating: This article has not yet been rated.
Views (Total / Last 10 Days): 20894/ 54
Article Contents:

Introduction

Republished With Permission - Original Article

Someone on a listserv recently asked whether there was a way to figure out why and when ASP.NET restarts application domains.  Specifically, he was looking for the exact cause of what was triggering them on his application in a production shared hosted environment (was it a web.config file change, a global.asax change, an app_code directory change, a directory delete change, max-num-compilations reached quota, \bin directory change, etc). 

Thomas on my team has a cool code-snippet that he wrote that uses some nifty private reflection tricks to capture and log this information.  It is pretty easy to re-use and add into any application, and can be used to log the information anywhere you want (the below code use the NT Event Log to save it – but you could just as easily send it to a database or via an email to an admin).  The code works with both ASP.NET V1.1 and ASP.NET V2.0.

Simply add the System.Reflection and System.Diagnostics namespaces to your Global.asax class/file, and then add the Application_End event with this code (note: you can also download a .zip file containing the code from here):

Listing 1

public void Application_End()
{
 
  HttpRuntime runtime =(HttpRuntime)typeof(System.Web.HttpRuntime)
    .InvokeMember("_theRuntime",
 
  BindingFlags.NonPublic
 
   | BindingFlags.Static
 
   | BindingFlags.GetField,
 
  null,
 
  null,
 
  null);
 
  if (runtime == null)
 
    return ;
 
  string shutDownMessage =(string)runtime.GetType().InvokeMember(
    "_shutDownMessage",
 
  BindingFlags.NonPublic
 
   | BindingFlags.Instance
 
   | BindingFlags.GetField,
 
  null,
 
  runtime,
 
  null);
 
  string shutDownStack =(string)runtime.GetType().InvokeMember(
    "_shutDownStack",
 
  BindingFlags.NonPublic
 
   | BindingFlags.Instance
 
   | BindingFlags.GetField,
 
  null,
 
  runtime,
 
  null);
 
  if (!EventLog.SourceExists(".NETRuntime"))
  {
 
    EventLog.CreateEventSource(".NETRuntime""Application");
 
  }
 
  EventLog log = new EventLog();
 
  log.Source = ".NET Runtime";
 
  log.WriteEntry(String.Format(
    "\r\n\r\n_shutDownMessage={0}\r\n\r\n_shutDownStack={1}",
 
  shutDownMessage,
 
  shutDownStack),
 
  EventLogEntryType.Error);
 
}

I tried this out using a simple web-site using ASP.NET 2.0 and the built-in VS Web-Server (aka Cassini).  When I changed the web.config file in my running application, the following was logged to my "Application" event viewer:

Listing 2

_shutDownMessage=CONFIG change

HostingEnvironment caused shutdown

CONFIG change

CONFIG change

_shutDownStack= at System.Environment.GetStackTrace(Exception e, Boolean needFileInfo)

at System.Environment.get_StackTrace()

at System.Web.HttpRuntime.ShutdownAppDomain()

at System.Web.Hosting.HostingEnvironment.ShutdownThisAppDomainOnce()

at System.Web.Hosting.HostingEnvironment.InitiateShutdownWorkItemCallback(Object state)

at System.Threading._ThreadPoolWaitCallback.WaitCallback_Context(Object state)

at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)

at System.Threading._ThreadPoolWaitCallback.PerformWaitCallback(Object state).

When I updated my Global.asax file with some code change, the following was logged:

Listing 3

_shutDownMessage=Change in GLOBAL.ASAX

Change in GLOBAL.ASAX

Change in GLOBAL.ASAX

HostingEnvironment caused shutdown

_shutDownStack= at System.Environment.GetStackTrace(Exception e, Boolean needFileInfo)

at System.Environment.get_StackTrace()

 

at System.Web.HttpRuntime.ShutdownAppDomain()

at System.Web.HttpApplicationFactory.OnAppFileChange(Object sender, FileChangeEvent e)

at System.Web.DirectoryMonitor.FireNotifications()

at System.Web.Util.WorkItem.CallCallbackWithAssert(WorkItemCallback callback)

at System.Web.Util.WorkItem.OnQueueUserWorkItemCompletion(Object state)

at System.Threading._ThreadPoolWaitCallback.WaitCallback_Context(Object state)

at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)

at System.Threading._ThreadPoolWaitCallback.PerformWaitCallback(Object state).

And when I changed the contents of my \bin directory I got:

Listing 4

_shutDownMessage=Change Notification for critical directories.

bin dir change or directory rename

HostingEnvironment caused shutdown

Directory rename change notification for 'E:\Unload'.

Unload dir change or directory rename

_shutDownStack= at System.Environment.GetStackTrace(Exception e, Boolean needFileInfo)

at System.Environment.get_StackTrace()

at System.Web.HttpRuntime.ShutdownAppDomain()

at System.Web.Hosting.HostingEnvironment.ShutdownThisAppDomainOnce()

at System.Web.Hosting.HostingEnvironment.InitiateShutdownWorkItemCallback(Object state)

at System.Threading._ThreadPoolWaitCallback.WaitCallback_Context(Object state)

at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)

at System.Threading.

Hopefully this is a useful trick that you can re-use in your own applications to get better visibility into what is going on with them.  If you are using ASP.NET 2.0, then you should definitely also investigate the new ASP.NET 2.0 Health Monitoring feature-set.  This provides a rich eventing architecture for instrumenting your code, as well as raising notifications of issues to admins when they occur within your application.  K. Scott Allen has written a good overview article of how this new feature-set works, and links to the MSDN documentation.


View Entire Article

User Comments

Title: Good job   
Name: Game 9
Date: 6/22/2011 2:36:01 AM
Comment:
Good Job! man
Title: Medium trust forbids this code   
Name: Andrei Rinea
Date: 1/12/2009 5:01:00 AM
Comment:
I cannot run this in medium trust because of the use of reflection. Any other alternative? :(
Title: HostingEnvironment caused shutdown   
Name: ulu
Date: 1/25/2007 4:12:30 AM
Comment:
Hi, and thanks for the great article.

My log gives me _shutDownMessage = HostingEnvironment caused shutdown and the following stack:
at System.Environment.GetStackTrace(Exception e, Boolean needFileInfo)
System.Environment.get_StackTrace()
System.Web.HttpRuntime.ShutdownAppDomain()
System.Web.Hosting.HostingEnvironment.ShutdownThisAppDomainOnce()
System.Web.Hosting.HostingEnvironment.InitiateShutdownWorkItemCallback(Object state)
System.Threading._ThreadPoolWaitCallback.WaitCallback_Context(Object state)
System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
System.Threading._ThreadPoolWaitCallback.PerformWaitCallback(Object state)

Any clue how to interpret this?

Big thanks

Product Spotlight
Product Spotlight 





Community Advice: ASP | SQL | XML | Regular Expressions | Windows


©Copyright 1998-2014 ASPAlliance.com  |  Page Processed at 7/29/2014 10:46:46 AM  AspAlliance Recent Articles RSS Feed
About ASPAlliance | Newsgroups | Advertise | Authors | Email Lists | Feedback | Link To Us | Privacy | Search