<?xml version="1.0" encoding="utf-8"?>
<rss xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:pingback="http://madskills.com/public/xml/rss/module/pingback/" version="2.0">
  <channel>
    <title>Samurai Programmer.com - Best Practice</title>
    <link>http://www.samuraiprogrammer.com/blog/</link>
    <description>I know kung fu</description>
    <language>en-us</language>
    <copyright>Greg Varveris</copyright>
    <lastBuildDate>Sun, 29 Aug 2010 22:10:07 GMT</lastBuildDate>
    <generator>newtelligence dasBlog 2.3.9074.18820</generator>
    <managingEditor>greg@samuraiprogrammer.com</managingEditor>
    <webMaster>greg@samuraiprogrammer.com</webMaster>
    <item>
      <trackback:ping>http://www.samuraiprogrammer.com/blog/Trackback.aspx?guid=a06708f7-9f9b-4ea2-8844-b13dad549af5</trackback:ping>
      <pingback:server>http://www.samuraiprogrammer.com/blog/pingback.aspx</pingback:server>
      <pingback:target>http://www.samuraiprogrammer.com/blog/PermaLink,guid,a06708f7-9f9b-4ea2-8844-b13dad549af5.aspx</pingback:target>
      <dc:creator>Greg Varveris</dc:creator>
      <wfw:comment>http://www.samuraiprogrammer.com/blog/CommentView,guid,a06708f7-9f9b-4ea2-8844-b13dad549af5.aspx</wfw:comment>
      <wfw:commentRss>http://www.samuraiprogrammer.com/blog/SyndicationService.asmx/GetEntryCommentsRss?guid=a06708f7-9f9b-4ea2-8844-b13dad549af5</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
          <a href="http://www.samuraiprogrammer.com/blog/content/binary/WindowsLiveWriter/ParsingASP.NETEventLogErrorMessagesforF_445/image_4.png">
            <img style="border-right-width: 0px; margin: 10px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" align="left" src="http://www.samuraiprogrammer.com/blog/content/binary/WindowsLiveWriter/ParsingASP.NETEventLogErrorMessagesforF_445/image_thumb_1.png" width="189" height="158" />
          </a> Sometimes
a customer will ask me to look at their site and make some recommendations on what
can be improved.  One of the many things I’ll look at is their event logs. 
One of the nice things about ASP.NET is that when you encounter an unhandled exception,
an event will be placed into your Application event log.  The message of the
event log entry will usually include lots of good stuff like the application, path,
machine name, exception type, stack trace, etc.  Loads of great stuff and all
for free.  For customers that don’t have a centralized exception logging strategy,
this can be a gold mine.
</p>
        <p>
The way it usually works is that they will provide me an EVTX from their servers. 
If you’re not aware, an EVTX is just an archive of the events from the event log you
specify.  By itself, looking at the raw event logs from a server can be quite
daunting.  There are usually thousands of entries in the event log and filtering
down to what you actually care about can be exhausting.  Even if you do find
a series of ASP.NET event log messages, the problem has always been – how do you take
all of this great information that’s just dumped into the Message property of the
event log entry and put it into a format you can easily report on, generate statistics,
etc.  Fortunately, I have a non-painful solution.  
</p>
        <p>
I’ve broken this down into a relatively simple 4-step process:
</p>
        <ul>
          <li>
Get the EVTX 
</li>
          <li>
Generate a useful XML file 
</li>
          <li>
Parse into an object model 
</li>
          <li>
Analyze and report on the data 
</li>
        </ul>
        <p>
Let’s get to it.
</p>
        <h3>Step 1:  Get the EVTX
</h3>
        <p>
This step is pretty short and sweet.  In the Event Log manager, select the “Application”
group and then select the “Save All Events As…” option.  
</p>
        <p>
          <a href="http://www.samuraiprogrammer.com/blog/content/binary/WindowsLiveWriter/ParsingASP.NETEventLogErrorMessagesforF_445/image_2.png">
            <img style="border-right-width: 0px; margin: 10px 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://www.samuraiprogrammer.com/blog/content/binary/WindowsLiveWriter/ParsingASP.NETEventLogErrorMessagesforF_445/image_thumb.png" width="451" height="146" />
          </a>
        </p>
        <p>
That will produce an EVTX file with whatever name you specify.  Once you have
the file, transfer it to your machine as you generally do not want to install too
many tools in your production environment.
</p>
        <h3>Step 2:  Generate a useful XML file
</h3>
        <p>
Now that we have the raw EVTX file, we can get just the data we care about using <a href="http://www.microsoft.com/downloads/details.aspx?FamilyID=890cd06b-abf8-4c25-91b2-f8d975cf8c07&amp;displaylang=en" target="_blank">a
great tool called LogParser</a>.  <a href="http://www.codinghorror.com/blog/2005/08/microsoft-logparser.html" target="_blank">Jeff
Atwood did a nice little write-up on the tool</a> but simply put it’s <strong>the </strong>Swiss
Army knife of parsing tools.  It can do just about anything data related you
would wish using a nice pseudo-SQL language.  We’ll use the tool to pull out
just the data from the event log we want and dump it into an XML file.  The query
that we can use for this task is daunting in its simplicity:
</p>
        <div style="border-bottom: silver 1px solid; text-align: left; border-left: silver 1px solid; padding-bottom: 4px; line-height: 12pt; background-color: #f4f4f4; margin: 20px 0px 10px; padding-left: 4px; width: 97.5%; padding-right: 4px; font-family: 'Courier New', courier, monospace; direction: ltr; font-size: 8pt; border-top: silver 1px solid; cursor: text; border-right: silver 1px solid; padding-top: 4px" id="codeSnippetWrapper">
          <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px" id="codeSnippet">
            <span style="color: #0000ff">SELECT</span> Message <span style="color: #0000ff">INTO</span> MyData.xml<br /><span style="color: #0000ff">FROM</span> ‘*.evtx’<br /><span style="color: #0000ff">WHERE</span> EventID=1309</pre>
          <br />
        </div>
        <p>
The only other thing we need to tell LogParser is the format in which it the data
is coming in and the format to put it into.  This makes our single command the
following:
</p>
        <div style="border-bottom: silver 1px solid; text-align: left; border-left: silver 1px solid; padding-bottom: 4px; line-height: 12pt; background-color: #f4f4f4; margin: 20px 0px 10px; padding-left: 4px; width: 97.5%; padding-right: 4px; font-family: 'Courier New', courier, monospace; direction: ltr; font-size: 8pt; border-top: silver 1px solid; cursor: text; border-right: silver 1px solid; padding-top: 4px" id="codeSnippetWrapper">
          <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px" id="codeSnippet">C:\&gt;logparser -i:EVT -o:XML<br />
"<span style="color: #0000ff">SELECT</span> Message <span style="color: #0000ff">INTO</span> MyData.xml <span style="color: #0000ff">FROM</span> ‘*.evtx’ <span style="color: #0000ff">WHERE</span> EventID=1309" </pre>
          <br />
        </div>
        <p>
This will produce a nice XML file that looks something like the following:
</p>
        <div style="border-bottom: silver 1px solid; text-align: left; border-left: silver 1px solid; padding-bottom: 4px; line-height: 12pt; background-color: #f4f4f4; margin: 20px 0px 10px; padding-left: 4px; width: 97.5%; padding-right: 4px; font-family: 'Courier New', courier, monospace; direction: ltr; font-size: 8pt; border-top: silver 1px solid; cursor: text; border-right: silver 1px solid; padding-top: 4px" id="codeSnippetWrapper">
          <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px" id="codeSnippet">
            <span style="color: #0000ff">&lt;?</span>
            <span style="color: #800000">xml</span>
            <span style="color: #ff0000">version</span>
            <span style="color: #0000ff">="1.0"</span>
            <span style="color: #ff0000">encoding</span>
            <span style="color: #0000ff">="ISO-10646-UCS-2"</span>
            <span style="color: #ff0000">standalone</span>
            <span style="color: #0000ff">="yes"</span> ?<span style="color: #0000ff">&gt;</span><br /><span style="color: #0000ff">&lt;</span><span style="color: #800000">ROOT</span><span style="color: #ff0000">DATE_CREATED</span><span style="color: #0000ff">="2010-08-29
06:04:20"</span><span style="color: #ff0000">CREATED_BY</span><span style="color: #0000ff">="Microsoft
Log Parser V2.2"</span><span style="color: #0000ff">&gt;</span><br /><span style="color: #0000ff">&lt;</span><span style="color: #800000">ROW</span><span style="color: #0000ff">&gt;</span><br /><span style="color: #0000ff">&lt;</span><span style="color: #800000">Message</span><span style="color: #0000ff">&gt;</span>Event
code: 3005 Event message: An unhandled exception has occurred... 
<br /><span style="color: #0000ff">&lt;/</span><span style="color: #800000">Message</span><span style="color: #0000ff">&gt;</span><br /><span style="color: #0000ff">&lt;/</span><span style="color: #800000">ROW</span><span style="color: #0000ff">&gt;</span><br />
...<br /><span style="color: #0000ff">&lt;/</span><span style="color: #800000">ROOT</span><span style="color: #0000ff">&gt;</span></pre>
          <br />
        </div>
        <p>
One thing that you may notice is that all of the nicely formatted data from our original
event log message is munged together into one unending string.  This will actually
work in our favor but more on that in the next step.
</p>
        <h3>
        </h3>
        <h3>
        </h3>
        <h3>Step 3:  Parse into an object model
</h3>
        <p>
So, now that we have an XML file with all of our event details, let’s do some parsing. 
Since all of our data is in one string, the simplest method is to apply a RegEx expression
with grouping to grab the data we care about.  
</p>
        <blockquote>
          <p>
            <em>
              <strong>In a future post, I’ll talk about a much faster way of getting this type
of data without a RegEx expression.  </strong>
            </em>
            <a href="http://msdn.microsoft.com/en-us/magazine/cc300800.aspx" target="_blank">
              <em>
                <strong>After
all, refactoring is a way of life for developers</strong>
              </em>
            </a>
            <em>
              <strong>.</strong>
            </em>
          </p>
        </blockquote>
        <div style="border-bottom: silver 1px solid; text-align: left; border-left: silver 1px solid; padding-bottom: 4px; line-height: 12pt; background-color: #f4f4f4; margin: 20px 0px 10px; padding-left: 4px; width: 97.5%; padding-right: 4px; font-family: 'Courier New', courier, monospace; direction: ltr; font-size: 8pt; border-top: silver 1px solid; cursor: text; border-right: silver 1px solid; padding-top: 4px" id="codeSnippetWrapper">
          <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px" id="codeSnippet">
            <span style="color: #0000ff">private</span>
            <span style="color: #0000ff">const</span>
            <span style="color: #0000ff">string</span> LargeRegexString
= <span style="color: #006080">@"Event code:(?&lt;Eventcode&gt;.+)"</span> +<br /><span style="color: #006080">@"Event message:(?&lt;Eventmessage&gt;.+)"</span> +<br /><span style="color: #006080">@"Event time:(?&lt;Eventtime&gt;.+)"</span> +<br /><span style="color: #006080">@"Event time \(UTC\):(?&lt;EventtimeUTC&gt;.+)"</span> +<br /><span style="color: #006080">@"Event ID:(?&lt;EventID&gt;.+)"</span> +<br /><span style="color: #006080">@"Event sequence:(?&lt;Eventsequence&gt;.+)"</span> +<br /><span style="color: #006080">@"Event occurrence:(?&lt;Eventoccurrence&gt;.+)"</span> +<br /><span style="color: #006080">@"Event detail code:(?&lt;Eventdetailcode&gt;.+)"</span> +<br /><span style="color: #006080">@"Application information:(?&lt;Applicationinformation&gt;.+)"</span> +<br /><span style="color: #006080">@"Application domain:(?&lt;Applicationdomain&gt;.+)"</span> +<br /><span style="color: #006080">@"Trust level:(?&lt;Trustlevel&gt;.+)"</span> +<br /><span style="color: #006080">@"Full Application Virtual Path:(?&lt;FullApplicationVirtualPath&gt;.+)"</span> +<br /><span style="color: #006080">@"Application Path:(?&lt;ApplicationPath&gt;.+)"</span> +<br /><span style="color: #006080">@"Machine name:(?&lt;Machinename&gt;.+)"</span> +<br /><span style="color: #006080">@"Process information:(?&lt;Processinformation&gt;.+)"</span> +<br /><span style="color: #006080">@"Process ID:(?&lt;ProcessID&gt;.+)"</span> +<br /><span style="color: #006080">@"Process name:(?&lt;Processname&gt;.+)"</span> +<br /><span style="color: #006080">@"Account name:(?&lt;Accountname&gt;.+)"</span> +<br /><span style="color: #006080">@"Exception information:(?&lt;Exceptioninformation&gt;.+)"</span> +<br /><span style="color: #006080">@"Exception type:(?&lt;Exceptiontype&gt;.+)"</span> +<br /><span style="color: #006080">@"Exception message:(?&lt;Exceptionmessage&gt;.+)"</span> +<br /><span style="color: #006080">@"Request information:(?&lt;Requestinformation&gt;.+)"</span> +<br /><span style="color: #006080">@"Request URL:(?&lt;RequestURL&gt;.+)"</span> +<br /><span style="color: #006080">@"Request path:(?&lt;Requestpath&gt;.+)"</span> +<br /><span style="color: #006080">@"User host address:(?&lt;Userhostaddress&gt;.+)"</span> +<br /><span style="color: #006080">@"User:(?&lt;User&gt;.+)"</span> +<br /><span style="color: #006080">@"Is authenticated:(?&lt;Isauthenticated&gt;.+)"</span> +<br /><span style="color: #006080">@"Authentication Type:(?&lt;AuthenticationType&gt;.+)"</span> +<br /><span style="color: #006080">@"Thread account name:(?&lt;Threadaccountname&gt;.+)"</span> +<br /><span style="color: #006080">@"Thread information:(?&lt;Threadinformation&gt;.+)"</span> +<br /><span style="color: #006080">@"Thread ID:(?&lt;ThreadID&gt;.+)"</span> +<br /><span style="color: #006080">@"Thread account name:(?&lt;Threadaccountname&gt;.+)"</span> +<br /><span style="color: #006080">@"Is impersonating:(?&lt;Isimpersonating&gt;.+)"</span> +<br /><span style="color: #006080">@"Stack trace:(?&lt;Stacktrace&gt;.+)"</span> +<br /><span style="color: #006080">@"Custom event details:(?&lt;Customeventdetails&gt;.+)"</span>;</pre>
          <br />
        </div>
        <p>
