Tracing or Instrumentation is invaluable, most effective, and efficient when dealing with performance problems in ASP.NET Applications. The problem is that it requires coding that too often cut or even never planned to be made.
Quick Resource Box
- Sysinternals ProcMon New & Improved – Captures Both System & Application Events
- DebugView – Free Simple Tool To Quickly Identify Performance Problems
- Process Monitor
- DebugView
The other downside is some instrumentation implementations are based on heavyweight logging that introduces even more performance problems.
In this post I am sharing my simple techniques I was using for tracing ASP.NET applications without heavy weight coding and without affecting performance significantly. It produced results relatively quick – we were able to put our fingers on the root cause for slowly performing functions relatively quick.
Instrument with System.Diagnostics.Trace
I am using simple class to report function Entry and Exit using System.Diagnostics.Trace class similar to this [I am sure you can prettify it even more]:
namespace Instrumentation
{
public class Tracing
{
public static void TraceFunctionEnter()
{
StackTrace st = new StackTrace();
System.Diagnostics.Trace.WriteLine(true, ”TRC: ENTERING: “ + st.GetFrame(1).GetMethod() + ”USER:” + System.Web.HttpContext.Current.User.Identity.Name);
}
public static void TraceFunctionExit()
{
CheckAndFixDefaultListener();
StackTrace st = new StackTrace();
Trace.WriteLineIf(true, ”TRC: EXITING: “ + st.GetFrame(1).GetMethod() + ”USER:” + System.Web.HttpContext.Current.User.Identity.Name);
}
public static void CheckAndFixDefaultListener()
{
DefaultTraceListener dtl = null;
TraceListenerCollection listeners = System.Diagnostics.Trace.Listeners;if (listeners.Count == 0)
{
dtl = new DefaultTraceListener();
Trace.Listeners.Add(dtl);
return;
}
foreach (TraceListener listener in listeners)
{
string listenerType = listener.ToString();
if ((string.Compare(listenerType, ”System.Diagnostics.DefaultTraceListener”,true) == 0))
{
return;
}
}
dtl = new DefaultTraceListener();
Trace.Listeners.Add(dtl);
}
}
}
Next is simply calling on static methods when entering and exiting the functions:
protected void Button1_Click(object sender, EventArgs e)
{
Instrumentation.Tracing.TraceFunctionEnter();
//DO STUFF
System.Threading.Thread.Sleep(3000);
Instrumentation.Tracing.TraceFunctionExit();
}
Collecting Instrumentation Information
Until recently I was using freely available Sysinternals DebugView. Here is how instrumented code would look in DebugView:
![]()
Even though I have not reported timestamps, DebugView have it’s own stop watch and shows the timestamps precisely.
Recently I discovered new and improved [freely available] Procmon that is able to capture System.Diagnostics.Trace events alongside with system events, so I next time I am on assignment I’d probably use Procmon
.
Conclusion and Recommendations
The techniques I have outlined in this post does not require heavy weight coding and do not affect performance itself significantly. These techniques also use readily available tools for collecting and parsing the results.
« Best ASP.NET Performance Winner For Data Binding – Hands Up To Response.Write() Use FREE Tools From IIS Resource Kit To Warm Up Your ASP.NET 1.1 Application By Batch Compilation »
