Tracing in ASP
-
Upload
jersson-dongo -
Category
Documents
-
view
218 -
download
0
Transcript of Tracing in ASP
-
8/6/2019 Tracing in ASP
1/13
Tracing in ASP.NETFuente: http:/ / weblogs.asp.net/ plip/ articles/ 111130.aspx
This small article will focus on ASP.NETs built in Tracing functionality, this offersthe developer a place to put all the debug information from their program without itmucking up your expertly designed UI (well I can dream!).
We will discuss the benefits of using Trace, as well as the costs it imposes on youas the developer especially in a team based environment. There is also a specialsection of this article devoted to the classic ASP developers that know and love
Response.Write, hopefully I can persuade you not to use it any more
The .NET Documentation describes Tracing as so: -
ASP.NET introduces new functionality that allows you to write debug statements,directly in your code, without having to remove them from your application when itis deployed to production servers. Called tracing, this feature allows you to writevariables or structures in a page, assert whether a condition is met, or simply tracethrough the execution path of your page or application.
In order for these messages and other tracing information to be gathered and
displayed, you must enable tracing for the page or application. When you enabletracing, two things occur:
ASP.NET appends a series of diagnostic information tables immediately
following the page's output. The information is also sent to a trace viewerapplication (only if you have enabled tracing for the application).
ASP.NET displays your custom diagnostic messages in the Trace
I n f o rma t i o n table of the appended performance data.
Diagnostic information and tracing messages that you specify are appended to theoutput of the page that is sent to the requesting browser. Optionally, you can viewthis information from a separate trace viewer (trace.axd) that displays traceinformation for every page in a given application. This information can help you to
clarify errors or undesired results as ASP.NET processes a page request.
Trace statements are processed and displayed only when tracing is enabled. Youcan control whether tracing is displayed to a page, to the trace viewer, or both.
-
8/6/2019 Tracing in ASP
2/13
Turning it on
What I shall show you first is simply how to turn tracing on for one of your existingASP.NET pages.
First find the Page directive on your ASP.NET page (usually the first line in thepage): -
Now we need to turn on Tracing for your page, we do this by adding the Traceproperty to the directive and setting it to true, like this: -
Save your page, and open it in a browser. You should see the trace information at
the bottom of the page looking something like this: -
If you are not seeing the Trace information then take a quick look through this
checklist to make sure something isnt overriding your settings.
Note you can also enable tracing in your application, at an application level.
-
8/6/2019 Tracing in ASP
3/13
Whats in it?
Request Details
Trace Information
Control Tree
Session Collection
Cookies Collection
Forms Collection
Headers Collection
Server Variables
-
8/6/2019 Tracing in ASP
4/13
How does it w ork with my page HTML?
As soon as ASP.NET detects the tag is in the response buffer it adds theTrace information to the end of the page, this is all encapsulated in a with an
id of __asptrace.
Talk about absolute positioning
-
8/6/2019 Tracing in ASP
5/13
Lets use it to help us Debug a page
Visual Studio .NET and ASP.NET offer the developer some really cool debuggingtools, but if you dont have access to them, then you are stuck with the good old
ways of doing things, writing out your variables until you find the problem.
Lets just quickly throw together some business logic that has a variable changing
its value through out the page, in real life this could be anything from the contentof a shopping basket right up to some high level mathematics. For now its just me
playing around with a number.
privatevoid Page_Load(object sender, System.EventArgs e)
{//Some fake business logic
//Take a variable, any variable
int i = 0;
//Perform some addition
i += 10;
//Perform some more additioni += 30;
//Do something slightly more complex than additioni = (i * (i + -2));
//Pass it to a methodi = DoSomething(i);
}
publicint DoSomething(int aNumber){
//Blow up, just to prove a pointif(aNumber > 0)
{thrownew Exception("aNumber is more than 0!");
}else
{//Set it to 0return 0;
}
}
In the Page_Load event we can see how were changing the value of i quite a bit. Ifsomething is going wrong like this: -Trace Information
Category MessageFrom
First(s)From
Last(s)
aspx.page Begin Init
aspx.page End Init 0.001180 0.001180
UnhandledExecutionError
aNumber is more than 0!at intranet._default.DoSomething(Int32 aNumber) in
c:\inetpub\wwwroot\intranet\default.aspx.cs:line 56
0.002194 0.001014
-
8/6/2019 Tracing in ASP
6/13
at intranet._default.Page_Load(Object sender, EventArgs e)in c:\inetpub\wwwroot\intranet\default.aspx.cs:line 44
at System.Web.UI.Control.OnLoad(EventArgs e)at System.Web.UI.Control.LoadRecursive()at System.Web.UI.Page.ProcessRequestMain()
This gives us no information as to where our sums are going wrong, so we can usethe Trace commands to output the variables value throughout its life time.
So here is the same method above with some Trace calls: -
privatevoid Page_Load(object sender, System.EventArgs e){
//Some fake business logic
//Take a variable, any variableint i = 0;
Trace.Write("i","Variable after it's been created is " + i.ToString());
//Perform some additioni += 10;
Trace.Write("i","Variable after it's been added to is " + i.ToString());
//Perform some more addition
i += 30;
Trace.Write("i","Variable after it's been added to again is " + i.ToString());
//Do something slightly more complex than additioni = (i * (i + -2));
Trace.Write("i","Variable after it's been messed around with is " +i.ToString());
//Pass it to a methodi = DoSomething(i);
Trace.Write("i","Variable after it's been processed is " + i.ToString());
}
publicint DoSomething(int aNumber){
//Blow up, just to prove a pointif(aNumber > 0){
thrownew Exception("aNumber is more than 0!");}else{
//Set it to 0return 0;
}
}
-
8/6/2019 Tracing in ASP
7/13
When we run our page with the Trace information included we get it all placed in tothe Trace log: -Trace Information
Category MessageFrom
First(s)From
Last(s)
aspx.page Begin Init
aspx.page End Init 0.001043 0.001043
i Variable after it's been created is 0 0.002366 0.001323
i Variable after it's been added to is 10 0.002413 0.000047
i Variable after it's been added to again is 40 0.002442 0.000030
i Variable after it's been messed around with is 1520 0.002472 0.000030
UnhandledExecutionError
aNumber is more than 0!at intranet._default.DoSomething(Int32 aNumber) in
c:\inetpub\wwwroot\intranet\default.aspx.cs:line 56at intranet._default.Page_Load(Object sender, EventArgs e)
in c:\inetpub\wwwroot\intranet\default.aspx.cs:line 44at System.Web.UI.Control.OnLoad(EventArgs e)at System.Web.UI.Control.LoadRecursive()at System.Web.UI.Page.ProcessRequestMain()
0.003193 0.000720
Now we can see by looking at the trace log, whats happening to the number, andwe can modify our business logic accordingly.
privatevoid Page_Load(object sender, System.EventArgs e){
//Some fake business logic
//Take a variable, any variable
int i = 0;
Trace.Write("i","Variable after it's been created is " + i.ToString());
//Perform some additioni += 10;
Trace.Write("i","Variable after it's been added to is " + i.ToString());
//Perform some more additioni += 30;
Trace.Write("i","Variable after it's been added to again is " + i.ToString());
//Do something slightly more complex than additioni = (i * -(i + -2));
Trace.Write("i","Variable after it's been messed around with is " +i.ToString());
//Pass it to a method
i = DoSomething(i);
Trace.Write("i","Variable after it's been processed is " + i.ToString());}
Now when we look at the page the exception does not occur and we can see whywhen we look at the Trace information: -Trace Information
Category Message From First(s) From Last(s)aspx.page Begin Initaspx.page End Init 0.003425 0.003425
-
8/6/2019 Tracing in ASP
8/13
i Variable after it's been created is 0 0.006264 0.002838i Variable after it's been added to is 10 0.006327 0.000063i Variable after it's been added to again is 40 0.006370 0.000044i Variable after it's been messed around with is -1520 0.006414 0.000044i Variable after it's been processed is 0 0.007609 0.001195aspx.page Begin PreRender 0.007684 0.000074aspx.page End PreRender 0.009410 0.001727aspx.page Begin SaveViewState 0.034088 0.024677
aspx.page End SaveViewState 0.085753 0.051665aspx.page Begin Render 0.085834 0.000081aspx.page End Render 0.288975 0.203141
Now we have fixed our code, we dont need to do anything to the Trace commandsas they do not interfear with the visual side of our page. All we need to do is set theTrace property to false in the page directive Tag.
-
8/6/2019 Tracing in ASP
9/13
Which part of False do you not understand?
Remember way back to the top of the article, where I showed you an excerpt fromthe .NET SDK Documentation, it said Trace statements are processed and
displayed only when tracing is enabled.?
It Lies.
We can prove this by setting the Trace property on a page to False and then callinga trace command that will cause an exception, for example referencing an objectthat doesnt exist such as a Querystring value: -
privatevoid Page_Load(object sender, System.EventArgs e)
{Trace.Write(Request.QueryString["Doesn'tExist"].ToString());
}
Calling this when Trace is enabled causes an exception to occur: -
Server Error in '/intranet' Application.
Object reference not set to an instance of an object.Description: An unhandled exception occurred during the execution of the current web request. Please reviewthe stack trace for more information about the error and where it originated in the code.
Exception Details: System.NullReferenceException: Object reference not set to an instance of an object.
Source Error:
Line 21: {Line 22: //Some fake business logicLine 23: Trace.Write(Request.QueryString["Doesn'tExist"].ToString());Line 24: }
Line 25:
Source File: c:\inetpub\wwwroot\intranet\default.aspx.cs Line: 23
Stack Trace:
[NullReferenceException: Object reference not set to an instance of anobject.]
intranet._default.Page_Load(Object sender, EventArgs e) inc:\inetpub\wwwroot\intranet\default.aspx.cs:23
System.Web.UI.Control.OnLoad(EventArgs e) +67System.Web.UI.Control.LoadRecursive() +29System.Web.UI.Page.ProcessRequestMain() +718
Version Information: Microsoft .NET Framework Version:1.0.3705.288; ASP.NET Version:1.0.3705.288
This means that the statement Trace statements are processed and displayed onlywhen tracing is enabled. is obviously a blatant lie.
This is also important in terms of costly operations, lets say youve put a large loop
in to your page and its outputting data to the Trace log so you can debug it whydo we need to call this when Trace is turned off?
A solution is provided in the form of Trace.IsEnabled(), we can check to see if
Tracing is enabled before we run the Trace commands, like this: -
-
8/6/2019 Tracing in ASP
10/13
privatevoid Page_Load(object sender, System.EventArgs e){
if(Trace.IsEnabled)
{Trace.Write(Request.QueryString["Doesn'tExist"].ToString());
}}
Now, that means we now have to write four lines of code for every Trace we haveto write, which is really not an inviting thought Trace is supposed to make thingsEASIER not HARDER!
Lets also add some error handling to our Trace command to make sure that even
when we get errors we can handle them properly: -
privatevoid Page_Load(object sender, System.EventArgs e){
if(Trace.IsEnabled){
try{
Trace.Write(Request.QueryString["Doesn'tExist"].ToString());}catch (Exception ex){
Trace.Warn("Trace","Exception",ex);}
}}
Now, our simple 1 line Trace.Write call is 11 lines long! Messy I hope youll agree.
-
8/6/2019 Tracing in ASP
11/13
Tidy the Mess
The easiest and quickest way to get around these limitations of Trace is toencapsulate all the functionality so that we can call it in one line. One way to do
this is to create a class such as so.
using System;
namespace My{
publicclass Trace{
publicstaticvoid Write(string Message){
if(System.Web.HttpContext.Current.Trace.IsEnabled){
try
{
System.Web.HttpContext.Current.Trace.Write(Message.ToString());}
catch(Exception e){
System.Web.HttpContext.Current.Trace.Warn("Intranet.Web","Write",e);}
}}publicstaticvoid Write(string Category, string Message){
if(System.Web.HttpContext.Current.Trace.IsEnabled){
try{
System.Web.HttpContext.Current.Trace.Write(Category.ToString(),Message.ToString());
}catch(Exception e){
System.Web.HttpContext.Current.Trace.Warn("Intranet.Web","Write",e);}
}
}publicstaticvoid Write(string Category, string Message,
System.Exception exe){
if(System.Web.HttpContext.Current.Trace.IsEnabled){try{
System.Web.HttpContext.Current.Trace.Write(Category.ToString(),Message.ToString(),exe);
}catch(Exception e)
{
-
8/6/2019 Tracing in ASP
12/13
System.Web.HttpContext.Current.Trace.Warn("Intranet.Web","Write",e);
}
}}publicstaticvoid Warn(string Message){
if(System.Web.HttpContext.Current.Trace.IsEnabled){
try{
System.Web.HttpContext.Current.Trace.Warn(Message.ToString());}
catch(Exception e){
System.Web.HttpContext.Current.Trace.Warn("Intranet.Web","Write",e);}
}
}publicstaticvoid Warn(string Category, string Message){
if(System.Web.HttpContext.Current.Trace.IsEnabled){
try{
System.Web.HttpContext.Current.Trace.Warn(Category.ToString(),Message.
ToString());}catch(Exception e)
{
System.Web.HttpContext.Current.Trace.Warn("Intranet.Web","Write",e);}
}}publicstaticvoid Warn(string Category, string Message,
System.Exception exe)
{if(System.Web.HttpContext.Current.Trace.IsEnabled){
try{
System.Web.HttpContext.Current.Trace.Warn(Category.ToString(),Message.
ToString(),exe);}catch(Exception e){
System.Web.HttpContext.Current.Trace.Warn("Intranet.Web","Write",e);}
}}
}
-
8/6/2019 Tracing in ASP
13/13
}
If you place the above in to a class file in your project, you can then use it as a 1line replacement for Trace as so: -
privatevoid Page_Load(object sender, System.EventArgs e){
if(Request.QueryString["Doesn'tExist"] != null){
My.Trace.Write(Request.QueryString["Doesn'tExist"].ToString());}
}
This is all nice and neat and encapsulated now, and gives you a performanceincrease which scales with your application through debug and in to release, as wellas error handling of your Trace commands, all this with the ease of use of the Trace
methods them selves.