Now that we have our RegEx, we’ll just write the code to match it against a string
and populate our class.   While I’ve included the entire regex above, I’ve
only included a partial implementation of the class population below. 
</p>
        <div style="border-bottom: silver 1px solid; text-align: left; border-left: silver 1px solid; padding-bottom: 4px; line-height: 12pt; background-color: #f4f4f4; margin: 20px 0px 10px; padding-left: 4px; width: 97.5%; padding-right: 4px; font-family: 'Courier New', courier, monospace; direction: ltr; font-size: 8pt; border-top: silver 1px solid; cursor: text; border-right: silver 1px solid; padding-top: 4px" id="codeSnippetWrapper">
          <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px" id="codeSnippet">
            <span style="color: #0000ff">public</span>
            <span style="color: #0000ff">class</span> EventLogMessage<br />
{<br /><br /><span style="color: #0000ff">private</span><span style="color: #0000ff">static</span> Regex
s_regex = <span style="color: #0000ff">new</span> Regex(LargeRegexString, RegexOptions.Compiled);<br /><br /><span style="color: #0000ff">public</span><span style="color: #0000ff">static</span> EventLogMessage
Load(<span style="color: #0000ff">string</span> rawMessageText)<br />
{<br /><br />
Match myMatch = s_regex.Match(rawMessageText);<br />
EventLogMessage message = <span style="color: #0000ff">new</span> EventLogMessage();<br />
message.Eventcode = myMatch.Groups[<span style="color: #006080">"Eventcode"</span>].Value;<br />
message.Eventmessage = myMatch.Groups[<span style="color: #006080">"Eventmessage"</span>].Value;<br />
message.Eventtime = myMatch.Groups[<span style="color: #006080">"Eventtime"</span>].Value;<br />
message.EventtimeUTC = myMatch.Groups[<span style="color: #006080">"EventtimeUTC"</span>].Value;<br />
message.EventID = myMatch.Groups[<span style="color: #006080">"EventID"</span>].Value;<br />
message.Eventsequence = myMatch.Groups[<span style="color: #006080">"Eventsequence"</span>].Value;<br />
message.Eventoccurrence = myMatch.Groups[<span style="color: #006080">"Eventoccurrence"</span>].Value;<br />
...<br /><span style="color: #0000ff">return</span> message;<br />
}<br /><br /><span style="color: #0000ff">public</span><span style="color: #0000ff">string</span> Eventcode
{ get; set; }<br /><span style="color: #0000ff">public</span><span style="color: #0000ff">string</span> Eventmessage
{ get; set; }<br /><span style="color: #0000ff">public</span><span style="color: #0000ff">string</span> Eventtime
{ get; set; }<br /><span style="color: #0000ff">public</span><span style="color: #0000ff">string</span> EventtimeUTC
{ get; set; }<br /><span style="color: #0000ff">public</span><span style="color: #0000ff">string</span> EventID
{ get; set; }<br /><span style="color: #0000ff">public</span><span style="color: #0000ff">string</span> Eventsequence
{ get; set; }<br /><span style="color: #0000ff">public</span><span style="color: #0000ff">string</span> Eventoccurrence
{ get; set; }<br />
...<br />
}</pre>
          <br />
        </div>
        <p>
The last step is just to read in the XML file and instantiate these objects.
</p>
        <div style="border-bottom: silver 1px solid; text-align: left; border-left: silver 1px solid; padding-bottom: 4px; line-height: 12pt; background-color: #f4f4f4; margin: 20px 0px 10px; padding-left: 4px; width: 97.5%; padding-right: 4px; font-family: 'Courier New', courier, monospace; direction: ltr; font-size: 8pt; border-top: silver 1px solid; cursor: text; border-right: silver 1px solid; padding-top: 4px" id="codeSnippetWrapper">
          <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px" id="codeSnippet">XDocument document = XDocument.Load(<span style="color: #006080">@"&lt;path
to data&gt;\MyData.xml"</span>);<br /><br />
var messages = from message <span style="color: #0000ff">in</span> document.Descendants(<span style="color: #006080">"Message"</span>)<br />
select EventLogMessage.Load(message.Value);</pre>
          <br />
        </div>
        <p>
Now that we have our objects and everything is parsed just right, we can <strong>finally </strong>get
some statistics and make sense of the data.
</p>
        <h3>Step 4:  Analyze and report on the data
</h3>
        <p>
This last step is really the whole point of this exercise.  Fortunately, now
that all of the data is an easily query’able format using our old friend LINQ, the
actual aggregates and statistics are trivial.  Really, though, everyone’s needs
are going to be different but I’ll provide a few queries that might be useful.
</p>
        <h4>Query 1:  Exception Type Summary
</h4>
        <p>
For example, let’s say you wanted to output a breakdown of the various Exception Types
in your log file.  The query you would use for that would be something like:
</p>
        <div style="border-bottom: silver 1px solid; text-align: left; border-left: silver 1px solid; padding-bottom: 4px; line-height: 12pt; background-color: #f4f4f4; margin: 20px 0px 10px; padding-left: 4px; width: 97.5%; padding-right: 4px; font-family: 'Courier New', courier, monospace; direction: ltr; font-size: 8pt; border-top: silver 1px solid; cursor: text; border-right: silver 1px solid; padding-top: 4px" id="codeSnippetWrapper">
          <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px" id="codeSnippet">var results = from log <span style="color: #0000ff">in</span> messages<br />
group log by log.Exceptiontype into l<br />
orderby l.Count() descending, l.Key<br />
select <span style="color: #0000ff">new</span><br />
{<br />
ExceptionType = l.Key,<br />
ExceptionCount = l.Count()<br />
};<br /><br /><span style="color: #0000ff">foreach</span> (var result <span style="color: #0000ff">in</span> results)<br />
{<br /><br />
Console.WriteLine(<span style="color: #006080">"{0} : {1} time(s)"</span>, 
<br />
result.ExceptionType, 
<br />
result.ExceptionCount);<br /><br />
}</pre>
          <br />
        </div>
        <p>
This would then output something like:
</p>
        <div style="border-bottom: silver 1px solid; text-align: left; border-left: silver 1px solid; padding-bottom: 4px; line-height: 12pt; background-color: #f4f4f4; margin: 20px 0px 10px; padding-left: 4px; width: 97.5%; padding-right: 4px; font-family: 'Courier New', courier, monospace; direction: ltr; font-size: 8pt; border-top: silver 1px solid; cursor: text; border-right: silver 1px solid; padding-top: 4px" id="codeSnippetWrapper">
          <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px" id="codeSnippet">WebException : 15 time(s)<br />
InvalidOperationException : 7 time(s)<br />
NotImplementedException : 2 time(s)<br />
InvalidCastException : 1 time(s)<br />
MissingMethodException : 1 time(s)</pre>
          <br />
        </div>
        <h4>Query 2:  Exception Type and Request URL Summary
</h4>
        <p>
Let’s say that you wanted to go deeper and get the breakdown of which URL’s generated
the most exceptions.  You can just expand that second foreach loop in the above
snippet to do the following:
</p>
        <div style="border-bottom: silver 1px solid; text-align: left; border-left: silver 1px solid; padding-bottom: 4px; line-height: 12pt; background-color: #f4f4f4; margin: 20px 0px 10px; padding-left: 4px; width: 97.5%; padding-right: 4px; font-family: 'Courier New', courier, monospace; direction: ltr; font-size: 8pt; border-top: silver 1px solid; cursor: text; border-right: silver 1px solid; padding-top: 4px" id="codeSnippetWrapper">
          <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px" id="codeSnippet">
            <span style="color: #0000ff">foreach</span> (var
result <span style="color: #0000ff">in</span> results)<br />
{<br /><br />
Console.WriteLine(<span style="color: #006080">"{0} : {1} time(s)"</span>, 
<br />
result.ExceptionType, 
<br />
result.ExceptionCount);<br /><br />
var requestUrls = from urls <span style="color: #0000ff">in</span> messages<br /><span style="color: #0000ff">where</span> urls.Exceptiontype == result.ExceptionType<br />
group urls by urls.RequestURL.ToLower() into url<br />
orderby url.Count() descending, url.Key<br />
select <span style="color: #0000ff">new</span><br />
{<br />
RequestUrl = url.Key,<br />
Count = url.Count()<br />
};<br /><br /><span style="color: #0000ff">foreach</span> (var url <span style="color: #0000ff">in</span> requestUrls){<br /><br />
Console.WriteLine(<span style="color: #006080">"\t{0} : {1} times "</span>,<br />
url.RequestUrl,<br />
url.Count);<br />
} 
<br />
}</pre>
          <br />
        </div>
        <p>
This then would produce output like this:
</p>
        <div style="border-bottom: silver 1px solid; text-align: left; border-left: silver 1px solid; padding-bottom: 4px; line-height: 12pt; background-color: #f4f4f4; margin: 20px 0px 10px; padding-left: 4px; width: 97.5%; padding-right: 4px; font-family: 'Courier New', courier, monospace; direction: ltr; font-size: 8pt; border-top: silver 1px solid; cursor: text; border-right: silver 1px solid; padding-top: 4px" id="codeSnippetWrapper">
          <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px" id="codeSnippet">WebException  : 15 time(s)<br />
http://localhost/menusample/default<span style="color: #ff0000">.</span>aspx : 11
times<br />
http://localhost:63188/menusample/default<span style="color: #ff0000">.</span>aspx
: 4 times<br />
InvalidOperationException : 7 time(s)<br />
http://localhost:63188/menusample/default<span style="color: #ff0000">.</span>aspx
: 6 times<br />
http://localhost/menusample/default<span style="color: #ff0000">.</span>aspx : 1 times<br />
NotImplementedException : 2 time(s)<br />
http://localhost/samplewebsiteerror/default<span style="color: #ff0000">.</span>aspx
: 2 times<br />
InvalidCastException : 1 time(s)<br />
http://localhost:63188/menusample/default<span style="color: #ff0000">.</span>aspx
: 1 times<br />
MissingMethodException : 1 time(s)<br />
http://localhost:63188/menusample/default<span style="color: #ff0000">.</span>aspx
: 1 times</pre>
          <br />
        </div>
        <h4>Query 3:  Exception Type, Request URL and Method Name Summary
</h4>
        <p>
You can even go deeper, if you so desire, to find out which of your methods threw
the most exceptions.  For this to work, we need to make a slight change to our
EventLogMessage class to parse the Stack Trace data into a class.  First, we’ll
start with our simple little StackTraceFrame class:
</p>
        <div style="border-bottom: silver 1px solid; text-align: left; border-left: silver 1px solid; padding-bottom: 4px; line-height: 12pt; background-color: #f4f4f4; margin: 20px 0px 10px; padding-left: 4px; width: 97.5%; padding-right: 4px; font-family: 'Courier New', courier, monospace; direction: ltr; font-size: 8pt; border-top: silver 1px solid; cursor: text; border-right: silver 1px solid; padding-top: 4px" id="codeSnippetWrapper">
          <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px" id="codeSnippet">
            <span style="color: #0000ff">public</span>
            <span style="color: #0000ff">class</span> StackTraceFrame<br />
{<br /><span style="color: #0000ff">public</span><span style="color: #0000ff">string</span> Method
{ get; set; }<br /><br />
}</pre>
          <br />
        </div>
        <p>
Second, add a new property to our EventLogMessage class to hold a List&lt;StackTraceFrame&gt;:
</p>
        <div style="border-bottom: silver 1px solid; text-align: left; border-left: silver 1px solid; padding-bottom: 4px; line-height: 12pt; background-color: #f4f4f4; margin: 20px 0px 10px; padding-left: 4px; width: 97.5%; padding-right: 4px; font-family: 'Courier New', courier, monospace; direction: ltr; font-size: 8pt; border-top: silver 1px solid; cursor: text; border-right: silver 1px solid; padding-top: 4px" id="codeSnippetWrapper">
          <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px" id="codeSnippet">
            <span style="color: #0000ff">public</span> List&lt;StackTraceFrame&gt;
StackTraceFrames { get; set; }</pre>
          <br />
        </div>
        <p>
Lastly, add a method (and its caller) to parse out the stack frames and assign the
resulting List to the StackTraceFrames property mentioned above:
</p>
        <div style="border-bottom: silver 1px solid; text-align: left; border-left: silver 1px solid; padding-bottom: 4px; line-height: 12pt; background-color: #f4f4f4; margin: 20px 0px 10px; padding-left: 4px; width: 97.5%; padding-right: 4px; font-family: 'Courier New', courier, monospace; direction: ltr; font-size: 8pt; border-top: silver 1px solid; cursor: text; border-right: silver 1px solid; padding-top: 4px" id="codeSnippetWrapper">
          <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px" id="codeSnippet">
            <span style="color: #0000ff">public</span> EventLogMessage(<span style="color: #0000ff">string</span> rawMessageText)<br />
{<br />
Match myMatch = s_regex.Match(rawMessageText);<br />
...<br />
Stacktrace = myMatch.Groups[<span style="color: #006080">"Stacktrace"</span>].Value;<br />
...<br />
StackTraceFrames = ParseStackTrace(Stacktrace);<br />
}<br /><br /><span style="color: #0000ff">private</span> List&lt;StackTraceFrame&gt; ParseStackTrace(<span style="color: #0000ff">string</span> stackTrace)<br />
{<br />
List&lt;StackTraceFrame&gt; frames = <span style="color: #0000ff">new</span> List&lt;StackTraceFrame&gt;();<br /><span style="color: #0000ff">string</span>[] stackTraceSplit = stackTrace.Split(<span style="color: #0000ff">new</span><span style="color: #0000ff">string</span>[]
{ <span style="color: #006080">" at "</span> }, 
<br />
StringSplitOptions.RemoveEmptyEntries);<br /><span style="color: #0000ff">foreach</span> (<span style="color: #0000ff">string</span> st <span style="color: #0000ff">in</span> stackTraceSplit)<br />
{<br /><span style="color: #0000ff">if</span> (!<span style="color: #0000ff">string</span>.IsNullOrEmpty(st))<br />
{<br />
frames.Add(<span style="color: #0000ff">new</span> StackTraceFrame() { Method = st
});<br />
}<br />
}<br /><span style="color: #0000ff">return</span> frames;<br />
}</pre>
          <br />
        </div>
        <blockquote>
          <p>
            <em>
              <strong>Please Note:  You could enhance the ParseStackTrace(…) method to
parse out the source files, line numbers, etc. I’ll leave this as an exercise for
you, dear reader.</strong>
            </em>
          </p>
        </blockquote>
        <p>
Now that we have the infrastructure in place, the query is just as simple.  We’ll
just nest this additional query inside of our URL query like so:
</p>
        <div style="border-bottom: silver 1px solid; text-align: left; border-left: silver 1px solid; padding-bottom: 4px; line-height: 12pt; background-color: #f4f4f4; margin: 20px 0px 10px; padding-left: 4px; width: 97.5%; padding-right: 4px; font-family: 'Courier New', courier, monospace; direction: ltr; font-size: 8pt; border-top: silver 1px solid; cursor: text; border-right: silver 1px solid; padding-top: 4px" id="codeSnippetWrapper">
          <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px" id="codeSnippet">
            <span style="color: #0000ff">foreach</span> (var
url <span style="color: #0000ff">in</span> requestUrls){<br /><br />
Console.WriteLine(<span style="color: #006080">"\t{0} : {1} times "</span>,<br />
url.RequestUrl,<br />
url.Count);<br /><br />
var methods = from method <span style="color: #0000ff">in</span> messages<br /><span style="color: #0000ff">where</span><span style="color: #0000ff">string</span>.Equals(method.RequestURL, 
<br />
url.RequestUrl, 
<br />
StringComparison.InvariantCultureIgnoreCase) 
<br />
&amp;&amp;<br /><span style="color: #0000ff">string</span>.Equals(method.Exceptiontype, 
<br />
result.ExceptionType, 
<br />
StringComparison.InvariantCultureIgnoreCase)<br />
group method by method.StackTraceFrames[0].Method into mt<br />
orderby mt.Count() descending, mt.Key<br />
select <span style="color: #0000ff">new</span><br />
{<br />
MethodName = mt.Key,<br />
Count = mt.Count()<br />
};<br /><br /><span style="color: #0000ff">foreach</span> (var method <span style="color: #0000ff">in</span> methods)<br />
{<br />
Console.WriteLine(<span style="color: #006080">"\t\t{0} : {1} times "</span>,<br />
method.MethodName,<br />
method.Count<br />
);<br />
}<br />
} </pre>
          <br />
        </div>
        <p>
This would then produce output like the following:
</p>
        <div style="border-bottom: silver 1px solid; text-align: left; border-left: silver 1px solid; padding-bottom: 4px; line-height: 12pt; background-color: #f4f4f4; margin: 20px 0px 10px; padding-left: 4px; width: 97.5%; padding-right: 4px; font-family: 'Courier New', courier, monospace; direction: ltr; font-size: 8pt; border-top: silver 1px solid; cursor: text; border-right: silver 1px solid; padding-top: 4px" id="codeSnippetWrapper">
          <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px" id="codeSnippet">WebException  : 15 time(s)<br />
http://localhost/menusample/default.aspx : 11 times<br />
System.Net.HttpWebRequest.GetResponse() : 11 times<br />
http://localhost:63188/menusample/default.aspx : 4 times<br />
System.Net.HttpWebRequest.GetResponse() : 4 times<br />
InvalidOperationException : 7 time(s)<br />
http://localhost:63188/menusample/default.aspx : 6 times<br />
System.Web.UI.WebControls.Menu... : 6 times<br />
http://localhost/menusample/default.aspx : 1 times<br />
System.Web.UI.WebControls.Menu... : 1 times</pre>
          <br />
        </div>
        <p>
One last thing you may notice is that the in the example above, the first frame for
each of those exceptions are somewhere in the bowels of the .NET BCL.  You may
want to filter this out even further to only return <strong>YOUR </strong>method. 
This can be accomplished very easily with the method below.  It will simply loop
through the StackTraceFrame List and return the first method it encounters that does
not start with “System.” or “Microsoft.”.
</p>
        <div style="border-bottom: silver 1px solid; text-align: left; border-left: silver 1px solid; padding-bottom: 4px; line-height: 12pt; background-color: #f4f4f4; margin: 20px 0px 10px; padding-left: 4px; width: 97.5%; padding-right: 4px; font-family: 'Courier New', courier, monospace; direction: ltr; font-size: 8pt; border-top: silver 1px solid; cursor: text; border-right: silver 1px solid; padding-top: 4px" id="codeSnippetWrapper">
          <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px" id="codeSnippet">
            <span style="color: #0000ff">private</span>
            <span style="color: #0000ff">static</span>
            <span style="color: #0000ff">string</span> GetMyMethod(List&lt;StackTraceFrame&gt;
frames)<br />
{<br /><br /><span style="color: #0000ff">foreach</span> (StackTraceFrame frame <span style="color: #0000ff">in</span> frames)<br />
{<br /><br /><span style="color: #0000ff">if</span> (!frame.Method.StartsWith(<span style="color: #006080">"System."</span>)
&amp;&amp;<br />
!frame.Method.StartsWith(<span style="color: #006080">"Microsoft."</span>))<br /><span style="color: #0000ff">return</span> frame.Method;<br /><br /><br />
}<br /><br /><span style="color: #0000ff">return</span><span style="color: #006080">"No User
Code detected."</span>;<br />
}</pre>
          <br />
        </div>
        <p>
Then, you can just call that method from the new query we wrote above:
</p>
        <div style="border-bottom: silver 1px solid; text-align: left; border-left: silver 1px solid; padding-bottom: 4px; line-height: 12pt; background-color: #f4f4f4; margin: 20px 0px 10px; padding-left: 4px; width: 97.5%; padding-right: 4px; font-family: 'Courier New', courier, monospace; direction: ltr; font-size: 8pt; border-top: silver 1px solid; cursor: text; border-right: silver 1px solid; padding-top: 4px" id="codeSnippetWrapper">
          <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px" id="codeSnippet">var methods = from method <span style="color: #0000ff">in</span> messages<br /><span style="color: #0000ff">where</span> ...<br />
group method by 
<br />
GetMyMethod(method.StackTraceFrames) into mt<br />
...</pre>
          <br />
        </div>
        <p>
Finally, with this new snippet in place, we’ll get output like this:
</p>
        <div style="border-bottom: silver 1px solid; text-align: left; border-left: silver 1px solid; padding-bottom: 4px; line-height: 12pt; background-color: #f4f4f4; margin: 20px 0px 10px; padding-left: 4px; width: 97.5%; padding-right: 4px; font-family: 'Courier New', courier, monospace; direction: ltr; font-size: 8pt; border-top: silver 1px solid; cursor: text; border-right: silver 1px solid; padding-top: 4px" id="codeSnippetWrapper">
          <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px" id="codeSnippet">WebException  : 15 time(s)<br />
http://localhost/menusample/default.aspx : 11 times<br />
_Default.Page_Load(Object sender, EventArgs e)...: 8 times<br />
No User Code detected. : 3 times<br /><br />
http://localhost:63188/menusample/default.aspx : 4 times<br />
_Default.Page_Load(Object sender, EventArgs e)... : 1 times<br />
No User Code detected. : 1 times<br />
WebControls.CustomXmlHierarchicalDataSourceView.Select()... : 2 times</pre>
          <br />
        </div>
        <p>
As you can see, the sky’s the limit.
</p>
        <p>
Enjoy!
</p>
      </body>
      <title>Parsing ASP.NET event log error messages for fun and profit</title>
      <guid isPermaLink="false">http://www.samuraiprogrammer.com/blog/PermaLink,guid,a06708f7-9f9b-4ea2-8844-b13dad549af5.aspx</guid>
      <link>http://www.samuraiprogrammer.com/blog/2010/08/29/ParsingASPNETEventLogErrorMessagesForFunAndProfit.aspx</link>
      <pubDate>Sun, 29 Aug 2010 22:10:07 GMT</pubDate>
      <description>&lt;p&gt;
&lt;a href="http://www.samuraiprogrammer.com/blog/content/binary/WindowsLiveWriter/ParsingASP.NETEventLogErrorMessagesforF_445/image_4.png"&gt;&lt;img style="border-right-width: 0px; margin: 10px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" align="left" src="http://www.samuraiprogrammer.com/blog/content/binary/WindowsLiveWriter/ParsingASP.NETEventLogErrorMessagesforF_445/image_thumb_1.png" width="189" height="158" /&gt;&lt;/a&gt; Sometimes
a customer will ask me to look at their site and make some recommendations on what
can be improved.&amp;#160; One of the many things I’ll look at is their event logs.&amp;#160;
One of the nice things about ASP.NET is that when you encounter an unhandled exception,
an event will be placed into your Application event log.&amp;#160; The message of the
event log entry will usually include lots of good stuff like the application, path,
machine name, exception type, stack trace, etc.&amp;#160; Loads of great stuff and all
for free.&amp;#160; For customers that don’t have a centralized exception logging strategy,
this can be a gold mine.
&lt;/p&gt;
&lt;p&gt;
The way it usually works is that they will provide me an EVTX from their servers.&amp;#160;
If you’re not aware, an EVTX is just an archive of the events from the event log you
specify.&amp;#160; By itself, looking at the raw event logs from a server can be quite
daunting.&amp;#160; There are usually thousands of entries in the event log and filtering
down to what you actually care about can be exhausting.&amp;#160; Even if you do find
a series of ASP.NET event log messages, the problem has always been – how do you take
all of this great information that’s just dumped into the Message property of the
event log entry and put it into a format you can easily report on, generate statistics,
etc.&amp;#160; Fortunately, I have a non-painful solution.&amp;#160; 
&lt;/p&gt;
&lt;p&gt;
I’ve broken this down into a relatively simple 4-step process:
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
Get the EVTX 
&lt;/li&gt;
&lt;li&gt;
Generate a useful XML file 
&lt;/li&gt;
&lt;li&gt;
Parse into an object model 
&lt;/li&gt;
&lt;li&gt;
Analyze and report on the data 
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
Let’s get to it.
&lt;/p&gt;
&lt;h3&gt;Step 1:&amp;#160; Get the EVTX
&lt;/h3&gt;
&lt;p&gt;
This step is pretty short and sweet.&amp;#160; In the Event Log manager, select the “Application”
group and then select the “Save All Events As…” option.&amp;#160; 
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://www.samuraiprogrammer.com/blog/content/binary/WindowsLiveWriter/ParsingASP.NETEventLogErrorMessagesforF_445/image_2.png"&gt;&lt;img style="border-right-width: 0px; margin: 10px 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://www.samuraiprogrammer.com/blog/content/binary/WindowsLiveWriter/ParsingASP.NETEventLogErrorMessagesforF_445/image_thumb.png" width="451" height="146" /&gt;&lt;/a&gt; 
&lt;/p&gt;
&lt;p&gt;
That will produce an EVTX file with whatever name you specify.&amp;#160; Once you have
the file, transfer it to your machine as you generally do not want to install too
many tools in your production environment.
&lt;/p&gt;
&lt;h3&gt;Step 2:&amp;#160; Generate a useful XML file
&lt;/h3&gt;
&lt;p&gt;
Now that we have the raw EVTX file, we can get just the data we care about using &lt;a href="http://www.microsoft.com/downloads/details.aspx?FamilyID=890cd06b-abf8-4c25-91b2-f8d975cf8c07&amp;amp;displaylang=en" target="_blank"&gt;a
great tool called LogParser&lt;/a&gt;.&amp;#160; &lt;a href="http://www.codinghorror.com/blog/2005/08/microsoft-logparser.html" target="_blank"&gt;Jeff
Atwood did a nice little write-up on the tool&lt;/a&gt; but simply put it’s &lt;strong&gt;the &lt;/strong&gt;Swiss
Army knife of parsing tools.&amp;#160; It can do just about anything data related you
would wish using a nice pseudo-SQL language.&amp;#160; We’ll use the tool to pull out
just the data from the event log we want and dump it into an XML file.&amp;#160; The query
that we can use for this task is daunting in its simplicity:
&lt;/p&gt;
&lt;div style="border-bottom: silver 1px solid; text-align: left; border-left: silver 1px solid; padding-bottom: 4px; line-height: 12pt; background-color: #f4f4f4; margin: 20px 0px 10px; padding-left: 4px; width: 97.5%; padding-right: 4px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; font-size: 8pt; border-top: silver 1px solid; cursor: text; border-right: silver 1px solid; padding-top: 4px" id="codeSnippetWrapper"&gt;
&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px" id="codeSnippet"&gt;&lt;span style="color: #0000ff"&gt;SELECT&lt;/span&gt; Message &lt;span style="color: #0000ff"&gt;INTO&lt;/span&gt; MyData.xml&lt;br /&gt;
&lt;span style="color: #0000ff"&gt;FROM&lt;/span&gt; ‘*.evtx’&lt;br /&gt;
&lt;span style="color: #0000ff"&gt;WHERE&lt;/span&gt; EventID=1309&lt;/pre&gt;
&lt;br /&gt;
&lt;/div&gt;
&lt;p&gt;
The only other thing we need to tell LogParser is the format in which it the data
is coming in and the format to put it into.&amp;#160; This makes our single command the
following:
&lt;/p&gt;
&lt;div style="border-bottom: silver 1px solid; text-align: left; border-left: silver 1px solid; padding-bottom: 4px; line-height: 12pt; background-color: #f4f4f4; margin: 20px 0px 10px; padding-left: 4px; width: 97.5%; padding-right: 4px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; font-size: 8pt; border-top: silver 1px solid; cursor: text; border-right: silver 1px solid; padding-top: 4px" id="codeSnippetWrapper"&gt;
&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px" id="codeSnippet"&gt;C:\&amp;gt;logparser -i:EVT -o:XML&lt;br /&gt;
&amp;quot;&lt;span style="color: #0000ff"&gt;SELECT&lt;/span&gt; Message &lt;span style="color: #0000ff"&gt;INTO&lt;/span&gt; MyData.xml &lt;span style="color: #0000ff"&gt;FROM&lt;/span&gt; ‘*.evtx’ &lt;span style="color: #0000ff"&gt;WHERE&lt;/span&gt; EventID=1309&amp;quot; &lt;/pre&gt;
&lt;br /&gt;
&lt;/div&gt;
&lt;p&gt;
This will produce a nice XML file that looks something like the following:
&lt;/p&gt;
&lt;div style="border-bottom: silver 1px solid; text-align: left; border-left: silver 1px solid; padding-bottom: 4px; line-height: 12pt; background-color: #f4f4f4; margin: 20px 0px 10px; padding-left: 4px; width: 97.5%; padding-right: 4px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; font-size: 8pt; border-top: silver 1px solid; cursor: text; border-right: silver 1px solid; padding-top: 4px" id="codeSnippetWrapper"&gt;
&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px" id="codeSnippet"&gt;&lt;span style="color: #0000ff"&gt;&amp;lt;?&lt;/span&gt;&lt;span style="color: #800000"&gt;xml&lt;/span&gt; &lt;span style="color: #ff0000"&gt;version&lt;/span&gt;&lt;span style="color: #0000ff"&gt;=&amp;quot;1.0&amp;quot;&lt;/span&gt; &lt;span style="color: #ff0000"&gt;encoding&lt;/span&gt;&lt;span style="color: #0000ff"&gt;=&amp;quot;ISO-10646-UCS-2&amp;quot;&lt;/span&gt; &lt;span style="color: #ff0000"&gt;standalone&lt;/span&gt;&lt;span style="color: #0000ff"&gt;=&amp;quot;yes&amp;quot;&lt;/span&gt; ?&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;
&lt;br /&gt;
&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;ROOT&lt;/span&gt; &lt;span style="color: #ff0000"&gt;DATE_CREATED&lt;/span&gt;&lt;span style="color: #0000ff"&gt;=&amp;quot;2010-08-29
06:04:20&amp;quot;&lt;/span&gt; &lt;span style="color: #ff0000"&gt;CREATED_BY&lt;/span&gt;&lt;span style="color: #0000ff"&gt;=&amp;quot;Microsoft
Log Parser V2.2&amp;quot;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;
&lt;br /&gt;
&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;ROW&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;
&lt;br /&gt;
&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;Message&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;Event
code: 3005 Event message: An unhandled exception has occurred... 
&lt;br /&gt;
&lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;Message&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;
&lt;br /&gt;
&lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;ROW&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;
&lt;br /&gt;
...&lt;br /&gt;
&lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;ROOT&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;br /&gt;
&lt;/div&gt;
&lt;p&gt;
One thing that you may notice is that all of the nicely formatted data from our original
event log message is munged together into one unending string.&amp;#160; This will actually
work in our favor but more on that in the next step.
&lt;/p&gt;
&lt;h3&gt;
&lt;/h3&gt;
&lt;h3&gt;
&lt;/h3&gt;
&lt;h3&gt;Step 3:&amp;#160; Parse into an object model
&lt;/h3&gt;
&lt;p&gt;
So, now that we have an XML file with all of our event details, let’s do some parsing.&amp;#160;
Since all of our data is in one string, the simplest method is to apply a RegEx expression
with grouping to grab the data we care about.&amp;#160; 
&lt;/p&gt;
&lt;blockquote&gt; 
&lt;p&gt;
&lt;em&gt;&lt;strong&gt;In a future post, I’ll talk about a much faster way of getting this type
of data without a RegEx expression.&amp;#160; &lt;/strong&gt;&lt;/em&gt;&lt;a href="http://msdn.microsoft.com/en-us/magazine/cc300800.aspx" target="_blank"&gt;&lt;em&gt;&lt;strong&gt;After
all, refactoring is a way of life for developers&lt;/strong&gt;&lt;/em&gt;&lt;/a&gt;&lt;em&gt;&lt;strong&gt;.&lt;/strong&gt;&lt;/em&gt;
&lt;/p&gt;
&lt;/blockquote&gt; 
&lt;div style="border-bottom: silver 1px solid; text-align: left; border-left: silver 1px solid; padding-bottom: 4px; line-height: 12pt; background-color: #f4f4f4; margin: 20px 0px 10px; padding-left: 4px; width: 97.5%; padding-right: 4px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; font-size: 8pt; border-top: silver 1px solid; cursor: text; border-right: silver 1px solid; padding-top: 4px" id="codeSnippetWrapper"&gt;
&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px" id="codeSnippet"&gt;&lt;span style="color: #0000ff"&gt;private&lt;/span&gt; &lt;span style="color: #0000ff"&gt;const&lt;/span&gt; &lt;span style="color: #0000ff"&gt;string&lt;/span&gt; LargeRegexString
= &lt;span style="color: #006080"&gt;@&amp;quot;Event code:(?&amp;lt;Eventcode&amp;gt;.+)&amp;quot;&lt;/span&gt; +&lt;br /&gt;
&lt;span style="color: #006080"&gt;@&amp;quot;Event message:(?&amp;lt;Eventmessage&amp;gt;.+)&amp;quot;&lt;/span&gt; +&lt;br /&gt;
&lt;span style="color: #006080"&gt;@&amp;quot;Event time:(?&amp;lt;Eventtime&amp;gt;.+)&amp;quot;&lt;/span&gt; +&lt;br /&gt;
&lt;span style="color: #006080"&gt;@&amp;quot;Event time \(UTC\):(?&amp;lt;EventtimeUTC&amp;gt;.+)&amp;quot;&lt;/span&gt; +&lt;br /&gt;
&lt;span style="color: #006080"&gt;@&amp;quot;Event ID:(?&amp;lt;EventID&amp;gt;.+)&amp;quot;&lt;/span&gt; +&lt;br /&gt;
&lt;span style="color: #006080"&gt;@&amp;quot;Event sequence:(?&amp;lt;Eventsequence&amp;gt;.+)&amp;quot;&lt;/span&gt; +&lt;br /&gt;
&lt;span style="color: #006080"&gt;@&amp;quot;Event occurrence:(?&amp;lt;Eventoccurrence&amp;gt;.+)&amp;quot;&lt;/span&gt; +&lt;br /&gt;
&lt;span style="color: #006080"&gt;@&amp;quot;Event detail code:(?&amp;lt;Eventdetailcode&amp;gt;.+)&amp;quot;&lt;/span&gt; +&lt;br /&gt;
&lt;span style="color: #006080"&gt;@&amp;quot;Application information:(?&amp;lt;Applicationinformation&amp;gt;.+)&amp;quot;&lt;/span&gt; +&lt;br /&gt;
&lt;span style="color: #006080"&gt;@&amp;quot;Application domain:(?&amp;lt;Applicationdomain&amp;gt;.+)&amp;quot;&lt;/span&gt; +&lt;br /&gt;
&lt;span style="color: #006080"&gt;@&amp;quot;Trust level:(?&amp;lt;Trustlevel&amp;gt;.+)&amp;quot;&lt;/span&gt; +&lt;br /&gt;
&lt;span style="color: #006080"&gt;@&amp;quot;Full Application Virtual Path:(?&amp;lt;FullApplicationVirtualPath&amp;gt;.+)&amp;quot;&lt;/span&gt; +&lt;br /&gt;
&lt;span style="color: #006080"&gt;@&amp;quot;Application Path:(?&amp;lt;ApplicationPath&amp;gt;.+)&amp;quot;&lt;/span&gt; +&lt;br /&gt;
&lt;span style="color: #006080"&gt;@&amp;quot;Machine name:(?&amp;lt;Machinename&amp;gt;.+)&amp;quot;&lt;/span&gt; +&lt;br /&gt;
&lt;span style="color: #006080"&gt;@&amp;quot;Process information:(?&amp;lt;Processinformation&amp;gt;.+)&amp;quot;&lt;/span&gt; +&lt;br /&gt;
&lt;span style="color: #006080"&gt;@&amp;quot;Process ID:(?&amp;lt;ProcessID&amp;gt;.+)&amp;quot;&lt;/span&gt; +&lt;br /&gt;
&lt;span style="color: #006080"&gt;@&amp;quot;Process name:(?&amp;lt;Processname&amp;gt;.+)&amp;quot;&lt;/span&gt; +&lt;br /&gt;
&lt;span style="color: #006080"&gt;@&amp;quot;Account name:(?&amp;lt;Accountname&amp;gt;.+)&amp;quot;&lt;/span&gt; +&lt;br /&gt;
&lt;span style="color: #006080"&gt;@&amp;quot;Exception information:(?&amp;lt;Exceptioninformation&amp;gt;.+)&amp;quot;&lt;/span&gt; +&lt;br /&gt;
&lt;span style="color: #006080"&gt;@&amp;quot;Exception type:(?&amp;lt;Exceptiontype&amp;gt;.+)&amp;quot;&lt;/span&gt; +&lt;br /&gt;
&lt;span style="color: #006080"&gt;@&amp;quot;Exception message:(?&amp;lt;Exceptionmessage&amp;gt;.+)&amp;quot;&lt;/span&gt; +&lt;br /&gt;
&lt;span style="color: #006080"&gt;@&amp;quot;Request information:(?&amp;lt;Requestinformation&amp;gt;.+)&amp;quot;&lt;/span&gt; +&lt;br /&gt;
&lt;span style="color: #006080"&gt;@&amp;quot;Request URL:(?&amp;lt;RequestURL&amp;gt;.+)&amp;quot;&lt;/span&gt; +&lt;br /&gt;
&lt;span style="color: #006080"&gt;@&amp;quot;Request path:(?&amp;lt;Requestpath&amp;gt;.+)&amp;quot;&lt;/span&gt; +&lt;br /&gt;
&lt;span style="color: #006080"&gt;@&amp;quot;User host address:(?&amp;lt;Userhostaddress&amp;gt;.+)&amp;quot;&lt;/span&gt; +&lt;br /&gt;
&lt;span style="color: #006080"&gt;@&amp;quot;User:(?&amp;lt;User&amp;gt;.+)&amp;quot;&lt;/span&gt; +&lt;br /&gt;
&lt;span style="color: #006080"&gt;@&amp;quot;Is authenticated:(?&amp;lt;Isauthenticated&amp;gt;.+)&amp;quot;&lt;/span&gt; +&lt;br /&gt;
&lt;span style="color: #006080"&gt;@&amp;quot;Authentication Type:(?&amp;lt;AuthenticationType&amp;gt;.+)&amp;quot;&lt;/span&gt; +&lt;br /&gt;
&lt;span style="color: #006080"&gt;@&amp;quot;Thread account name:(?&amp;lt;Threadaccountname&amp;gt;.+)&amp;quot;&lt;/span&gt; +&lt;br /&gt;
&lt;span style="color: #006080"&gt;@&amp;quot;Thread information:(?&amp;lt;Threadinformation&amp;gt;.+)&amp;quot;&lt;/span&gt; +&lt;br /&gt;
&lt;span style="color: #006080"&gt;@&amp;quot;Thread ID:(?&amp;lt;ThreadID&amp;gt;.+)&amp;quot;&lt;/span&gt; +&lt;br /&gt;
&lt;span style="color: #006080"&gt;@&amp;quot;Thread account name:(?&amp;lt;Threadaccountname&amp;gt;.+)&amp;quot;&lt;/span&gt; +&lt;br /&gt;
&lt;span style="color: #006080"&gt;@&amp;quot;Is impersonating:(?&amp;lt;Isimpersonating&amp;gt;.+)&amp;quot;&lt;/span&gt; +&lt;br /&gt;
&lt;span style="color: #006080"&gt;@&amp;quot;Stack trace:(?&amp;lt;Stacktrace&amp;gt;.+)&amp;quot;&lt;/span&gt; +&lt;br /&gt;
&lt;span style="color: #006080"&gt;@&amp;quot;Custom event details:(?&amp;lt;Customeventdetails&amp;gt;.+)&amp;quot;&lt;/span&gt;;&lt;/pre&gt;
&lt;br /&gt;
&lt;/div&gt;
&lt;p&gt;
Now that we have our RegEx, we’ll just write the code to match it against a string
and populate our class.&amp;#160;&amp;#160; While I’ve included the entire regex above, I’ve
only included a partial implementation of the class population below. 
&lt;/p&gt;
&lt;div style="border-bottom: silver 1px solid; text-align: left; border-left: silver 1px solid; padding-bottom: 4px; line-height: 12pt; background-color: #f4f4f4; margin: 20px 0px 10px; padding-left: 4px; width: 97.5%; padding-right: 4px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; font-size: 8pt; border-top: silver 1px solid; cursor: text; border-right: silver 1px solid; padding-top: 4px" id="codeSnippetWrapper"&gt;
&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px" id="codeSnippet"&gt;&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;class&lt;/span&gt; EventLogMessage&lt;br /&gt;
{&lt;br /&gt;
&lt;br /&gt;
&lt;span style="color: #0000ff"&gt;private&lt;/span&gt; &lt;span style="color: #0000ff"&gt;static&lt;/span&gt; Regex
s_regex = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; Regex(LargeRegexString, RegexOptions.Compiled);&lt;br /&gt;
&lt;br /&gt;
&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;static&lt;/span&gt; EventLogMessage
Load(&lt;span style="color: #0000ff"&gt;string&lt;/span&gt; rawMessageText)&lt;br /&gt;
{&lt;br /&gt;
&lt;br /&gt;
Match myMatch = s_regex.Match(rawMessageText);&lt;br /&gt;
EventLogMessage message = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; EventLogMessage();&lt;br /&gt;
message.Eventcode = myMatch.Groups[&lt;span style="color: #006080"&gt;&amp;quot;Eventcode&amp;quot;&lt;/span&gt;].Value;&lt;br /&gt;
message.Eventmessage = myMatch.Groups[&lt;span style="color: #006080"&gt;&amp;quot;Eventmessage&amp;quot;&lt;/span&gt;].Value;&lt;br /&gt;
message.Eventtime = myMatch.Groups[&lt;span style="color: #006080"&gt;&amp;quot;Eventtime&amp;quot;&lt;/span&gt;].Value;&lt;br /&gt;
message.EventtimeUTC = myMatch.Groups[&lt;span style="color: #006080"&gt;&amp;quot;EventtimeUTC&amp;quot;&lt;/span&gt;].Value;&lt;br /&gt;
message.EventID = myMatch.Groups[&lt;span style="color: #006080"&gt;&amp;quot;EventID&amp;quot;&lt;/span&gt;].Value;&lt;br /&gt;
message.Eventsequence = myMatch.Groups[&lt;span style="color: #006080"&gt;&amp;quot;Eventsequence&amp;quot;&lt;/span&gt;].Value;&lt;br /&gt;
message.Eventoccurrence = myMatch.Groups[&lt;span style="color: #006080"&gt;&amp;quot;Eventoccurrence&amp;quot;&lt;/span&gt;].Value;&lt;br /&gt;
...&lt;br /&gt;
&lt;span style="color: #0000ff"&gt;return&lt;/span&gt; message;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;string&lt;/span&gt; Eventcode
{ get; set; }&lt;br /&gt;
&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;string&lt;/span&gt; Eventmessage
{ get; set; }&lt;br /&gt;
&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;string&lt;/span&gt; Eventtime
{ get; set; }&lt;br /&gt;
&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;string&lt;/span&gt; EventtimeUTC
{ get; set; }&lt;br /&gt;
&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;string&lt;/span&gt; EventID
{ get; set; }&lt;br /&gt;
&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;string&lt;/span&gt; Eventsequence
{ get; set; }&lt;br /&gt;
&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;string&lt;/span&gt; Eventoccurrence
{ get; set; }&lt;br /&gt;
...&lt;br /&gt;
}&lt;/pre&gt;
&lt;br /&gt;
&lt;/div&gt;
&lt;p&gt;
The last step is just to read in the XML file and instantiate these objects.
&lt;/p&gt;
&lt;div style="border-bottom: silver 1px solid; text-align: left; border-left: silver 1px solid; padding-bottom: 4px; line-height: 12pt; background-color: #f4f4f4; margin: 20px 0px 10px; padding-left: 4px; width: 97.5%; padding-right: 4px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; font-size: 8pt; border-top: silver 1px solid; cursor: text; border-right: silver 1px solid; padding-top: 4px" id="codeSnippetWrapper"&gt;
&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px" id="codeSnippet"&gt;XDocument document = XDocument.Load(&lt;span style="color: #006080"&gt;@&amp;quot;&amp;lt;path
to data&amp;gt;\MyData.xml&amp;quot;&lt;/span&gt;);&lt;br /&gt;
&lt;br /&gt;
var messages = from message &lt;span style="color: #0000ff"&gt;in&lt;/span&gt; document.Descendants(&lt;span style="color: #006080"&gt;&amp;quot;Message&amp;quot;&lt;/span&gt;)&lt;br /&gt;
select EventLogMessage.Load(message.Value);&lt;/pre&gt;
&lt;br /&gt;
&lt;/div&gt;
&lt;p&gt;
Now that we have our objects and everything is parsed just right, we can &lt;strong&gt;finally &lt;/strong&gt;get
some statistics and make sense of the data.
&lt;/p&gt;
&lt;h3&gt;Step 4:&amp;#160; Analyze and report on the data
&lt;/h3&gt;
&lt;p&gt;
This last step is really the whole point of this exercise.&amp;#160; Fortunately, now
that all of the data is an easily query’able format using our old friend LINQ, the
actual aggregates and statistics are trivial.&amp;#160; Really, though, everyone’s needs
are going to be different but I’ll provide a few queries that might be useful.
&lt;/p&gt;
&lt;h4&gt;Query 1:&amp;#160; Exception Type Summary
&lt;/h4&gt;
&lt;p&gt;
For example, let’s say you wanted to output a breakdown of the various Exception Types
in your log file.&amp;#160; The query you would use for that would be something like:
&lt;/p&gt;
&lt;div style="border-bottom: silver 1px solid; text-align: left; border-left: silver 1px solid; padding-bottom: 4px; line-height: 12pt; background-color: #f4f4f4; margin: 20px 0px 10px; padding-left: 4px; width: 97.5%; padding-right: 4px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; font-size: 8pt; border-top: silver 1px solid; cursor: text; border-right: silver 1px solid; padding-top: 4px" id="codeSnippetWrapper"&gt;
&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px" id="codeSnippet"&gt;var results = from log &lt;span style="color: #0000ff"&gt;in&lt;/span&gt; messages&lt;br /&gt;
group log by log.Exceptiontype into l&lt;br /&gt;
orderby l.Count() descending, l.Key&lt;br /&gt;
select &lt;span style="color: #0000ff"&gt;new&lt;/span&gt;
&lt;br /&gt;
{&lt;br /&gt;
ExceptionType = l.Key,&lt;br /&gt;
ExceptionCount = l.Count()&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
&lt;span style="color: #0000ff"&gt;foreach&lt;/span&gt; (var result &lt;span style="color: #0000ff"&gt;in&lt;/span&gt; results)&lt;br /&gt;
{&lt;br /&gt;
&lt;br /&gt;
Console.WriteLine(&lt;span style="color: #006080"&gt;&amp;quot;{0} : {1} time(s)&amp;quot;&lt;/span&gt;, 
&lt;br /&gt;
result.ExceptionType, 
&lt;br /&gt;
result.ExceptionCount);&lt;br /&gt;
&lt;br /&gt;
}&lt;/pre&gt;
&lt;br /&gt;
&lt;/div&gt;
&lt;p&gt;
This would then output something like:
&lt;/p&gt;
&lt;div style="border-bottom: silver 1px solid; text-align: left; border-left: silver 1px solid; padding-bottom: 4px; line-height: 12pt; background-color: #f4f4f4; margin: 20px 0px 10px; padding-left: 4px; width: 97.5%; padding-right: 4px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; font-size: 8pt; border-top: silver 1px solid; cursor: text; border-right: silver 1px solid; padding-top: 4px" id="codeSnippetWrapper"&gt;
&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px" id="codeSnippet"&gt;WebException : 15 time(s)&lt;br /&gt;
InvalidOperationException : 7 time(s)&lt;br /&gt;
NotImplementedException : 2 time(s)&lt;br /&gt;
InvalidCastException : 1 time(s)&lt;br /&gt;
MissingMethodException : 1 time(s)&lt;/pre&gt;
&lt;br /&gt;
&lt;/div&gt;
&lt;h4&gt;Query 2:&amp;#160; Exception Type and Request URL Summary
&lt;/h4&gt;
&lt;p&gt;
Let’s say that you wanted to go deeper and get the breakdown of which URL’s generated
the most exceptions.&amp;#160; You can just expand that second foreach loop in the above
snippet to do the following:
&lt;/p&gt;
&lt;div style="border-bottom: silver 1px solid; text-align: left; border-left: silver 1px solid; padding-bottom: 4px; line-height: 12pt; background-color: #f4f4f4; margin: 20px 0px 10px; padding-left: 4px; width: 97.5%; padding-right: 4px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; font-size: 8pt; border-top: silver 1px solid; cursor: text; border-right: silver 1px solid; padding-top: 4px" id="codeSnippetWrapper"&gt;
&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px" id="codeSnippet"&gt;&lt;span style="color: #0000ff"&gt;foreach&lt;/span&gt; (var
result &lt;span style="color: #0000ff"&gt;in&lt;/span&gt; results)&lt;br /&gt;
{&lt;br /&gt;
&lt;br /&gt;
Console.WriteLine(&lt;span style="color: #006080"&gt;&amp;quot;{0} : {1} time(s)&amp;quot;&lt;/span&gt;, 
&lt;br /&gt;
result.ExceptionType, 
&lt;br /&gt;
result.ExceptionCount);&lt;br /&gt;
&lt;br /&gt;
var requestUrls = from urls &lt;span style="color: #0000ff"&gt;in&lt;/span&gt; messages&lt;br /&gt;
&lt;span style="color: #0000ff"&gt;where&lt;/span&gt; urls.Exceptiontype == result.ExceptionType&lt;br /&gt;
group urls by urls.RequestURL.ToLower() into url&lt;br /&gt;
orderby url.Count() descending, url.Key&lt;br /&gt;
select &lt;span style="color: #0000ff"&gt;new&lt;/span&gt;
&lt;br /&gt;
{&lt;br /&gt;
RequestUrl = url.Key,&lt;br /&gt;
Count = url.Count()&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
&lt;span style="color: #0000ff"&gt;foreach&lt;/span&gt; (var url &lt;span style="color: #0000ff"&gt;in&lt;/span&gt; requestUrls){&lt;br /&gt;
&lt;br /&gt;
Console.WriteLine(&lt;span style="color: #006080"&gt;&amp;quot;\t{0} : {1} times &amp;quot;&lt;/span&gt;,&lt;br /&gt;
url.RequestUrl,&lt;br /&gt;
url.Count);&lt;br /&gt;
} 
&lt;br /&gt;
}&lt;/pre&gt;
&lt;br /&gt;
&lt;/div&gt;
&lt;p&gt;
This then would produce output like this:
&lt;/p&gt;
&lt;div style="border-bottom: silver 1px solid; text-align: left; border-left: silver 1px solid; padding-bottom: 4px; line-height: 12pt; background-color: #f4f4f4; margin: 20px 0px 10px; padding-left: 4px; width: 97.5%; padding-right: 4px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; font-size: 8pt; border-top: silver 1px solid; cursor: text; border-right: silver 1px solid; padding-top: 4px" id="codeSnippetWrapper"&gt;
&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px" id="codeSnippet"&gt;WebException  : 15 time(s)&lt;br /&gt;
http://localhost/menusample/default&lt;span style="color: #ff0000"&gt;.&lt;/span&gt;aspx : 11
times&lt;br /&gt;
http://localhost:63188/menusample/default&lt;span style="color: #ff0000"&gt;.&lt;/span&gt;aspx
: 4 times&lt;br /&gt;
InvalidOperationException : 7 time(s)&lt;br /&gt;
http://localhost:63188/menusample/default&lt;span style="color: #ff0000"&gt;.&lt;/span&gt;aspx
: 6 times&lt;br /&gt;
http://localhost/menusample/default&lt;span style="color: #ff0000"&gt;.&lt;/span&gt;aspx : 1 times&lt;br /&gt;
NotImplementedException : 2 time(s)&lt;br /&gt;
http://localhost/samplewebsiteerror/default&lt;span style="color: #ff0000"&gt;.&lt;/span&gt;aspx
: 2 times&lt;br /&gt;
InvalidCastException : 1 time(s)&lt;br /&gt;
http://localhost:63188/menusample/default&lt;span style="color: #ff0000"&gt;.&lt;/span&gt;aspx
: 1 times&lt;br /&gt;
MissingMethodException : 1 time(s)&lt;br /&gt;
http://localhost:63188/menusample/default&lt;span style="color: #ff0000"&gt;.&lt;/span&gt;aspx
: 1 times&lt;/pre&gt;
&lt;br /&gt;
&lt;/div&gt;
&lt;h4&gt;Query 3:&amp;#160; Exception Type, Request URL and Method Name Summary
&lt;/h4&gt;
&lt;p&gt;
You can even go deeper, if you so desire, to find out which of your methods threw
the most exceptions.&amp;#160; For this to work, we need to make a slight change to our
EventLogMessage class to parse the Stack Trace data into a class.&amp;#160; First, we’ll
start with our simple little StackTraceFrame class:
&lt;/p&gt;
&lt;div style="border-bottom: silver 1px solid; text-align: left; border-left: silver 1px solid; padding-bottom: 4px; line-height: 12pt; background-color: #f4f4f4; margin: 20px 0px 10px; padding-left: 4px; width: 97.5%; padding-right: 4px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; font-size: 8pt; border-top: silver 1px solid; cursor: text; border-right: silver 1px solid; padding-top: 4px" id="codeSnippetWrapper"&gt;
&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px" id="codeSnippet"&gt;&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;class&lt;/span&gt; StackTraceFrame&lt;br /&gt;
{&lt;br /&gt;
&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;string&lt;/span&gt; Method
{ get; set; }&lt;br /&gt;
&lt;br /&gt;
}&lt;/pre&gt;
&lt;br /&gt;
&lt;/div&gt;
&lt;p&gt;
Second, add a new property to our EventLogMessage class to hold a List&amp;lt;StackTraceFrame&amp;gt;:
&lt;/p&gt;
&lt;div style="border-bottom: silver 1px solid; text-align: left; border-left: silver 1px solid; padding-bottom: 4px; line-height: 12pt; background-color: #f4f4f4; margin: 20px 0px 10px; padding-left: 4px; width: 97.5%; padding-right: 4px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; font-size: 8pt; border-top: silver 1px solid; cursor: text; border-right: silver 1px solid; padding-top: 4px" id="codeSnippetWrapper"&gt;
&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px" id="codeSnippet"&gt;&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; List&amp;lt;StackTraceFrame&amp;gt;
StackTraceFrames { get; set; }&lt;/pre&gt;
&lt;br /&gt;
&lt;/div&gt;
&lt;p&gt;
Lastly, add a method (and its caller) to parse out the stack frames and assign the
resulting List to the StackTraceFrames property mentioned above:
&lt;/p&gt;
&lt;div style="border-bottom: silver 1px solid; text-align: left; border-left: silver 1px solid; padding-bottom: 4px; line-height: 12pt; background-color: #f4f4f4; margin: 20px 0px 10px; padding-left: 4px; width: 97.5%; padding-right: 4px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; font-size: 8pt; border-top: silver 1px solid; cursor: text; border-right: silver 1px solid; padding-top: 4px" id="codeSnippetWrapper"&gt;
&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px" id="codeSnippet"&gt;&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; EventLogMessage(&lt;span style="color: #0000ff"&gt;string&lt;/span&gt; rawMessageText)&lt;br /&gt;
{&lt;br /&gt;
Match myMatch = s_regex.Match(rawMessageText);&lt;br /&gt;
...&lt;br /&gt;
Stacktrace = myMatch.Groups[&lt;span style="color: #006080"&gt;&amp;quot;Stacktrace&amp;quot;&lt;/span&gt;].Value;&lt;br /&gt;
...&lt;br /&gt;
StackTraceFrames = ParseStackTrace(Stacktrace);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;span style="color: #0000ff"&gt;private&lt;/span&gt; List&amp;lt;StackTraceFrame&amp;gt; ParseStackTrace(&lt;span style="color: #0000ff"&gt;string&lt;/span&gt; stackTrace)&lt;br /&gt;
{&lt;br /&gt;
List&amp;lt;StackTraceFrame&amp;gt; frames = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; List&amp;lt;StackTraceFrame&amp;gt;();&lt;br /&gt;
&lt;span style="color: #0000ff"&gt;string&lt;/span&gt;[] stackTraceSplit = stackTrace.Split(&lt;span style="color: #0000ff"&gt;new&lt;/span&gt; &lt;span style="color: #0000ff"&gt;string&lt;/span&gt;[]
{ &lt;span style="color: #006080"&gt;&amp;quot; at &amp;quot;&lt;/span&gt; }, 
&lt;br /&gt;
StringSplitOptions.RemoveEmptyEntries);&lt;br /&gt;
&lt;span style="color: #0000ff"&gt;foreach&lt;/span&gt; (&lt;span style="color: #0000ff"&gt;string&lt;/span&gt; st &lt;span style="color: #0000ff"&gt;in&lt;/span&gt; stackTraceSplit)&lt;br /&gt;
{&lt;br /&gt;
&lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (!&lt;span style="color: #0000ff"&gt;string&lt;/span&gt;.IsNullOrEmpty(st))&lt;br /&gt;
{&lt;br /&gt;
frames.Add(&lt;span style="color: #0000ff"&gt;new&lt;/span&gt; StackTraceFrame() { Method = st
});&lt;br /&gt;
}&lt;br /&gt;
}&lt;br /&gt;
&lt;span style="color: #0000ff"&gt;return&lt;/span&gt; frames;&lt;br /&gt;
}&lt;/pre&gt;
&lt;br /&gt;
&lt;/div&gt;
&lt;blockquote&gt; 
&lt;p&gt;
&lt;em&gt;&lt;strong&gt;Please Note:&amp;#160; You could enhance the ParseStackTrace(…) method to
parse out the source files, line numbers, etc. I’ll leave this as an exercise for
you, dear reader.&lt;/strong&gt;&lt;/em&gt;
&lt;/p&gt;
&lt;/blockquote&gt; 
&lt;p&gt;
Now that we have the infrastructure in place, the query is just as simple.&amp;#160; We’ll
just nest this additional query inside of our URL query like so:
&lt;/p&gt;
&lt;div style="border-bottom: silver 1px solid; text-align: left; border-left: silver 1px solid; padding-bottom: 4px; line-height: 12pt; background-color: #f4f4f4; margin: 20px 0px 10px; padding-left: 4px; width: 97.5%; padding-right: 4px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; font-size: 8pt; border-top: silver 1px solid; cursor: text; border-right: silver 1px solid; padding-top: 4px" id="codeSnippetWrapper"&gt;
&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px" id="codeSnippet"&gt;&lt;span style="color: #0000ff"&gt;foreach&lt;/span&gt; (var
url &lt;span style="color: #0000ff"&gt;in&lt;/span&gt; requestUrls){&lt;br /&gt;
&lt;br /&gt;
Console.WriteLine(&lt;span style="color: #006080"&gt;&amp;quot;\t{0} : {1} times &amp;quot;&lt;/span&gt;,&lt;br /&gt;
url.RequestUrl,&lt;br /&gt;
url.Count);&lt;br /&gt;
&lt;br /&gt;
var methods = from method &lt;span style="color: #0000ff"&gt;in&lt;/span&gt; messages&lt;br /&gt;
&lt;span style="color: #0000ff"&gt;where&lt;/span&gt; &lt;span style="color: #0000ff"&gt;string&lt;/span&gt;.Equals(method.RequestURL, 
&lt;br /&gt;
url.RequestUrl, 
&lt;br /&gt;
StringComparison.InvariantCultureIgnoreCase) 
&lt;br /&gt;
&amp;amp;&amp;amp;&lt;br /&gt;
&lt;span style="color: #0000ff"&gt;string&lt;/span&gt;.Equals(method.Exceptiontype, 
&lt;br /&gt;
result.ExceptionType, 
&lt;br /&gt;
StringComparison.InvariantCultureIgnoreCase)&lt;br /&gt;
group method by method.StackTraceFrames[0].Method into mt&lt;br /&gt;
orderby mt.Count() descending, mt.Key&lt;br /&gt;
select &lt;span style="color: #0000ff"&gt;new&lt;/span&gt;
&lt;br /&gt;
{&lt;br /&gt;
MethodName = mt.Key,&lt;br /&gt;
Count = mt.Count()&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
&lt;span style="color: #0000ff"&gt;foreach&lt;/span&gt; (var method &lt;span style="color: #0000ff"&gt;in&lt;/span&gt; methods)&lt;br /&gt;
{&lt;br /&gt;
Console.WriteLine(&lt;span style="color: #006080"&gt;&amp;quot;\t\t{0} : {1} times &amp;quot;&lt;/span&gt;,&lt;br /&gt;
method.MethodName,&lt;br /&gt;
method.Count&lt;br /&gt;
);&lt;br /&gt;
}&lt;br /&gt;
} &lt;/pre&gt;
&lt;br /&gt;
&lt;/div&gt;
&lt;p&gt;
This would then produce output like the following:
&lt;/p&gt;
&lt;div style="border-bottom: silver 1px solid; text-align: left; border-left: silver 1px solid; padding-bottom: 4px; line-height: 12pt; background-color: #f4f4f4; margin: 20px 0px 10px; padding-left: 4px; width: 97.5%; padding-right: 4px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; font-size: 8pt; border-top: silver 1px solid; cursor: text; border-right: silver 1px solid; padding-top: 4px" id="codeSnippetWrapper"&gt;
&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px" id="codeSnippet"&gt;WebException  : 15 time(s)&lt;br /&gt;
http://localhost/menusample/default.aspx : 11 times&lt;br /&gt;
System.Net.HttpWebRequest.GetResponse() : 11 times&lt;br /&gt;
http://localhost:63188/menusample/default.aspx : 4 times&lt;br /&gt;
System.Net.HttpWebRequest.GetResponse() : 4 times&lt;br /&gt;
InvalidOperationException : 7 time(s)&lt;br /&gt;
http://localhost:63188/menusample/default.aspx : 6 times&lt;br /&gt;
System.Web.UI.WebControls.Menu... : 6 times&lt;br /&gt;
http://localhost/menusample/default.aspx : 1 times&lt;br /&gt;
System.Web.UI.WebControls.Menu... : 1 times&lt;/pre&gt;
&lt;br /&gt;
&lt;/div&gt;
&lt;p&gt;
One last thing you may notice is that the in the example above, the first frame for
each of those exceptions are somewhere in the bowels of the .NET BCL.&amp;#160; You may
want to filter this out even further to only return &lt;strong&gt;YOUR &lt;/strong&gt;method.&amp;#160;
This can be accomplished very easily with the method below.&amp;#160; It will simply loop
through the StackTraceFrame List and return the first method it encounters that does
not start with “System.” or “Microsoft.”.
&lt;/p&gt;
&lt;div style="border-bottom: silver 1px solid; text-align: left; border-left: silver 1px solid; padding-bottom: 4px; line-height: 12pt; background-color: #f4f4f4; margin: 20px 0px 10px; padding-left: 4px; width: 97.5%; padding-right: 4px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; font-size: 8pt; border-top: silver 1px solid; cursor: text; border-right: silver 1px solid; padding-top: 4px" id="codeSnippetWrapper"&gt;
&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px" id="codeSnippet"&gt;&lt;span style="color: #0000ff"&gt;private&lt;/span&gt; &lt;span style="color: #0000ff"&gt;static&lt;/span&gt; &lt;span style="color: #0000ff"&gt;string&lt;/span&gt; GetMyMethod(List&amp;lt;StackTraceFrame&amp;gt;
frames)&lt;br /&gt;
{&lt;br /&gt;
&lt;br /&gt;
&lt;span style="color: #0000ff"&gt;foreach&lt;/span&gt; (StackTraceFrame frame &lt;span style="color: #0000ff"&gt;in&lt;/span&gt; frames)&lt;br /&gt;
{&lt;br /&gt;
&lt;br /&gt;
&lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (!frame.Method.StartsWith(&lt;span style="color: #006080"&gt;&amp;quot;System.&amp;quot;&lt;/span&gt;)
&amp;amp;&amp;amp;&lt;br /&gt;
!frame.Method.StartsWith(&lt;span style="color: #006080"&gt;&amp;quot;Microsoft.&amp;quot;&lt;/span&gt;))&lt;br /&gt;
&lt;span style="color: #0000ff"&gt;return&lt;/span&gt; frame.Method;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;span style="color: #0000ff"&gt;return&lt;/span&gt; &lt;span style="color: #006080"&gt;&amp;quot;No User
Code detected.&amp;quot;&lt;/span&gt;;&lt;br /&gt;
}&lt;/pre&gt;
&lt;br /&gt;
&lt;/div&gt;
&lt;p&gt;
Then, you can just call that method from the new query we wrote above:
&lt;/p&gt;
&lt;div style="border-bottom: silver 1px solid; text-align: left; border-left: silver 1px solid; padding-bottom: 4px; line-height: 12pt; background-color: #f4f4f4; margin: 20px 0px 10px; padding-left: 4px; width: 97.5%; padding-right: 4px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; font-size: 8pt; border-top: silver 1px solid; cursor: text; border-right: silver 1px solid; padding-top: 4px" id="codeSnippetWrapper"&gt;
&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px" id="codeSnippet"&gt;var methods = from method &lt;span style="color: #0000ff"&gt;in&lt;/span&gt; messages&lt;br /&gt;
&lt;span style="color: #0000ff"&gt;where&lt;/span&gt; ...&lt;br /&gt;
group method by 
&lt;br /&gt;
GetMyMethod(method.StackTraceFrames) into mt&lt;br /&gt;
...&lt;/pre&gt;
&lt;br /&gt;
&lt;/div&gt;
&lt;p&gt;
Finally, with this new snippet in place, we’ll get output like this:
&lt;/p&gt;
&lt;div style="border-bottom: silver 1px solid; text-align: left; border-left: silver 1px solid; padding-bottom: 4px; line-height: 12pt; background-color: #f4f4f4; margin: 20px 0px 10px; padding-left: 4px; width: 97.5%; padding-right: 4px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; font-size: 8pt; border-top: silver 1px solid; cursor: text; border-right: silver 1px solid; padding-top: 4px" id="codeSnippetWrapper"&gt;
&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px" id="codeSnippet"&gt;WebException  : 15 time(s)&lt;br /&gt;
http://localhost/menusample/default.aspx : 11 times&lt;br /&gt;
_Default.Page_Load(Object sender, EventArgs e)...: 8 times&lt;br /&gt;
No User Code detected. : 3 times&lt;br /&gt;
&lt;br /&gt;
http://localhost:63188/menusample/default.aspx : 4 times&lt;br /&gt;
_Default.Page_Load(Object sender, EventArgs e)... : 1 times&lt;br /&gt;
No User Code detected. : 1 times&lt;br /&gt;
WebControls.CustomXmlHierarchicalDataSourceView.Select()... : 2 times&lt;/pre&gt;
&lt;br /&gt;
&lt;/div&gt;
&lt;p&gt;
As you can see, the sky’s the limit.
&lt;/p&gt;
&lt;p&gt;
Enjoy!
&lt;/p&gt;</description>
      <comments>http://www.samuraiprogrammer.com/blog/CommentView,guid,a06708f7-9f9b-4ea2-8844-b13dad549af5.aspx</comments>
      <category>ASP.NET</category>
      <category>Best Practice</category>
      <category>Development</category>
    </item>
    <item>
      <trackback:ping>http://www.samuraiprogrammer.com/blog/Trackback.aspx?guid=9d87b777-0aac-438c-9b47-91e479fea03a</trackback:ping>
      <pingback:server>http://www.samuraiprogrammer.com/blog/pingback.aspx</pingback:server>
      <pingback:target>http://www.samuraiprogrammer.com/blog/PermaLink,guid,9d87b777-0aac-438c-9b47-91e479fea03a.aspx</pingback:target>
      <dc:creator>Greg Varveris</dc:creator>
      <wfw:comment>http://www.samuraiprogrammer.com/blog/CommentView,guid,9d87b777-0aac-438c-9b47-91e479fea03a.aspx</wfw:comment>
      <wfw:commentRss>http://www.samuraiprogrammer.com/blog/SyndicationService.asmx/GetEntryCommentsRss?guid=9d87b777-0aac-438c-9b47-91e479fea03a</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
          <a href="http://www.samuraiprogrammer.com/blog/content/binary/WindowsLiveWriter/Microoptimizationorjustgoodcodingpractic_DBB8/cheetah_2.jpg">
            <img style="border-right-width: 0px; margin: 10px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="cheetah" border="0" alt="cheetah" align="left" src="http://www.samuraiprogrammer.com/blog/content/binary/WindowsLiveWriter/Microoptimizationorjustgoodcodingpractic_DBB8/cheetah_thumb.jpg" width="244" height="184" />
          </a> This
is a common topic and I thought I’d write up some thoughts I have on it.  In-fact,
I was just working with a customer on improving their code reviews and what they should
be checking for and the question arose - “Should performance be targeted during a
code review?”  It’s an interesting question.  I’m a big fan of performance
testing early and often and not waiting until the end of a dev cycle but code reviews,
IMO, should focus on logic, maintainability and best practices.  I may be in
the minority and if you look around the web, you’ll see varying opinions on the topic.  <a href="http://msdn.microsoft.com/en-us/library/ff647802.aspx" target="_blank">For
example, one of the PAG articles states</a>:
</p>
        <blockquote>
          <p>
“Code reviews should be a regular part of your development process. Performance and
scalability code reviews focus on identifying coding techniques and design choices
that could lead to performance and scalability issues. The review goal is to identify
potential performance and scalability issues before the code is deployed. The cost
and effort of fixing performance and scalability flaws at development time is far
less than fixing them later in the product deployment cycle.
</p>
          <p>
Avoid performance code reviews too early in the coding phase because this can restrict
your design options. Also, bear in mind that that performance decisions often involve
tradeoffs. For example, it is easy to reduce maintainability and flexibility while
striving to optimize code.”
</p>
        </blockquote>
        <p>
As I mentioned above, I am a huge proponent of performance analysis and optimization
many times throughout a typical product development cycle.  I can say with a
fair amount of certainty that if you don’t build performance reviews into your project
plan at regular intervals, you will hit some problem (or multiple problems) in production
and have to refactor some code.  
</p>
        <p>
Circling back to the original question, though, are code reviews the place for performance
analysis?  Typically, I’d recommend using them to squash little bits of bad code
but maintainability and code-cleanliness should be first and foremost in your minds. 
That said, if you see a pattern that <strong>you know </strong>can be improved, by
all means bring it up.  What’s an example of that type of situation?  
</p>
        <p>
Let’s take a look at predicates, <a href="http://msdn.microsoft.com/en-us/library/x0b5b5bc.aspx" target="_blank">specifically
their usage in the Find method of a List&lt;T&gt;</a>.  If you’re not aware,
the Find() method performs a linear search through all of the items until it finds
the first match – then it returns.  This makes it a O(n) operation where “n”
is the number of items in the list.  Basically, this means that the more items
you have in the list, the longer a Find() operation can potentially take.  So,
if we slam about 10,000 elements into a list:
</p>
        <div style="border-bottom: silver 1px solid; text-align: left; border-left: silver 1px solid; padding-bottom: 4px; line-height: 12pt; background-color: #f4f4f4; margin: 20px 0px 10px; padding-left: 4px; width: 97.5%; padding-right: 4px; font-family: 'Courier New', courier, monospace; direction: ltr; font-size: 8pt; border-top: silver 1px solid; cursor: text; border-right: silver 1px solid; padding-top: 4px" id="codeSnippetWrapper">
          <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px" id="codeSnippet">
            <span style="color: #0000ff">private</span>
            <span style="color: #0000ff">static</span> List&lt;Data&gt;
LoadList()<br />
{<br />
List&lt;Data&gt; myList = <span style="color: #0000ff">new</span> List&lt;Data&gt;();<br /><span style="color: #0000ff">for</span> (<span style="color: #0000ff">int</span> i
= 0; i &lt; 10000; i++)<br />
{<br />
myList.Add(<span style="color: #0000ff">new</span> Data() { Id = <span style="color: #006080">"Id"</span> +
i.ToString(), 
<br />
Value = <span style="color: #006080">"Value"</span> + i.ToString() });<br />
}<br /><br /><span style="color: #0000ff">return</span> myList;<br />
}</pre>
          <br />
        </div>
        <p>
Then, if someone wants to return the instance of the Data class that contains an Id
of say “Id10000”, they might write the following code:
</p>
        <div style="border-bottom: silver 1px solid; text-align: left; border-left: silver 1px solid; padding-bottom: 4px; line-height: 12pt; background-color: #f4f4f4; margin: 20px 0px 10px; padding-left: 4px; width: 97.5%; padding-right: 4px; font-family: 'Courier New', courier, monospace; direction: ltr; font-size: 8pt; border-top: silver 1px solid; cursor: text; border-right: silver 1px solid; padding-top: 4px" id="codeSnippetWrapper">
          <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px" id="codeSnippet">
            <span style="color: #0000ff">static</span> Data
Find1(List&lt;Data&gt; myList, <span style="color: #0000ff">string</span> idToFind)<br />
{<br />
Data data = myList.Find(s =&gt; 
<br />
s.Id.ToLower() == 
<br />
idToFind.ToLower());<br /><br /><span style="color: #0000ff">return</span> data;<br />
}</pre>
          <br />
        </div>
        <p>
Now, keep in mind that the predicate is executed for each element in the List&lt;T&gt;
until it finds the instance you care about.  With that in mind, we would probably
want to refactor out the “idToFind.ToLower()” above the predicate since that value
isn’t changing.  So, you might end-up with something like this:
</p>
        <div style="border-bottom: silver 1px solid; text-align: left; border-left: silver 1px solid; padding-bottom: 4px; line-height: 12pt; background-color: #f4f4f4; margin: 20px 0px 10px; padding-left: 4px; width: 97.5%; padding-right: 4px; font-family: 'Courier New', courier, monospace; direction: ltr; font-size: 8pt; border-top: silver 1px solid; cursor: text; border-right: silver 1px solid; padding-top: 4px" id="codeSnippetWrapper">
          <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px" id="codeSnippet">
            <span style="color: #0000ff">static</span> Data
Find2(List&lt;Data&gt; myList, <span style="color: #0000ff">string</span> idToFind)<br />
{<br /><br />
idToFind = idToFind.ToLower();<br /><br />
Data data = myList.Find(s =&gt; 
<br />
s.Id.ToLower() == 
<br />
idToFind);<br /><br /><span style="color: #0000ff">return</span> data;<br />
}</pre>
          <br />
        </div>
        <p>
Another route you may want to go is just to use the string.Equals(…) method to perform
the comparison.  That would look like:
</p>
        <div style="border-bottom: silver 1px solid; text-align: left; border-left: silver 1px solid; padding-bottom: 4px; line-height: 12pt; background-color: #f4f4f4; margin: 20px 0px 10px; padding-left: 4px; width: 97.5%; padding-right: 4px; font-family: 'Courier New', courier, monospace; direction: ltr; font-size: 8pt; border-top: silver 1px solid; cursor: text; border-right: silver 1px solid; padding-top: 4px" id="codeSnippetWrapper">
          <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px" id="codeSnippet">
            <span style="color: #0000ff">static</span> Data
Find3(List&lt;Data&gt; myList, <span style="color: #0000ff">string</span> idToFind)<br />
{<br /><br />
Data data = myList.Find(s =&gt; 
<br /><span style="color: #0000ff">string</span>.Equals(<br />
s.Id, 
<br />
idToFind, 
<br />
StringComparison.<br />
InvariantCultureIgnoreCase)<br />
);<br /><br /><span style="color: #0000ff">return</span> data;<br /><br />
}</pre>
          <br />
        </div>
        <p>
Fact is, the last method <strong>IS</strong> the fastest way to perform the operation. 
I can say that without even needing to run it through a profiler.  But if you
don’t believe me…   <span style="widows: 2; text-transform: none; text-indent: 0px; border-collapse: separate; font: 14pt arial; white-space: normal; orphans: 2; letter-spacing: normal; color: rgb(0,0,0); word-spacing: 0px; -webkit-border-horizontal-spacing: 0px; -webkit-border-vertical-spacing: 0px; -webkit-text-decorations-in-effect: none; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px"></span></p>
        <p>
          <table style="border-bottom-style: none; border-right-style: none; border-collapse: collapse; border-top-style: none; font-size: 14pt; border-left-style: none" border="0" cellspacing="0" cellpadding="0">
            <tbody>
              <tr>
                <td style="border-bottom: rgb(0,0,0) 0px solid; border-left: rgb(51,51,153) 1px solid; border-top: rgb(51,51,153) 1px solid; border-right: rgb(0,0,0) 0px solid" bgcolor="#000000" height="29" width="406">
                  <div style="text-indent: 0pt">
                    <span style="font-family: calibri; color: rgb(255,255,255); font-size: 11pt">
                      <b>Function
Name</b>
                    </span>
                  </div>
                </td>
                <td style="border-bottom: rgb(0,0,0) 0px solid; border-left: rgb(0,0,0) 0px solid; border-top: rgb(51,51,153) 1px solid; border-right: rgb(51,51,153) 1px solid" bgcolor="#000000" width="175">
                  <div style="text-indent: 0pt">
                    <span style="font-family: calibri; color: rgb(255,255,255); font-size: 11pt">
                      <b>Elapsed</b>
                    </span>
                  </div>
                  <div style="text-indent: 0pt">
                    <span style="font-family: calibri; color: rgb(255,255,255); font-size: 11pt">
                      <b>Inclusive
Time</b>
                    </span>
                  </div>
                </td>
              </tr>
              <tr>
                <td style="border-bottom: rgb(0,0,0) 0px solid; border-left: rgb(51,51,153) 1px solid; border-top: rgb(51,51,153) 1px solid; border-right: rgb(0,0,0) 0px solid" height="14" width="406">
                  <div style="text-indent: 0pt">
                    <span style="font-family: calibri; color: rgb(0,0,0); font-size: 11pt">...Find1(System.Collections.Generic.List`1&lt;....Data&gt;,string)</span>
                  </div>
                </td>
                <td style="border-bottom: rgb(0,0,0) 0px solid; border-left: rgb(0,0,0) 0px solid; border-top: rgb(51,51,153) 1px solid; border-right: rgb(51,51,153) 1px solid" width="175">
                  <div style="text-indent: 0pt" align="right">
                    <span style="font-family: calibri; color: rgb(0,0,0); font-size: 11pt">6.34</span>
                  </div>
                </td>
              </tr>
              <tr>
                <td style="border-bottom: rgb(0,0,0) 0px solid; border-left: rgb(51,51,153) 1px solid; border-top: rgb(51,51,153) 1px solid; border-right: rgb(0,0,0) 0px solid" height="14" width="406">
                  <div style="text-indent: 0pt">
                    <span style="font-family: calibri; color: rgb(0,0,0); font-size: 11pt">...Find2(System.Collections.Generic.List`1&lt;....Data&gt;,string)</span>
                  </div>
                </td>
                <td style="border-bottom: rgb(0,0,0) 0px solid; border-left: rgb(0,0,0) 0px solid; border-top: rgb(51,51,153) 1px solid; border-right: rgb(51,51,153) 1px solid" width="175">
                  <div style="text-indent: 0pt" align="right">
                    <span style="font-family: calibri; color: rgb(0,0,0); font-size: 11pt">4.47</span>
                  </div>
                </td>
              </tr>
              <tr>
                <td style="border-bottom: rgb(51,51,153) 1px solid; border-left: rgb(51,51,153) 1px solid; border-top: rgb(51,51,153) 1px solid; border-right: rgb(0,0,0) 0px solid" height="14" width="406">
                  <div style="text-indent: 0pt">
                    <span style="font-family: calibri; color: rgb(0,0,0); font-size: 11pt">...Find3(System.Collections.Generic.List`1&lt;....Data&gt;,string)</span>
                  </div>
                </td>
                <td style="border-bottom: rgb(51,51,153) 1px solid; border-left: rgb(0,0,0) 0px solid; border-top: rgb(51,51,153) 1px solid; border-right: rgb(51,51,153) 1px solid" width="175">
                  <div style="text-indent: 0pt" align="right">
                    <span style="font-family: calibri; color: rgb(0,0,0); font-size: 11pt">3.65</span>
                  </div>
                </td>
              </tr>
            </tbody>
          </table>
        </p>
        <div>That’s something I might put into the category of a micro-optimization AND just
good coding practice.  But is this something that should be caught during a code
review?  I’d say “yes” because logically it all makes sense and none of the solutions
would really hurt maintainability or readability of the code.
</div>
        <div> 
</div>
        <div>So, I’d tag this as a good coding practice.  Other thoughts on the topic?
</div>
        <div> 
</div>
        <div>Enjoy!
</div>
        <div>
        </div>
      </body>
      <title>Micro optimization or just good coding practice?</title>
      <guid isPermaLink="false">http://www.samuraiprogrammer.com/blog/PermaLink,guid,9d87b777-0aac-438c-9b47-91e479fea03a.aspx</guid>
      <link>http://www.samuraiprogrammer.com/blog/2010/08/21/MicroOptimizationOrJustGoodCodingPractice.aspx</link>
      <pubDate>Sat, 21 Aug 2010 04:36:27 GMT</pubDate>
      <description>&lt;p&gt;
&lt;a href="http://www.samuraiprogrammer.com/blog/content/binary/WindowsLiveWriter/Microoptimizationorjustgoodcodingpractic_DBB8/cheetah_2.jpg"&gt;&lt;img style="border-right-width: 0px; margin: 10px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="cheetah" border="0" alt="cheetah" align="left" src="http://www.samuraiprogrammer.com/blog/content/binary/WindowsLiveWriter/Microoptimizationorjustgoodcodingpractic_DBB8/cheetah_thumb.jpg" width="244" height="184" /&gt;&lt;/a&gt; This
is a common topic and I thought I’d write up some thoughts I have on it.&amp;#160; In-fact,
I was just working with a customer on improving their code reviews and what they should
be checking for and the question arose - “Should performance be targeted during a
code review?”&amp;#160; It’s an interesting question.&amp;#160; I’m a big fan of performance
testing early and often and not waiting until the end of a dev cycle but code reviews,
IMO, should focus on logic, maintainability and best practices.&amp;#160; I may be in
the minority and if you look around the web, you’ll see varying opinions on the topic.&amp;#160; &lt;a href="http://msdn.microsoft.com/en-us/library/ff647802.aspx" target="_blank"&gt;For
example, one of the PAG articles states&lt;/a&gt;:
&lt;/p&gt;
&lt;blockquote&gt; 
&lt;p&gt;
“Code reviews should be a regular part of your development process. Performance and
scalability code reviews focus on identifying coding techniques and design choices
that could lead to performance and scalability issues. The review goal is to identify
potential performance and scalability issues before the code is deployed. The cost
and effort of fixing performance and scalability flaws at development time is far
less than fixing them later in the product deployment cycle.
&lt;/p&gt;
&lt;p&gt;
Avoid performance code reviews too early in the coding phase because this can restrict
your design options. Also, bear in mind that that performance decisions often involve
tradeoffs. For example, it is easy to reduce maintainability and flexibility while
striving to optimize code.”
&lt;/p&gt;
&lt;/blockquote&gt; 
&lt;p&gt;
As I mentioned above, I am a huge proponent of performance analysis and optimization
many times throughout a typical product development cycle.&amp;#160; I can say with a
fair amount of certainty that if you don’t build performance reviews into your project
plan at regular intervals, you will hit some problem (or multiple problems) in production
and have to refactor some code.&amp;#160; 
&lt;/p&gt;
&lt;p&gt;
Circling back to the original question, though, are code reviews the place for performance
analysis?&amp;#160; Typically, I’d recommend using them to squash little bits of bad code
but maintainability and code-cleanliness should be first and foremost in your minds.&amp;#160;
That said, if you see a pattern that &lt;strong&gt;you know &lt;/strong&gt;can be improved, by
all means bring it up.&amp;#160; What’s an example of that type of situation?&amp;#160; 
&lt;/p&gt;
&lt;p&gt;
Let’s take a look at predicates, &lt;a href="http://msdn.microsoft.com/en-us/library/x0b5b5bc.aspx" target="_blank"&gt;specifically
their usage in the Find method of a List&amp;lt;T&amp;gt;&lt;/a&gt;.&amp;#160; If you’re not aware,
the Find() method performs a linear search through all of the items until it finds
the first match – then it returns.&amp;#160; This makes it a O(n) operation where “n”
is the number of items in the list.&amp;#160; Basically, this means that the more items
you have in the list, the longer a Find() operation can potentially take.&amp;#160; So,
if we slam about 10,000 elements into a list:
&lt;/p&gt;
&lt;div style="border-bottom: silver 1px solid; text-align: left; border-left: silver 1px solid; padding-bottom: 4px; line-height: 12pt; background-color: #f4f4f4; margin: 20px 0px 10px; padding-left: 4px; width: 97.5%; padding-right: 4px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; font-size: 8pt; border-top: silver 1px solid; cursor: text; border-right: silver 1px solid; padding-top: 4px" id="codeSnippetWrapper"&gt;
&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px" id="codeSnippet"&gt;&lt;span style="color: #0000ff"&gt;private&lt;/span&gt; &lt;span style="color: #0000ff"&gt;static&lt;/span&gt; List&amp;lt;Data&amp;gt;
LoadList()&lt;br /&gt;
{&lt;br /&gt;
List&amp;lt;Data&amp;gt; myList = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; List&amp;lt;Data&amp;gt;();&lt;br /&gt;
&lt;span style="color: #0000ff"&gt;for&lt;/span&gt; (&lt;span style="color: #0000ff"&gt;int&lt;/span&gt; i
= 0; i &amp;lt; 10000; i++)&lt;br /&gt;
{&lt;br /&gt;
myList.Add(&lt;span style="color: #0000ff"&gt;new&lt;/span&gt; Data() { Id = &lt;span style="color: #006080"&gt;&amp;quot;Id&amp;quot;&lt;/span&gt; +
i.ToString(), 
&lt;br /&gt;
Value = &lt;span style="color: #006080"&gt;&amp;quot;Value&amp;quot;&lt;/span&gt; + i.ToString() });&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;span style="color: #0000ff"&gt;return&lt;/span&gt; myList;&lt;br /&gt;
}&lt;/pre&gt;
&lt;br /&gt;
&lt;/div&gt;
&lt;p&gt;
Then, if someone wants to return the instance of the Data class that contains an Id
of say “Id10000”, they might write the following code:
&lt;/p&gt;
&lt;div style="border-bottom: silver 1px solid; text-align: left; border-left: silver 1px solid; padding-bottom: 4px; line-height: 12pt; background-color: #f4f4f4; margin: 20px 0px 10px; padding-left: 4px; width: 97.5%; padding-right: 4px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; font-size: 8pt; border-top: silver 1px solid; cursor: text; border-right: silver 1px solid; padding-top: 4px" id="codeSnippetWrapper"&gt;
&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px" id="codeSnippet"&gt;&lt;span style="color: #0000ff"&gt;static&lt;/span&gt; Data
Find1(List&amp;lt;Data&amp;gt; myList, &lt;span style="color: #0000ff"&gt;string&lt;/span&gt; idToFind)&lt;br /&gt;
{&lt;br /&gt;
Data data = myList.Find(s =&amp;gt; 
&lt;br /&gt;
s.Id.ToLower() == 
&lt;br /&gt;
idToFind.ToLower());&lt;br /&gt;
&lt;br /&gt;
&lt;span style="color: #0000ff"&gt;return&lt;/span&gt; data;&lt;br /&gt;
}&lt;/pre&gt;
&lt;br /&gt;
&lt;/div&gt;
&lt;p&gt;
Now, keep in mind that the predicate is executed for each element in the List&amp;lt;T&amp;gt;
until it finds the instance you care about.&amp;#160; With that in mind, we would probably
want to refactor out the “idToFind.ToLower()” above the predicate since that value
isn’t changing.&amp;#160; So, you might end-up with something like this:
&lt;/p&gt;
&lt;div style="border-bottom: silver 1px solid; text-align: left; border-left: silver 1px solid; padding-bottom: 4px; line-height: 12pt; background-color: #f4f4f4; margin: 20px 0px 10px; padding-left: 4px; width: 97.5%; padding-right: 4px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; font-size: 8pt; border-top: silver 1px solid; cursor: text; border-right: silver 1px solid; padding-top: 4px" id="codeSnippetWrapper"&gt;
&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px" id="codeSnippet"&gt;&lt;span style="color: #0000ff"&gt;static&lt;/span&gt; Data
Find2(List&amp;lt;Data&amp;gt; myList, &lt;span style="color: #0000ff"&gt;string&lt;/span&gt; idToFind)&lt;br /&gt;
{&lt;br /&gt;
&lt;br /&gt;
idToFind = idToFind.ToLower();&lt;br /&gt;
&lt;br /&gt;
Data data = myList.Find(s =&amp;gt; 
&lt;br /&gt;
s.Id.ToLower() == 
&lt;br /&gt;
idToFind);&lt;br /&gt;
&lt;br /&gt;
&lt;span style="color: #0000ff"&gt;return&lt;/span&gt; data;&lt;br /&gt;
}&lt;/pre&gt;
&lt;br /&gt;
&lt;/div&gt;
&lt;p&gt;
Another route you may want to go is just to use the string.Equals(…) method to perform
the comparison.&amp;#160; That would look like:
&lt;/p&gt;
&lt;div style="border-bottom: silver 1px solid; text-align: left; border-left: silver 1px solid; padding-bottom: 4px; line-height: 12pt; background-color: #f4f4f4; margin: 20px 0px 10px; padding-left: 4px; width: 97.5%; padding-right: 4px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; font-size: 8pt; border-top: silver 1px solid; cursor: text; border-right: silver 1px solid; padding-top: 4px" id="codeSnippetWrapper"&gt;
&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px" id="codeSnippet"&gt;&lt;span style="color: #0000ff"&gt;static&lt;/span&gt; Data
Find3(List&amp;lt;Data&amp;gt; myList, &lt;span style="color: #0000ff"&gt;string&lt;/span&gt; idToFind)&lt;br /&gt;
{&lt;br /&gt;
&lt;br /&gt;
Data data = myList.Find(s =&amp;gt; 
&lt;br /&gt;
&lt;span style="color: #0000ff"&gt;string&lt;/span&gt;.Equals(&lt;br /&gt;
s.Id, 
&lt;br /&gt;
idToFind, 
&lt;br /&gt;
StringComparison.&lt;br /&gt;
InvariantCultureIgnoreCase)&lt;br /&gt;
);&lt;br /&gt;
&lt;br /&gt;
&lt;span style="color: #0000ff"&gt;return&lt;/span&gt; data;&lt;br /&gt;
&lt;br /&gt;
}&lt;/pre&gt;
&lt;br /&gt;
&lt;/div&gt;
&lt;p&gt;
Fact is, the last method &lt;strong&gt;IS&lt;/strong&gt; the fastest way to perform the operation.&amp;#160;
I can say that without even needing to run it through a profiler.&amp;#160; But if you
don’t believe me…&amp;#160;&amp;#160; &lt;span style="widows: 2; text-transform: none; text-indent: 0px; border-collapse: separate; font: 14pt arial; white-space: normal; orphans: 2; letter-spacing: normal; color: rgb(0,0,0); word-spacing: 0px; -webkit-border-horizontal-spacing: 0px; -webkit-border-vertical-spacing: 0px; -webkit-text-decorations-in-effect: none; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px"&gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;table style="border-bottom-style: none; border-right-style: none; border-collapse: collapse; border-top-style: none; font-size: 14pt; border-left-style: none" border="0" cellspacing="0" cellpadding="0"&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style="border-bottom: rgb(0,0,0) 0px solid; border-left: rgb(51,51,153) 1px solid; border-top: rgb(51,51,153) 1px solid; border-right: rgb(0,0,0) 0px solid" bgcolor="#000000" height="29" width="406"&gt;
&lt;div style="text-indent: 0pt"&gt;&lt;span style="font-family: calibri; color: rgb(255,255,255); font-size: 11pt"&gt;&lt;b&gt;Function
Name&lt;/b&gt;&lt;/span&gt;
&lt;/div&gt;
&lt;/td&gt;
&lt;td style="border-bottom: rgb(0,0,0) 0px solid; border-left: rgb(0,0,0) 0px solid; border-top: rgb(51,51,153) 1px solid; border-right: rgb(51,51,153) 1px solid" bgcolor="#000000" width="175"&gt;
&lt;div style="text-indent: 0pt"&gt;&lt;span style="font-family: calibri; color: rgb(255,255,255); font-size: 11pt"&gt;&lt;b&gt;Elapsed&lt;/b&gt;&lt;/span&gt;
&lt;/div&gt;
&lt;div style="text-indent: 0pt"&gt;&lt;span style="font-family: calibri; color: rgb(255,255,255); font-size: 11pt"&gt;&lt;b&gt;Inclusive
Time&lt;/b&gt;&lt;/span&gt;
&lt;/div&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="border-bottom: rgb(0,0,0) 0px solid; border-left: rgb(51,51,153) 1px solid; border-top: rgb(51,51,153) 1px solid; border-right: rgb(0,0,0) 0px solid" height="14" width="406"&gt;
&lt;div style="text-indent: 0pt"&gt;&lt;span style="font-family: calibri; color: rgb(0,0,0); font-size: 11pt"&gt;...Find1(System.Collections.Generic.List`1&amp;lt;....Data&amp;gt;,string)&lt;/span&gt;
&lt;/div&gt;
&lt;/td&gt;
&lt;td style="border-bottom: rgb(0,0,0) 0px solid; border-left: rgb(0,0,0) 0px solid; border-top: rgb(51,51,153) 1px solid; border-right: rgb(51,51,153) 1px solid" width="175"&gt;
&lt;div style="text-indent: 0pt" align="right"&gt;&lt;span style="font-family: calibri; color: rgb(0,0,0); font-size: 11pt"&gt;6.34&lt;/span&gt;
&lt;/div&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="border-bottom: rgb(0,0,0) 0px solid; border-left: rgb(51,51,153) 1px solid; border-top: rgb(51,51,153) 1px solid; border-right: rgb(0,0,0) 0px solid" height="14" width="406"&gt;
&lt;div style="text-indent: 0pt"&gt;&lt;span style="font-family: calibri; color: rgb(0,0,0); font-size: 11pt"&gt;...Find2(System.Collections.Generic.List`1&amp;lt;....Data&amp;gt;,string)&lt;/span&gt;
&lt;/div&gt;
&lt;/td&gt;
&lt;td style="border-bottom: rgb(0,0,0) 0px solid; border-left: rgb(0,0,0) 0px solid; border-top: rgb(51,51,153) 1px solid; border-right: rgb(51,51,153) 1px solid" width="175"&gt;
&lt;div style="text-indent: 0pt" align="right"&gt;&lt;span style="font-family: calibri; color: rgb(0,0,0); font-size: 11pt"&gt;4.47&lt;/span&gt;
&lt;/div&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="border-bottom: rgb(51,51,153) 1px solid; border-left: rgb(51,51,153) 1px solid; border-top: rgb(51,51,153) 1px solid; border-right: rgb(0,0,0) 0px solid" height="14" width="406"&gt;
&lt;div style="text-indent: 0pt"&gt;&lt;span style="font-family: calibri; color: rgb(0,0,0); font-size: 11pt"&gt;...Find3(System.Collections.Generic.List`1&amp;lt;....Data&amp;gt;,string)&lt;/span&gt;
&lt;/div&gt;
&lt;/td&gt;
&lt;td style="border-bottom: rgb(51,51,153) 1px solid; border-left: rgb(0,0,0) 0px solid; border-top: rgb(51,51,153) 1px solid; border-right: rgb(51,51,153) 1px solid" width="175"&gt;
&lt;div style="text-indent: 0pt" align="right"&gt;&lt;span style="font-family: calibri; color: rgb(0,0,0); font-size: 11pt"&gt;3.65&lt;/span&gt;
&lt;/div&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/p&gt;
&lt;div&gt;That’s something I might put into the category of a micro-optimization AND just
good coding practice.&amp;#160; But is this something that should be caught during a code
review?&amp;#160; I’d say “yes” because logically it all makes sense and none of the solutions
would really hurt maintainability or readability of the code.
&lt;/div&gt;
&lt;div&gt;&amp;#160;
&lt;/div&gt;
&lt;div&gt;So, I’d tag this as a good coding practice.&amp;#160; Other thoughts on the topic?
&lt;/div&gt;
&lt;div&gt;&amp;#160;
&lt;/div&gt;
&lt;div&gt;Enjoy!
&lt;/div&gt;
&lt;div&gt;
&lt;/div&gt;</description>
      <comments>http://www.samuraiprogrammer.com/blog/CommentView,guid,9d87b777-0aac-438c-9b47-91e479fea03a.aspx</comments>
      <category>.NET</category>
      <category>Best Practice</category>
      <category>C#</category>
      <category>Code Reviews</category>
      <category>Development</category>
      <category>Performance</category>
    </item>
    <item>
      <trackback:ping>http://www.samuraiprogrammer.com/blog/Trackback.aspx?guid=6ccebde8-c9fb-430d-8b4b-c10636b94835</trackback:ping>
      <pingback:server>http://www.samuraiprogrammer.com/blog/pingback.aspx</pingback:server>
      <pingback:target>http://www.samuraiprogrammer.com/blog/PermaLink,guid,6ccebde8-c9fb-430d-8b4b-c10636b94835.aspx</pingback:target>
      <dc:creator>Greg Varveris</dc:creator>
      <wfw:comment>http://www.samuraiprogrammer.com/blog/CommentView,guid,6ccebde8-c9fb-430d-8b4b-c10636b94835.aspx</wfw:comment>
      <wfw:commentRss>http://www.samuraiprogrammer.com/blog/SyndicationService.asmx/GetEntryCommentsRss?guid=6ccebde8-c9fb-430d-8b4b-c10636b94835</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
I seem to get this question a lot and come across many customer environments where
they have enabled web gardening thinking that it will automagically improve the performance
for their site/application.
</p>
        <p>
          <a href="http://www.samuraiprogrammer.com/blog/content/binary/WindowsLiveWriter/IISWhentoenablewebgardening_101E6/webgardening_2.jpg">
            <img style="border-right-width: 0px; margin: 0px 10px 0px 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="webgardening" border="0" alt="webgardening" align="left" src="http://www.samuraiprogrammer.com/blog/content/binary/WindowsLiveWriter/IISWhentoenablewebgardening_101E6/webgardening_thumb.jpg" width="142" height="177" />
          </a>
        </p>
        <p>
Most time, that is not the case.  The funny thing is that once I finally convince
them that web gardening is not the way to go, they try to apply that same knowledge
to other sites and applications in their environment.  When this happens, I’ll
get an e-mail or phone call asking for some guidelines on when to enable web gardening.
</p>
        <p>
We typically recommend using Web Gardening as a stop-gap (or workaround) for when
a customer has a core issue that is limiting their website and web application scalability. 
</p>
        <p>
For example, if a customer has a memory issue that is causing OutOfMemoryExceptions
in their main website – we may recommend web gardening to spread the load across multiple
worker processes while we assist them in resolving the core memory issue.  Please
note that this would also increase the memory and processor utilization on the server
and in some cases might not be viable. 
</p>
        <p>
As a best practice, create Web gardens only for Web applications that meet the following
criteria (taken from <a href="http://technet.microsoft.com/en-us/library/cc759278(WS.10).aspx" target="_blank">here</a>): 
</p>
        <ul>
          <li>
The application runs multi-instantiated, so that a different instance of the application
can be assigned to each worker process. 
</li>
          <li>
The Web application is not CPU-intensive. If the CPU is the bottleneck, then adding
worker processes cannot help improve performance. 
</li>
          <li>
The application is subject to synchronous high latency. For example, if an application
calls a back-end database and the response is slow, then a Web garden supports other
concurrent connections without waiting for the slow connection to complete. 
</li>
        </ul>
        <p>
A good discussion of why not to use Web Gardening can be found here as well:  <a href="http://blogs.technet.com/b/mscom/archive/2007/07/10/gardening-on-the-web-server.aspx" target="_blank">http://blogs.technet.com/b/mscom/archive/2007/07/10/gardening-on-the-web-server.aspx</a></p>
        <p>
Enjoy!
</p>
      </body>
      <title>IIS: When to enable web gardening?</title>
      <guid isPermaLink="false">http://www.samuraiprogrammer.com/blog/PermaLink,guid,6ccebde8-c9fb-430d-8b4b-c10636b94835.aspx</guid>
      <link>http://www.samuraiprogrammer.com/blog/2010/07/29/IISWhenToEnableWebGardening.aspx</link>
      <pubDate>Thu, 29 Jul 2010 23:50:09 GMT</pubDate>
      <description>&lt;p&gt;
I seem to get this question a lot and come across many customer environments where
they have enabled web gardening thinking that it will automagically improve the performance
for their site/application.
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://www.samuraiprogrammer.com/blog/content/binary/WindowsLiveWriter/IISWhentoenablewebgardening_101E6/webgardening_2.jpg"&gt;&lt;img style="border-right-width: 0px; margin: 0px 10px 0px 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="webgardening" border="0" alt="webgardening" align="left" src="http://www.samuraiprogrammer.com/blog/content/binary/WindowsLiveWriter/IISWhentoenablewebgardening_101E6/webgardening_thumb.jpg" width="142" height="177" /&gt;&lt;/a&gt; 
&lt;/p&gt;
&lt;p&gt;
Most time, that is not the case.&amp;#160; The funny thing is that once I finally convince
them that web gardening is not the way to go, they try to apply that same knowledge
to other sites and applications in their environment.&amp;#160; When this happens, I’ll
get an e-mail or phone call asking for some guidelines on when to enable web gardening.
&lt;/p&gt;
&lt;p&gt;
We typically recommend using Web Gardening as a stop-gap (or workaround) for when
a customer has a core issue that is limiting their website and web application scalability. 
&lt;/p&gt;
&lt;p&gt;
For example, if a customer has a memory issue that is causing OutOfMemoryExceptions
in their main website – we may recommend web gardening to spread the load across multiple
worker processes while we assist them in resolving the core memory issue.&amp;#160; Please
note that this would also increase the memory and processor utilization on the server
and in some cases might not be viable. 
&lt;/p&gt;
&lt;p&gt;
As a best practice, create Web gardens only for Web applications that meet the following
criteria (taken from &lt;a href="http://technet.microsoft.com/en-us/library/cc759278(WS.10).aspx" target="_blank"&gt;here&lt;/a&gt;): 
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
The application runs multi-instantiated, so that a different instance of the application
can be assigned to each worker process. 
&lt;/li&gt;
&lt;li&gt;
The Web application is not CPU-intensive. If the CPU is the bottleneck, then adding
worker processes cannot help improve performance. 
&lt;/li&gt;
&lt;li&gt;
The application is subject to synchronous high latency. For example, if an application
calls a back-end database and the response is slow, then a Web garden supports other
concurrent connections without waiting for the slow connection to complete. 
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
A good discussion of why not to use Web Gardening can be found here as well:&amp;#160; &lt;a href="http://blogs.technet.com/b/mscom/archive/2007/07/10/gardening-on-the-web-server.aspx" target="_blank"&gt;http://blogs.technet.com/b/mscom/archive/2007/07/10/gardening-on-the-web-server.aspx&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;
Enjoy!
&lt;/p&gt;</description>
      <comments>http://www.samuraiprogrammer.com/blog/CommentView,guid,6ccebde8-c9fb-430d-8b4b-c10636b94835.aspx</comments>
      <category>Best Practice</category>
      <category>IIS</category>
      <category>Performance</category>
    </item>
  </channel>
</rss>