<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://blogs.msdn.com/utility/FeedStylesheets/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/"><channel><title>Vance Morrison's Weblog</title><link>http://blogs.msdn.com/b/vancem/</link><description>Vance Morrison is currently an Architect on the .NET Runtime Team, specializing in performance issues with the runtime or managed code in general. </description><dc:language>en-US</dc:language><generator>Telligent Evolution Platform Developer Build (Build: 5.6.50428.7875)</generator><item><title>Updated Instructions for collecting ETW data on a ARM WinRT device (e.g. Surface)</title><link>http://blogs.msdn.com/b/vancem/archive/2013/05/09/updated-instructions-for-collecting-etw-data-on-a-arm-winrt-device-e-g-surface.aspx</link><pubDate>Thu, 09 May 2013 12:52:37 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:10417307</guid><dc:creator>Vance Morrison</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/vancem/rsscomments.aspx?WeblogPostID=10417307</wfw:commentRss><comments>http://blogs.msdn.com/b/vancem/archive/2013/05/09/updated-instructions-for-collecting-etw-data-on-a-arm-winrt-device-e-g-surface.aspx#comments</comments><description>&lt;p&gt;I have updated my &lt;a href="http://blogs.msdn.com/b/vancem/archive/2012/12/19/collecting-etw-perfview-data-on-an-windows-rt-winrt-arm-surface-device.aspx"&gt;blog entry on collecting ETW data on an ARM WinRT device&lt;/a&gt;.&amp;nbsp;&amp;nbsp; Previously I told you to use the WPR's 'GeneralProfile' to collect the data.&amp;nbsp; This is OK for some investigations, but does not collect all the same events that PerfView would have collected (most notably&amp;nbsp;GC events, JIT compile events and&amp;nbsp;async Task Events).&amp;nbsp;&amp;nbsp;&amp;nbsp; We have created a DotNetRuntimeProfile.wprp, that will tell WPR to collect these extra events.&amp;nbsp; See the posting for more details.&amp;nbsp;&amp;nbsp; I do recommend this if you need to collect ETW for managed code applications on the ARM device.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;Vance&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=10417307" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/b/vancem/archive/tags/Perf/">Perf</category><category domain="http://blogs.msdn.com/b/vancem/archive/tags/Tools/">Tools</category><category domain="http://blogs.msdn.com/b/vancem/archive/tags/ETW/">ETW</category><category domain="http://blogs.msdn.com/b/vancem/archive/tags/PerfView/">PerfView</category><category domain="http://blogs.msdn.com/b/vancem/archive/tags/Perf+Tools/">Perf Tools</category></item><item><title>PerfView does JavaScript investigations too</title><link>http://blogs.msdn.com/b/vancem/archive/2013/04/02/perfview-does-javascript-investigations-too.aspx</link><pubDate>Tue, 02 Apr 2013 23:15:51 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:10407090</guid><dc:creator>Vance Morrison</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/vancem/rsscomments.aspx?WeblogPostID=10407090</wfw:commentRss><comments>http://blogs.msdn.com/b/vancem/archive/2013/04/02/perfview-does-javascript-investigations-too.aspx#comments</comments><description>&lt;p&gt;Do you have a windows store JavaScript/HTML applications that needs performance tuning?&amp;nbsp;&lt;/p&gt;
&lt;p&gt;PerfView can handle JavaScript.&amp;nbsp;&amp;nbsp;&amp;nbsp; In particular&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;It automatically collects the necessary events so that it can decode the names of the JavaScript functions&amp;nbsp;on any stacks that are captured.&amp;nbsp;&amp;nbsp;(Note however that if your JavaScript has been obfuscated, you do have problem).&amp;nbsp;&lt;/li&gt;
&lt;li&gt;When you use the Memory-&amp;gt;Take HeapSnapshot command on a process that has a JavaScript heap it will dump that heap (it will also dump the .NET heap if it has that (or both)).&amp;nbsp;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;For the most part, investigations of JavaScript applications are&amp;nbsp;basically the same as&amp;nbsp;that for .NET.&amp;nbsp; The main differences is in the heap dumping.&amp;nbsp;&amp;nbsp; Because JavaScript objects don't have a 'type' basically what PerfView can't aggregate as much (normally it aggregates by type), and what it shows instead is object property names (in .NET it shows the type names and NOT the property/field names).&amp;nbsp;&amp;nbsp; The basic strategy however is the same, so the &lt;a href="http://channel9.msdn.com/Series/PerfView-Tutorial"&gt;PerfView&amp;nbsp;videos&lt;/a&gt;&amp;nbsp;are&amp;nbsp;pretty relevant.&amp;nbsp; &amp;nbsp;&lt;/p&gt;
&lt;p&gt;Vance&lt;/p&gt;
&lt;p&gt;I have a note to myself to beef up the documentation in this regard, and well as do some targeted videos, but it may be a while&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=10407090" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/b/vancem/archive/tags/Tools/">Tools</category><category domain="http://blogs.msdn.com/b/vancem/archive/tags/PerfView/">PerfView</category><category domain="http://blogs.msdn.com/b/vancem/archive/tags/Perf+Tools/">Perf Tools</category></item><item><title>Using TraceEvent to mine information in OS registered ETW providers</title><link>http://blogs.msdn.com/b/vancem/archive/2013/03/09/using-traceevent-to-mine-information-in-os-registered-etw-providers.aspx</link><pubDate>Sat, 09 Mar 2013 21:49:27 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:10400890</guid><dc:creator>Vance Morrison</dc:creator><slash:comments>5</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/vancem/rsscomments.aspx?WeblogPostID=10400890</wfw:commentRss><comments>http://blogs.msdn.com/b/vancem/archive/2013/03/09/using-traceevent-to-mine-information-in-os-registered-etw-providers.aspx#comments</comments><description>&lt;p&gt;In &lt;a href="http://blogs.msdn.com/b/vancem/archive/tags/traceevent/"&gt;previous blocks on TraceEvent&lt;/a&gt; I shows you how easy it was to start up ETW sessions to collect information generated by System.Diagnnostics.Tracing.EventSource classes (typically logging that you yourself did).&amp;nbsp;&amp;nbsp; But I also mentioned in other blogs that the one of the real strengths of ETW was the fact that you get to correlate lots of OS generated events with your own.&amp;nbsp;&amp;nbsp; Well in this entry I will show you how to do this (although I will show you even better ways in later blogs).&lt;/p&gt;
&lt;p&gt;In&amp;nbsp;this blog I will walk though a simple application called 'ProcessMonitor' which basically&amp;nbsp;prints a line to the screen every time a process on the system starts or stops.&amp;nbsp;&amp;nbsp;&amp;nbsp;There is a ZIP file&amp;nbsp;of a VS2010/VS2012 solution at the end of the blog and I encourage you to open it and read the code and play around with it.&amp;nbsp; I have removed comments and error handling a the 'essential' code is only about 35 lines of code.&amp;nbsp;&amp;nbsp; Here it is.&amp;nbsp;&lt;/p&gt;
&lt;p style="padding-left: 30px;"&gt;&amp;nbsp;&lt;a href="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-38-00/8231.Capture.PNG"&gt;&lt;img src="http://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-38-00/8231.Capture.PNG" alt="" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;The basic structure is basically the same as the 'real time' (no file) EventSource example that &lt;a href="http://blogs.msdn.com/b/vancem/archive/2012/12/20/and-end-to-end-etw-tracing-example-eventsource-and-traceevent.aspx"&gt;I already blogged about&lt;/a&gt;.&amp;nbsp; &amp;nbsp;Basically you&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Open&lt;/strong&gt; a TraceEventSession (with a null file name to indicate a 'real time session'.&amp;nbsp; A session is a 'controller'&amp;nbsp;which can&amp;nbsp;turn&amp;nbsp;ETW providers on and off.&amp;nbsp; &amp;nbsp;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Connect&lt;/strong&gt; a ETWTraceEventSource to that session, A TraceEventSource represents the stream of events that were sent to the session.&amp;nbsp; An ETWTraceEventSource knows the 'basic' structure that is common to all events (like that every event has a process id, time stamp, source provider, task and opcode, but does NOT know how&amp;nbsp;the name of the event or&amp;nbsp;how to deserialize the payload of the event.&amp;nbsp; &amp;nbsp;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Connect&amp;nbsp;&lt;/strong&gt;one or more&amp;nbsp;TraceEventParsers to the ETWTraceEventSource.&amp;nbsp;&amp;nbsp; A TraceEventParser knows how the event names and how to deserialized the payload bytes of the raw ETWTraceEventSource FOR A PARITULAR SET OF EVENT PROVIDERS.&amp;nbsp;&amp;nbsp; In this case we connect the 'RegisteredTraceEventParser, which knows how to decode any event that was registered with the operating system (using wevtutil).&amp;nbsp;&amp;nbsp; EventSource are NOT typically registered (although they can be), for EventSources you connect a DynamicTraceEventParser (because EventSources log their event information at&amp;nbsp;EventSource startup time&amp;nbsp;(dynamically).&amp;nbsp; However&amp;nbsp;in this case we are interested in the OS providers, and&amp;nbsp;so RegsiteredTraceEventSource is&amp;nbsp;what we&amp;nbsp;want.&amp;nbsp; It is common to register both.&amp;nbsp;&amp;nbsp;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Subscribe&amp;nbsp;&lt;/strong&gt;to&amp;nbsp;the event callbacks of&amp;nbsp;TraceEventParsers that you connected to your source.&amp;nbsp; Some parsers are 'strongly typed' in that they know the exact name and fields of every event they know about at compile time (ClrTraceEventParser and KernelTraceEventParser are like this).&amp;nbsp; These are the best to use because they are VERY efficient (no string lookups), you get to use normal C# property accesses (since the names of these properties are known at compile time), and are type-safe (no casting needed).&amp;nbsp;&amp;nbsp; However both DynamicTraceEventParser and 'RegisteredTraceEventParser can not work like this because they fetch the information about events at runtime (not compile time), and thus look more like a reflection API.&amp;nbsp; In a later blog post I will show you how to fix this by generating TraceEventParsers for use at compile time, but until that we will make do with the limitations of 'RegisteredTraceEventParser .&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Because 'RegisteredTraceEventParser' does not know at compile time the names of ANY events, you can't subscribe to particular events with this TraceEventParser, instead you can only subscribe to 'All' meaning all events this parser knows how to parse.&amp;nbsp; Once inside the callback you can then filter out the particular events of interest.&amp;nbsp;&amp;nbsp;&amp;nbsp; In our case most of the code above is the delegate body that gets called on every event that 'RegisteredTraceEventParser knows how to parse.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Enable&lt;/strong&gt; the ETW Providers for the&amp;nbsp;events you are interested in.&amp;nbsp; &amp;nbsp;In the example above we use the GetProviderByName() API to convert the name Microsoft-Windows-Kernel-Process to is unique ID, and then used that to enable the provider with and&amp;nbsp;level (verbosity) of 'Informational'&amp;nbsp;and a&amp;nbsp;'keyword' (bitset) argument '0x10' .&amp;nbsp;&amp;nbsp;The 'keyword '&amp;nbsp;argument is a bitset that indicates which events to enable.&amp;nbsp;&amp;nbsp; It is not uncommon to use -1 (all 1s bitset, or every event in the provider), however in this case we 'knew' the right bitset was 0x10 (more on how we did that below).&amp;nbsp;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Process&lt;/strong&gt; incoming events by calling the ETWTraceEventSource's 'Process()' method.&amp;nbsp;&amp;nbsp; For files, this returns when all the events in the file are processed.&amp;nbsp; For real-time sessions, it only ends when the 'ETWTraceEventSoruce.StopProcessing()' method is called.&amp;nbsp;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Once Process() is called, as events come in&amp;nbsp;your event handlers will be called&amp;nbsp;(for real time sessions there typically is a 1-3 second delay between the event happening and being called back in your Parser).&amp;nbsp;&amp;nbsp; In our case we are looked for events with at 'TaskName' of 'ProcessStart' and 'ProcessStop' and based on what we see there we call 'PayloadByName' to fetch particular payloads (and cast them to the correct type), and then process them (in this case simply print a message to the Console.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;So you can see, that the actual mechanics of making this tool is reasonably straightforward, however we make two important observations:&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;The callback code is not very friendly.&amp;nbsp; It has lots of 'magic names' which if incorrect, will simply cause nulls to be returned (which means casting will throw an exception).&amp;nbsp; You had to know what type various things were (was CPUCycleCount an int, uint, long, ulong?) and you can imagine that the code behind 'PayloadByName' is relatively inefficient (it much do some sort of string lookup when it is called and then box its result into an object (which we then have to cast).&amp;nbsp;&amp;nbsp;&amp;nbsp; This is no horrific (as it would be if we had to deserialize the data blob ourselves), but is not unlike the string parsing you do when processing a CSV file, which we would like to avoid.&amp;nbsp;&amp;nbsp;&lt;/li&gt;
&lt;li&gt;There is also a discovery problem.&amp;nbsp;&amp;nbsp; How do we know that the provider 'Microsoft-Windows-Kernel-Process' event exists, and how did we know that the 0x10 keyword was what we wanted?&amp;nbsp;&amp;nbsp; Thus this example alone is really not sufficient, we need to understand what providers are out there and what keywords they have.&amp;nbsp;&amp;nbsp; How do we do this?&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;The answer to the first problem is to generate a provider-specific TraceEventParser at compile time.&amp;nbsp;&amp;nbsp; That is what we want is to have something that takes a provider (or more specifically a description of all the events in a provider called the manifest), and generates code that knows how to parse THOSE PARTICULAR EVENTS.&amp;nbsp;&amp;nbsp; Now you just link in that code, and the you can now get a much better experience, where intellisense works and each event knows the fields that are valid.&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; We have a tool called 'TraceParserGen' which does exactly this, which I will talk about in a future blog.&amp;nbsp;&amp;nbsp; In the mean time I will show you how to find the strings I used in the code above for yourself in this blog entry.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Then answer to the second point (how do we figure out what providers are out there and what events are in the provider) for today at least is the 'logman query providers' command.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;You can find out all the providers that have been registered in the operating system by running the command&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;logman query providers &amp;gt; providers.txt&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;It is a long list, which is why I redirected it to a file.&amp;nbsp;&amp;nbsp;&amp;nbsp; Generally you care most about the providers that begin with 'Microsoft-' because these are the 'new' ETW providers.&amp;nbsp; Most of the others are 'old' providers' and may not provide any useful information about how to enable them.&amp;nbsp; It also does not include providers that did not publish themselves to the OS (EventSources DO NOT publish themselves an thus are not on the list).&amp;nbsp;&amp;nbsp; Thus the command above is pretty much only useful to find out what OS providers there are (which is still VERY useful).&lt;/p&gt;
&lt;p&gt;There is a very useful variation of the command above.&amp;nbsp; You can give it a -pid &amp;lt;num&amp;gt; argument&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;logman query providers -pid 5400&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Which looks for all USER MODE providers that CAN BE ENABLED in the process given.&amp;nbsp;&amp;nbsp;&amp;nbsp; This will include all EVENTSOURCEes (however it will just show their GUID, so it is not super-helpful), and will NOT show KERNEL providers (they are implicitly available for all processes), but will show you the USER MODE OS providers that are available, which is still pretty handy.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Once you have a provider you are interested in, you can find out what Keywords and level it allows by specifying a provider name on the 'logman query providers' command.&amp;nbsp; For example have doing a logman query providers and seeing Microsoft-Windows-Kernel-Process, we can guess that if we wanted to know about process stuff that this provider would probably do it.&amp;nbsp;&amp;nbsp; Thus we execute the command&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;logman query providers Microsoft-Windows-Kernel-Process&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;And we get the output&lt;/p&gt;
&lt;p style="padding-left: 30px;"&gt;Value&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Keyword&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Description&lt;br /&gt;-------------------------------------------------------&lt;br /&gt;0x0000000000000010&amp;nbsp; WINEVENT_KEYWORD_PROCESS&lt;br /&gt;0x0000000000000020&amp;nbsp; WINEVENT_KEYWORD_THREAD&lt;br /&gt;0x0000000000000040&amp;nbsp; WINEVENT_KEYWORD_IMAGE&lt;br /&gt;0x0000000000000080&amp;nbsp; WINEVENT_KEYWORD_CPU_PRIORITY&lt;br /&gt;0x0000000000000100&amp;nbsp; WINEVENT_KEYWORD_OTHER_PRIORITY&lt;br /&gt;0x0000000000000200&amp;nbsp; WINEVENT_KEYWORD_PROCESS_FREEZE&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Which shows us that the keyword 0x10 will get use the WINEVENT_KEYWORD_PROCESS events and the keyword 0x40 would get us the WINEVENT_KEYWORD_IMAGE, so if we cared about processes and image loads, setting the keyword 0x50 (the OR) should give us what we need.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Another pretty common technique is to just 'try it and see'.&amp;nbsp;&amp;nbsp; For example, once we were interested in Microsoft-Windows-Kernel-Process we simply 'try it and see' using PerfView.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;PerfView /onlyProviders:Microsoft-Windows-Kernel-Process collect&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Let it run for a bit, and then look at the 'events' view in PerfView.&amp;nbsp;&amp;nbsp; By default if you simply specify a provider name in PerfView, it turns on ALL keywords and VERBOSE level, so you should get everything.&amp;nbsp; you can then see what you got.&amp;nbsp;&amp;nbsp;&amp;nbsp; Doing this for Microsoft-Windows-Kernel-Process&amp;nbsp; we see the following in the events view&lt;/p&gt;
&lt;p&gt;&lt;a href="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-38-00/8738.Capture.PNG"&gt;&lt;img src="http://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-38-00/8738.Capture.PNG" alt="" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;That the Microsoft-Windows-Kernel-Process provider has 4 events.&amp;nbsp;&amp;nbsp; In PerfView an events is show as 'Provider/Task/Opcode' so the first event in that display has a 'TaskName' of 'ImageLoad' and an empty opcode (Info).&amp;nbsp;&amp;nbsp; We also see the event with the &amp;nbsp;'ProcessStart' TaskName and the OpcodeName of 'Start'.&amp;nbsp;&amp;nbsp; These are probably of interest&lt;/li&gt;
&lt;li&gt;Looking at particular exmaples we see that a ProcessStart/Start event has fields like 'ParentProcessID' and 'ImageStart' and that the ProcessStop/Stop event has fields like 'ExitCode' and 'CPUCycleCount'.&amp;nbsp; This is how we know what strings to pass to 'PayloadByName'.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;It is possible to probe this information at runtime (if you just to a ToString() on a TraceEvent, it will dump a XML representation of all the fields of the event into the returned string).&amp;nbsp;&amp;nbsp; There are also the &amp;nbsp;'PayloadNames' property that tell you all the legal values to pass to 'PayloadByName'.&amp;nbsp;&amp;nbsp; Typically, it is easier to simply 'try it an see' in PerfView, however.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;So there you have it,&amp;nbsp; You are now armed with the ability to go data mining for all the interesting events in the ETW system.&amp;nbsp;&amp;nbsp; Keep in mind however, that for kernel events, your first reactions should be to&amp;nbsp;explore&amp;nbsp;the KernelTraceEventParser, because it is already got a nice, efficient, strongly typed wrapper.&amp;nbsp; However if it is not there, You can use RegisteredTraceEventParser to decode it.&amp;nbsp;&amp;nbsp; Couple this with the ability to also see your EventSources, and things start to get very exciting...&lt;/p&gt;
&lt;p&gt;So now its your turn.&amp;nbsp; Open the ProcessMonitor.ZIP file attached, drag it to your machine, open it in Visual Studio and take a look (it has lots of comments I omitted above).&amp;nbsp; Play around with it (try other providers, and keywords, Play with image load events or file open events).&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Vance&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=10400890" width="1" height="1"&gt;</description><enclosure url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-components-postattachments/00-10-40-08-90/ProcessMonitor.zip" length="658724" type="application/zip" /><category domain="http://blogs.msdn.com/b/vancem/archive/tags/TraceEvent/">TraceEvent</category></item><item><title>More Support for EventSource and strongly typed logging: The Semantic Logging Application Block</title><link>http://blogs.msdn.com/b/vancem/archive/2013/03/09/more-support-for-eventsource-and-strongly-typed-logging-the-semantic-logging-application-block.aspx</link><pubDate>Sat, 09 Mar 2013 18:14:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:10400878</guid><dc:creator>Vance Morrison</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/vancem/rsscomments.aspx?WeblogPostID=10400878</wfw:commentRss><comments>http://blogs.msdn.com/b/vancem/archive/2013/03/09/more-support-for-eventsource-and-strongly-typed-logging-the-semantic-logging-application-block.aspx#comments</comments><description>&lt;p&gt;If you have been following my blog at all, you have seen my &lt;a href="http://blogs.msdn.com/b/vancem/archive/tags/eventsource/"&gt;articles about System.Diagnostics.Tracing.EventSource&lt;/a&gt;, a class that&amp;nbsp;introduced in V4.5 of the .NET Runtime for production logging.&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;This class replaces the System.Diagnostics.TraceSource class&amp;nbsp; and we strongly encourage people to consider using EventSource instead of TraceSource for any future work (You can events from one go to the other 'stream' so you can transition slowly if you need to)&amp;nbsp;&amp;nbsp; We like to believe EventSource is &amp;nbsp;'ultimate' in logging APIs for .NET in that you should be able to do pretty much any logging you desire with it and we should not have to change it in incompatible ways, ever.&amp;nbsp;&amp;nbsp;&amp;nbsp;We believe this simply because of the 'shape' of a logging statement, here is a prototypical one&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;myEventSource.MyEvent(eventArg1, eventArg2, ...)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Basically at the call site you specify&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;The EventSource (myEventSource)&lt;/li&gt;
&lt;li&gt;The Name of the Event being raised as a method (MyEvent)&lt;/li&gt;
&lt;li&gt;Any 'payload' arguments you wish to log as part of logging that event.&amp;nbsp;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Notice I did not specify any formatting strings, logging levels, or other meta data at the call site, just what 'has to be there'.&amp;nbsp;&amp;nbsp; What may not be quite so obvious is that all the event arguments are passed without loss of type information (the MyEvent method is strongly typed, not a 'params object[]').&amp;nbsp;&amp;nbsp; Unlike 'printf' 'string.Format' logging we did not 'stringify' anything and loose information. It is all passed to the logging method.&amp;nbsp;&amp;nbsp; This information is preserved in the EventSource 'pipe' which means that when you access a particular event you can do so in a strongly typed way, accessing each payload argument with a property accessor as this snipped of code demonstrates.&amp;nbsp;&lt;/p&gt;
&lt;p style="padding-left: 30px;"&gt;MySourceParser.MyEvent += delegate(MyEventTraceEvent data) {&lt;/p&gt;
&lt;p style="padding-left: 30px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Console.WriteLine("MyEvent: Arg1 = {0}&amp;nbsp; Arg2 = {2} ", data.MyArg1, data.MyArg2);&amp;nbsp;&amp;nbsp;&amp;nbsp; // Where MyArg1, and MyArg2 are the names of the parameters of the 'MyEvent' method.&lt;/p&gt;
&lt;p style="padding-left: 30px;"&gt;}&lt;/p&gt;
&lt;p&gt;Thus you really can get to the point where your logging is what you wanted, it is like passing data a method call in the program being monitored, through the logging pipeline (serialization) to pop out as a &amp;nbsp;to strongly typed structure in some&amp;nbsp;automation that processes logging information&amp;nbsp;files.&amp;nbsp; &amp;nbsp; Basically you get a 'full fidelity' (without loss of type information or 'metadata' like payload names) end to end&amp;nbsp;pipeline for logging information.&amp;nbsp;&amp;nbsp; This is ideal in event logging, and EventSource is in a position to deliver it.&lt;/p&gt;
&lt;p&gt;We are not completely there yet as there are missing pieces.&amp;nbsp; However far more of it is actually in place, people just don't know about it.&amp;nbsp; I am trying to fix this with my blog, but there is a lot to tell and event that is a work in progress.&amp;nbsp;&amp;nbsp;&amp;nbsp; Well in the blog entry I am here to tell you about one of the big pieces of this overarching 'strongly typed eventing story' that is falling into place:&lt;/p&gt;
&lt;p&gt;&lt;span style="font-size: medium;"&gt;&lt;strong&gt;The Semantic Logging Application Block&lt;/strong&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;Microsoft has a team called the &lt;a href="http://pnp.azurewebsites.net/en-us/"&gt;'Patterns and Practices'&lt;/a&gt; team whose job it is to illustrate gpod and proven practices in using Microsoft technologies.&amp;nbsp;&amp;nbsp; As part of their work they write guidance and build samples of real applications, but they also write utility libraries that 'flesh out' Microsoft technologies that currently only provided 'the basics'.&amp;nbsp;&amp;nbsp; This team recognized that&amp;nbsp;the strongly typed pipeline that EventSource provides is a great foundation, but&amp;nbsp;only provided the basics, and they could provide the next layer of 'value add' libraries.&amp;nbsp;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;This is what the &lt;a href="http://entlib.codeplex.com/releases/view/101823"&gt;Semantic&amp;nbsp;Logging Application Block&lt;/a&gt; is.&amp;nbsp; &amp;nbsp; 'Semantic Logging' is their term for strongly typed logging.&amp;nbsp;&amp;nbsp; They like the term because it strongly conveys the fact that the logging happens at a more structural level, and is much closer to the logging the semantics of the program (since you pass strongly typed fields without losing the&amp;nbsp;types or the names of the event or fields), than classic&amp;nbsp;string based logging does.&amp;nbsp;&amp;nbsp;&amp;nbsp; This &lt;a href="http://blogs.msdn.com/b/agile/archive/2013/02/07/embracing-semantic-logging.aspx"&gt;'Embracing Semantic Logging'&lt;/a&gt; article gives a great summary of their view of why they like semantic logging and why you should too.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;As you might expect, I heartily endorse their philosophy on logging, and their efforts to 'flesh out' the EventSource foundation, and make it as useful as possible to as many as possible.&amp;nbsp;&amp;nbsp; If you are not already a convert to EventSource, I strongly encourage you to read &lt;a href="http://blogs.msdn.com/b/agile/archive/2013/02/07/embracing-semantic-logging.aspx"&gt;'Embracing Semantic Logging'.&lt;/a&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;For those of you&amp;nbsp;who are already 'on board' with strongly&amp;nbsp;typed logging,&amp;nbsp;what can &lt;a href="http://entlib.codeplex.com/releases/view/101823"&gt;Semantic&amp;nbsp;Logging Application Block&lt;/a&gt; do for you?&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;EventListeners that send your EventSource data to various places like a flat files, Azure storage, the windows event log, a database etc.&amp;nbsp;&lt;/li&gt;
&lt;li&gt;An EventListener host/service that can process events from any processes on the system and do application specific monitoring / rollups.&amp;nbsp;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&amp;nbsp;For more complete details see their the PDF file documentation on the 'Download' tab.&amp;nbsp; Here are the links for the current release (but are likely to be broken in the future)&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a id="fileDownload3" class="FileNameLink" tabindex="9" href="http://entlib.codeplex.com/downloads/get/623243"&gt;SemanticLogging-DevelopersGuide-draft-CTP.pdf&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a id="fileDownload4" class="FileNameLink" tabindex="9" href="http://entlib.codeplex.com/downloads/get/623244"&gt;SemanticLogging-ReferenceDocs-draft-CTP.pdf&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;So, if you are doing logging on the .NET platform, you should be using EventSource.&amp;nbsp;&amp;nbsp; If are looking around for what reusable code you can leverage, take a look at the Semantic Logging Application Block.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Vance&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=10400878" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/b/vancem/archive/tags/EventSource/">EventSource</category></item><item><title>A Lab on investigating Memory Performance with PerfView</title><link>http://blogs.msdn.com/b/vancem/archive/2013/02/27/a-lab-on-investigating-memory-performance-with-perfview.aspx</link><pubDate>Thu, 28 Feb 2013 04:40:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:10398025</guid><dc:creator>Vance Morrison</dc:creator><slash:comments>3</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/vancem/rsscomments.aspx?WeblogPostID=10398025</wfw:commentRss><comments>http://blogs.msdn.com/b/vancem/archive/2013/02/27/a-lab-on-investigating-memory-performance-with-perfview.aspx#comments</comments><description>&lt;p&gt;As part of a conference that I participated in this week, I have created a lab on using PerfView to investigate Memory issues.&amp;nbsp;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;The lab covers both managed and unmanaged code techniques.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;The ZIP file below&amp;nbsp;of two&amp;nbsp;Visual Studio 2012 projects which create&amp;nbsp;leaky apps&amp;nbsp;(one C++ and one C#), as well as an&amp;nbsp;MHT file (multi file HTML), which is the&amp;nbsp;document&amp;nbsp;that leads you through the lab.&amp;nbsp; It is loaded with screenshots and is quite detailed.&amp;nbsp;&amp;nbsp;&amp;nbsp; It does assume you have VS 2012 installed and are running on Windows 8.&lt;/p&gt;
&lt;p&gt;For those who don't have those prerequisites, I have put the data files&amp;nbsp;that you would have collected into &amp;nbsp;&lt;a href="https://skydrive.live.com/redir.aspx?cid=d068505f1c71ab61&amp;amp;page=self&amp;amp;resid=D068505F1C71AB61!211&amp;amp;parid=D068505F1C71AB61!124&amp;amp;authkey=!&amp;amp;Bpub=SDX.SkyDrive&amp;amp;Bsrc=Share"&gt;PreWin8DataPackage.zip&lt;/a&gt;&amp;nbsp;on my public&amp;nbsp;skydrive.&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Simply click on the link which takes you to skydrive, and then open the ZIP file by double clicking on int and the contents to a local place and then you can open them in perfView and follow along without needing Win8 or VS 2012.&amp;nbsp; .&amp;nbsp;&lt;/p&gt;
&lt;p&gt;To use the InvestigationMemory.ZIP attached below, file simply open it, and drag its contents to a convenient folder on your machine (e.g. the desktop).&amp;nbsp; Then open the MHT file (it should open in the browser) and follow the instructions.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Enjoy&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=10398025" width="1" height="1"&gt;</description><enclosure url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-components-postattachments/00-10-39-80-25/InvestigatingMemory.zip" length="5430645" type="application/octet-stream" /><category domain="http://blogs.msdn.com/b/vancem/archive/tags/Perf/">Perf</category><category domain="http://blogs.msdn.com/b/vancem/archive/tags/PerfView/">PerfView</category><category domain="http://blogs.msdn.com/b/vancem/archive/tags/Perf+Tools/">Perf Tools</category></item><item><title>New version of TraceEvent / PerfMonitor Posted to bcl.codeplex.com</title><link>http://blogs.msdn.com/b/vancem/archive/2013/01/07/new-version-of-traceevent-perfmonitor-posted-to-bcl-codeplex-com.aspx</link><pubDate>Mon, 07 Jan 2013 14:27:05 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:10382822</guid><dc:creator>Vance Morrison</dc:creator><slash:comments>7</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/vancem/rsscomments.aspx?WeblogPostID=10382822</wfw:commentRss><comments>http://blogs.msdn.com/b/vancem/archive/2013/01/07/new-version-of-traceevent-perfmonitor-posted-to-bcl-codeplex-com.aspx#comments</comments><description>&lt;p&gt;For several years now, I have had code called the 'TraceEvent library' that allows you to access ETW files (ETL files) from C#.&amp;nbsp;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;However for over a year now, I have not updated the public version of that library.&amp;nbsp;&amp;nbsp; Well, that time has ended.&lt;/p&gt;
&lt;p&gt;I&amp;nbsp;updated the &lt;a href="http://bcl.codeplex.com/wikipage?title=TraceEvent&amp;amp;referringTitle=Home"&gt;TraceEvent&lt;/a&gt;&amp;nbsp;library as well as the &lt;a href="http://bcl.codeplex.com/wikipage?title=PerfMonitor&amp;amp;referringTitle=Home"&gt;PerfMonitor&lt;/a&gt; sample at &lt;a href="http://bcl.codeplex.com"&gt;http://bcl.codeplex.com&lt;/a&gt;&amp;nbsp;to sync up with the latest internal versions.&amp;nbsp;&amp;nbsp; The TraceEvent library is version 1.2.7 (corresponding to the version of PerfView that uses it), and the version of PerfMonitor is Version 2.0.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;For those of you don't know, the&amp;nbsp;TraceEvent library is the&amp;nbsp;power&amp;nbsp;behind the &lt;a href="http://www.microsoft.com/en-us/download/details.aspx?id=28567"&gt;PerfView&lt;/a&gt; tool, and that makes it pretty powerful.&amp;nbsp;&amp;nbsp; With it you can&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Use the TraceEventSession class to turn on ETW providers, including the Windows Kernel provider (CPU sampling) and the .NET Runtime providers.&amp;nbsp; You can turn on capturing stack traces for most events.&amp;nbsp;&lt;/li&gt;
&lt;li&gt;You can tell the sesson to either log the data to a (ETL) file or send it to a in-memory buffer for 'real time' consumption of the events.&amp;nbsp;&amp;nbsp;&lt;/li&gt;
&lt;li&gt;Use the TraceEventSource class to read the resulting data (either ETL files or the in-memory buffer), and parse resulting payloads&lt;/li&gt;
&lt;li&gt;The library has built in support for the Kernel and .NET Runtime providers.&amp;nbsp;&lt;/li&gt;
&lt;li&gt;It also built-in support for System.Diagnostics.Tracing.EventSource using he 'DynamicTraceEventParser' class.&amp;nbsp; Thus you an always properly parse EventSource data.&amp;nbsp;&lt;/li&gt;
&lt;li&gt;As well as support for the RegisteredTraceEventParser, which knows how to decode any 'Manifest Based' provider (basically any OS supplied provider).&amp;nbsp;&amp;nbsp;&lt;/li&gt;
&lt;li&gt;The 'TraceLog' class creates a high level abstraction, which knows about Processes, Threads, Modules, and how to Decode Stacks.&amp;nbsp; It has a routines (the DiaLib) that know how to look up address in PDBS to get symbolic names as well as get symbolic names for Just in Time (JIT) compiled code.&amp;nbsp;&amp;nbsp; The result is that you can get at symbolic names for stacks (this is how PerfView works).&amp;nbsp;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;In short, most of what you see PerfView do with an ETL file, you can do yourself.&amp;nbsp;&amp;nbsp; Now if you just need a 'tweek' of what PerfView does, I recommend using PerfView's extensibility model to do the job (see the Help -&amp;gt; Extending PerfView menu entry in PerfView).&amp;nbsp; However if you want something 'stand alone'.&amp;nbsp; TraceEvent is a good choice.&lt;/p&gt;
&lt;p&gt;If you have used TraceEvent in the past, there are some small braking changes, but the port should be easy (I updated PerfMonitor in a couple hours).&amp;nbsp;&amp;nbsp; There have been numerous fixes, as well as the addition of the RegisteredTraceEventParser and much better support for Symbolc resolution The DiaLib stuff is new).&amp;nbsp;&amp;nbsp; It is worth upgrading to.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;The PerfMonitor utility can be thought of as a 'command line' version of PerfView.&amp;nbsp;&amp;nbsp; However I don't recommend using it as an actual tool, it almost all cases, PerfView is a better tool than PerfMonitor.&amp;nbsp;&amp;nbsp;&amp;nbsp;PerfMonitor&amp;nbsp;is more of a sample of how to use TraceEvent in non-trivial ways (it is easier to understand without all the GUI goo cluttering up the logic).&amp;nbsp;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;I will probably post more detailed 'how to's of using ETW with TraceEvent in future blog posts.&lt;/p&gt;
&lt;p&gt;Vance&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=10382822" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/b/vancem/archive/tags/ETW/">ETW</category><category domain="http://blogs.msdn.com/b/vancem/archive/tags/Perf+Tools/">Perf Tools</category><category domain="http://blogs.msdn.com/b/vancem/archive/tags/TraceEvent/">TraceEvent</category></item><item><title>Why doesn't my EventSource produce any events?</title><link>http://blogs.msdn.com/b/vancem/archive/2012/12/21/why-my-doesn-t-my-eventsource-produce-any-events.aspx</link><pubDate>Sat, 22 Dec 2012 01:16:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:10380233</guid><dc:creator>Vance Morrison</dc:creator><slash:comments>9</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/vancem/rsscomments.aspx?WeblogPostID=10380233</wfw:commentRss><comments>http://blogs.msdn.com/b/vancem/archive/2012/12/21/why-my-doesn-t-my-eventsource-produce-any-events.aspx#comments</comments><description>&lt;p&gt;This is a quick entry to warn about&amp;nbsp;a pitfall that you are likely to run into sooner or later&amp;nbsp;if you build or maintain EventSources.&amp;nbsp;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;As I have blogged about, it is very easy to get started with EventSources.&amp;nbsp;&amp;nbsp; Here is some code that someone might write&lt;/p&gt;
&lt;p&gt;&lt;a href="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-38-00/8664.Capture.PNG"&gt;&lt;img src="http://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-38-00/8664.Capture.PNG" alt="" border="0" /&gt;&lt;/a&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;And then use it by using by doing&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;span style="color: #2b91af; font-family: Consolas; font-size: x-small;"&gt;&lt;span style="color: #2b91af; font-family: Consolas; font-size: x-small;"&gt;&lt;span style="color: #2b91af; font-family: Consolas; font-size: x-small;"&gt;MyEventSource&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: Consolas; font-size: x-small;"&gt;&lt;span style="font-family: Consolas; font-size: x-small;"&gt;.Log.MyFirstMessage(&lt;/span&gt;&lt;/span&gt;&lt;span style="color: #a31515; font-family: Consolas; font-size: x-small;"&gt;&lt;span style="color: #a31515; font-family: Consolas; font-size: x-small;"&gt;&lt;span style="color: #a31515; font-family: Consolas; font-size: x-small;"&gt;"The time is "&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: Consolas; font-size: x-small;"&gt;&lt;span style="font-family: Consolas; font-size: x-small;"&gt; + &lt;/span&gt;&lt;/span&gt;&lt;span style="color: #2b91af; font-family: Consolas; font-size: x-small;"&gt;&lt;span style="color: #2b91af; font-family: Consolas; font-size: x-small;"&gt;&lt;span style="color: #2b91af; font-family: Consolas; font-size: x-small;"&gt;DateTime&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: Consolas; font-size: x-small;"&gt;&lt;span style="font-family: Consolas; font-size: x-small;"&gt;.Now);&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&amp;nbsp;You turn your EventSource on by doing&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;PerfView /providers=*MyEventSource run MyApp.exe&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;but you find that there are &lt;strong&gt;no events in the resulting log file from&amp;nbsp;MyEventSource&lt;/strong&gt;!&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;What is going on?&amp;nbsp;&amp;nbsp; The root of the problem is that there is a bug in the code above (can you spot it?).&amp;nbsp;&amp;nbsp; Notice that the First and second message call 'WriteEvent' with exactly the same ID.&amp;nbsp; This is a mistake.&amp;nbsp;&amp;nbsp; Each event in an eventSource must be given a unique ID.&amp;nbsp; In fact the rule is stricter than that: &amp;nbsp;the event you pass 'WriteEvent' must be exactly the event ID that EventSource thinks it should have.&amp;nbsp;&amp;nbsp; This ID is either&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;The ID assigned to it explicitly with the Event attribute (not used in the above case) OR&lt;/li&gt;
&lt;li&gt;The ordinal number of logging methods' where a logging method is defined to be a method that returns void.&amp;nbsp;&amp;nbsp;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Thus 'MySecondMessage MUST use the ID 2, not 1 (since it is the second logging message in the class).&amp;nbsp;&amp;nbsp; This insures that there is a unique ID given to each event that an EventSource generates.&amp;nbsp; EventSource checks for this and throws an exception if this (and many other error conditions) occur.&amp;nbsp;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;So where is my Exception?&amp;nbsp; This is the unfortunate part.&amp;nbsp;&amp;nbsp; Late in the development of EventSource users made the strong request that EventSource NEVER FAIL by default.&amp;nbsp;&amp;nbsp; This is a useful property, as logging is often 'optional' and you don't want to some startup error with ETW to cause your application to fail.&amp;nbsp;&amp;nbsp; This feature was implemented by simply wrapping the body of the constructor in a try-catch, which sets a flag in the catch clause that will make any subsequent WriteEvent call simply do nothing.&amp;nbsp;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;This satisfies the desire for EventSource to never throw, but it also makes finding&amp;nbsp;any mistake in your EventSource very difficult.&amp;nbsp;&amp;nbsp;&amp;nbsp; Worse, there seems to be a bug in VS where exception that are caught are not always&amp;nbsp;displayed&amp;nbsp;in the output window and setting the 'Exceptions'&amp;nbsp;dialog to&amp;nbsp;stop on any exception thrown does not seem to work (probably because in the typical case EventSource is called from the class constructor (to initialize a static variable)).&amp;nbsp;&lt;/p&gt;
&lt;p&gt;This is all very unfortunate, and leads to 'mysterious' failures if you make ANY mistake in your EventSource.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;The good news is that there is a pretty easy work-around that works today.&amp;nbsp;&amp;nbsp; It is simply this&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;When you make any changes to your EventSource, immediately use PerfView /providers=*&lt;em&gt;EventSourceName&lt;/em&gt; collect&amp;nbsp; test it.&amp;nbsp; (That is use PerfView's default settings and your provider to turn it on)&lt;/li&gt;
&lt;li&gt;If you don't find your events as expected, Open the 'Exceptions Stacks' view in the data file&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This will show you something like this&lt;/p&gt;
&lt;p&gt;&lt;a href="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-38-00/3276.Capture.PNG"&gt;&lt;img src="http://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-38-00/3276.Capture.PNG" alt="" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Which shows you all exceptions thrown during the trace, include any that were swallowed by a try-catch in the implementation of EventSource.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Notice that you get the exactly exception message, which tells you pretty clearly what you did wrong (in the example above the 'EventMessage1' event was passed 1 but it should have been 2.&lt;/p&gt;
&lt;p&gt;So the simple advice is&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;if your EventSource is not working after an update, simply look at the 'Exceptions view'.&amp;nbsp;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;What is nice is that once you know about this, it is probably EASIER than trying to debug it in the debugger (because you had to use something to turn on the provider anyway).&amp;nbsp;&amp;nbsp; Now you don't even need a debugger to resolve the issue.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=10380233" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/b/vancem/archive/tags/EventSource/">EventSource</category></item><item><title>Using TraceSource to log ETW data to a file</title><link>http://blogs.msdn.com/b/vancem/archive/2012/12/21/using-tracesource-to-log-etw-data-to-a-file.aspx</link><pubDate>Fri, 21 Dec 2012 06:19:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:10380023</guid><dc:creator>Vance Morrison</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/vancem/rsscomments.aspx?WeblogPostID=10380023</wfw:commentRss><comments>http://blogs.msdn.com/b/vancem/archive/2012/12/21/using-tracesource-to-log-etw-data-to-a-file.aspx#comments</comments><description>&lt;p&gt;&lt;a href="http://blogs.msdn.com/b/vancem/archive/2012/12/20/and-end-to-end-etw-tracing-example-eventsource-and-traceevent.aspx"&gt;Yesterday's blog post&lt;/a&gt; was showing how you can use EventSource to generate ETW events and the TraceEvent library to read them in 'real time'.&amp;nbsp;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Today we will do a slight variation on that example.&amp;nbsp; Instead of reading the events in real time, we will simply log them to a file, and then later (it happens to be right after the file was generated), we open this file and process it.&amp;nbsp; As you would hope the actual difference in the code is pretty minimal.&amp;nbsp;&amp;nbsp; This example also cleanly separates 'generation' of data from 'processing of data', which is nice.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;span style="font-size: medium;"&gt;&lt;strong&gt;Generating the file&lt;/strong&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;At it's heart, this is the code to generate the file is pretty simple.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;a href="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-38-00/2677.Capture.PNG"&gt;&lt;img src="http://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-38-00/2677.Capture.PNG" alt="" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;This code creates a TraceEventSession, giving it a name, and in this case a file name to log the data to.&amp;nbsp;&amp;nbsp; Next we tell the session that the OS session should&amp;nbsp;be stopped (reclaimed) when the TraceEventSession is disposed.&amp;nbsp;&amp;nbsp; We then enable any providers we want to log (in this case only one), and then collect for 12 seconds and then close the TraceEventSession (the using statement) which closes the file.&amp;nbsp; At this point we have our data.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;span style="font-size: medium;"&gt;&lt;strong&gt;Processing the file&lt;/strong&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;To process the file we use the following code.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-38-00/7802.Capture.PNG"&gt;&lt;img src="http://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-38-00/7802.Capture.PNG" alt="" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;This code opens the data file,&amp;nbsp;hooks up the DynamicTraceEventParser (which knows how to parse EventSource providers, and register a callback for ANY event that the parser recognizes (the All event).&amp;nbsp;&amp;nbsp; In this callback we print out the event and also print something special when we see the 'Stop'&amp;nbsp;event.&lt;/p&gt;
&lt;p&gt;After setting up the &amp;nbsp;callbacks we call 'Process' that reads the file and does all the necessary callbacks.&amp;nbsp; It returns when there are no more events in the file to process.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;And that is about it.&amp;nbsp;&amp;nbsp; As you can see it probably EASIER to do ETW data collection in two pieces (they split very nicely into two pieces).&amp;nbsp;&amp;nbsp; The first piece ONLY deals with TraceEventSession (the controller), and the latter piece ONLY deals with ETWTraceEventSource and parsers (the READER).&amp;nbsp;&amp;nbsp; Each one is pretty easy to understand.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;span style="font-size: medium;"&gt;&lt;strong&gt;Check out the complete sources&lt;/strong&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;The MonitorToFile.zip has the complete, buildable source code (uses a VS 2010 or VS2012 solution).&amp;nbsp;&amp;nbsp;&amp;nbsp;The code&amp;nbsp;is a bit longer because it has a lot of comments and a bit of error handling, but I hope you will&amp;nbsp;be able to&amp;nbsp;easily recognize the snippets above as the 'heart' of the program.&amp;nbsp;&amp;nbsp; &amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;span style="font-size: medium;"&gt;&lt;strong&gt;Advanced scenarios: Circular buffers and Kernel events.&amp;nbsp; &lt;/strong&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;Once you understand the basics, you may be interested in some of the more advanced features.&amp;nbsp;&amp;nbsp; In particular there is the ability to log to a 'circular' file, where the file size is constrained to a maximum and when the maximum is reached it starts overwriting the oldest data in the file.&amp;nbsp;&amp;nbsp;&amp;nbsp; This allows you to create a 'flight recorder' and allows you see the last few minutes of processing before an interesting event happened.&amp;nbsp;&amp;nbsp; Setting up a 'trigger' that will stop such a circular buffer logging session is a pretty common scenario.&amp;nbsp;&amp;nbsp;&amp;nbsp; But the loss of the events in the beginning of the trace brings problem, the most serious of these is that the decoding of some events requires information from other events.&amp;nbsp;&amp;nbsp; In particular EventSources themselves generate a 'manifest' event when they start that describes the fields of every other event the EventSource will generate.&amp;nbsp; If this event is lost, then libraries like TraceEvent.dll can't decode the payloads of the events (a HUGE loss).&amp;nbsp;&amp;nbsp;&amp;nbsp; To fix this, when you collect a circular trace, right before you stop the trace you need to force any EventSource that you started to emit is manifest event again.&amp;nbsp;&amp;nbsp; This way you make up for the loss this event that happened earlier in the trace but was discarded by the circular buffering.&amp;nbsp;&amp;nbsp;&amp;nbsp; It is reasonably straightforward, but does complicate the code a bit.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;We have seen that it is pretty easy to log EventSource data.&amp;nbsp; The same is true for .NET events as well as &lt;strong&gt;some&lt;/strong&gt; OS events.&amp;nbsp; However some of the most important events (the Kernel OS events) have additional restrictions on them, and one of these restrictions is that kernel events can only be logged in a session by itself.&amp;nbsp;&amp;nbsp; Thus if you want both EventSource data as well as Kernel OS data, collecting the data is more complex.&amp;nbsp;&amp;nbsp; If there is interest I will talk about this scenario, but you can also look at the &lt;a href="http://bcl.codeplex.com/wikipage?title=PerfMonitor&amp;amp;referringTitle=Home"&gt;PerfMonitor source code&lt;/a&gt;&amp;nbsp;right now&amp;nbsp;to see how it is done.&amp;nbsp;&amp;nbsp; This is particularly tricky for real time sessions because different buffer flushing protocols will make the events come from the two sessions in clumps that are only loosely related to the time the event happened.&amp;nbsp;&amp;nbsp; Thus it is a bit trickier to properly sort the events from the two sources.&amp;nbsp;&amp;nbsp; The PerfMonitor code has a special class specifically to solve this problem.&amp;nbsp;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=10380023" width="1" height="1"&gt;</description><enclosure url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-components-postattachments/00-10-38-00-23/MonitorToFile.zip" length="645152" type="application/zip" /><category domain="http://blogs.msdn.com/b/vancem/archive/tags/Perf/">Perf</category><category domain="http://blogs.msdn.com/b/vancem/archive/tags/Perf+Tools/">Perf Tools</category><category domain="http://blogs.msdn.com/b/vancem/archive/tags/EventSource/">EventSource</category><category domain="http://blogs.msdn.com/b/vancem/archive/tags/TraceEvent/">TraceEvent</category></item><item><title>How many samples are enough when using a sample based profiler in a performance Investigation?</title><link>http://blogs.msdn.com/b/vancem/archive/2012/12/20/how-many-samples-are-enough-when-using-a-sample-based-profiler-in-a-performance-investigation.aspx</link><pubDate>Thu, 20 Dec 2012 20:13:19 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:10379897</guid><dc:creator>Vance Morrison</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/vancem/rsscomments.aspx?WeblogPostID=10379897</wfw:commentRss><comments>http://blogs.msdn.com/b/vancem/archive/2012/12/20/how-many-samples-are-enough-when-using-a-sample-based-profiler-in-a-performance-investigation.aspx#comments</comments><description>&lt;p&gt;Performance analysis&amp;nbsp;is my job, and so I answer a lot of questions about perf, and this blog is about a frequently asked question I get.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;When doing CPU analysis, many profilers, including the &lt;a href="http://www.microsoft.com/en-us/download/details.aspx?id=28567"&gt;PerfView&lt;/a&gt; tool&amp;nbsp;are sampling profilers.&amp;nbsp;&amp;nbsp; In particular, for PerfView, by default every millisecond it will stop each processor and take a stack trace.&amp;nbsp;&amp;nbsp; Thus you don't see every method that gets executed, but only those that happen to be on the stack when these 1 msec samples are taken.&amp;nbsp;&amp;nbsp;&amp;nbsp; PerfView allows you to control this (there is a CPU Sample Interval MSec text box in the 'advanced' area of the collection dialog box).&amp;nbsp; Using this textbox you an set it as fast as once ever 1/8 of a msec and as slow as once every 100 msec or more.&amp;nbsp;&amp;nbsp; This leads to the question: How many samples are enough?&amp;nbsp;&amp;nbsp;&amp;nbsp; This is the subject of this blog entry.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;First&amp;nbsp; the obvious:&amp;nbsp;From an overhead perspective slower is better .125 sampling is 8X more expensive! both in terms of runtime as file size (EVERY manipulation of the trace is not 8X slower (e.g. file transfers, Perfview view updates ...)).&amp;nbsp;&amp;nbsp;&amp;nbsp; Thus&amp;nbsp;assuming you get the quality&amp;nbsp;of information you need, slower is&amp;nbsp;better.&lt;/p&gt;
&lt;p&gt;So: the question is what rate will get you the quality you need.&amp;nbsp;&amp;nbsp;&amp;nbsp; It is important to realize that the answer to this question is NOT&amp;nbsp;about the RATE, but whether you have&amp;nbsp;enough&amp;nbsp;TOTAL sample for you SCENARIO OF INTEREST.&amp;nbsp;&amp;nbsp;&amp;nbsp; There is information in the PerfView documentation on this very point (see How many samples do you need?)&amp;nbsp;which you can quickly find by following the 'Understanding Performance Data' link at the top of the CPU view.&amp;nbsp;&amp;nbsp;&amp;nbsp;What that section says is&amp;nbsp;that the potential error&amp;nbsp;of a measurement varies as the square root of the number of samples.&amp;nbsp;&amp;nbsp; Thus if you have a 100 samples, you have reasonable confidence that the 'true' number is between 90 and 110 (10% error).&amp;nbsp;&amp;nbsp; If you had 10K samples (100 times more), you would have reasonable confidence that the number is between&amp;nbsp;99900 and 10100 (a 1% error).&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Now while you might think you should drive the error as small as possible, really you don't need that.&amp;nbsp;&amp;nbsp; Typically you don't care about 1% regressions, you care about 10% regressions.&amp;nbsp;&amp;nbsp; If your scenario had 1K samples, a 1% regression is 100 samples and the error of that 100 sample measurement is&amp;nbsp;10 (sqrt(100)) or 10% (that is you are confident that the&amp;nbsp;true regression is between 90 and 110 msec).&amp;nbsp;&amp;nbsp;&amp;nbsp;As you can see that is typically&amp;nbsp;'good enough'&amp;nbsp;&amp;nbsp; This leads to the rule of thumb that you need between 1K and 10K samples OVER&amp;nbsp;YOUR SCENARIO to get&amp;nbsp;an error&amp;nbsp;that is good enough for most investigations.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;It is important to realize that this&amp;nbsp;has NOTHING to do with how small any particular function is.&amp;nbsp;&amp;nbsp;&amp;nbsp; The basic intuition is that if a function is small, unless it is called a lot you don't care about it.&amp;nbsp; If it is called a lot, it WILL show up in the samples if you have enough samples in your SCENARIO OF INTEREST.&amp;nbsp;&amp;nbsp; Thus the driving factors are&lt;/p&gt;
&lt;ol start="1"&gt;
&lt;li&gt;What the period of time is for the scenario of interest is.&amp;nbsp;&amp;nbsp;&amp;nbsp; If this is a 'one shot' scenario (only happens once), then you need a rate that will capture between 1 and 10K samples in that time period.&amp;nbsp;&amp;nbsp; Thus the MOST COMMON reason for needing a high sample rate is that you have a short scenario (100msec) that only happens once.&amp;nbsp; (thus you would LIKE .1msec sampling to get to 1000K total samples).&amp;nbsp;&amp;nbsp; But typically you are measuring AVERAGES over LONG time (e.g. you measure the average over 10 seconds of requests), then you can easily get your 10K samples using 1msec time.&amp;nbsp;&amp;nbsp; In fact whenever you have a RECURRRING scenario it is EASIER AND BETTER, to simply measure for a longer period of time rather than increase the sampling rate.&amp;nbsp;&amp;nbsp;&amp;nbsp; (In fact, when you have long traces, you can make perfView more responsive without loosing the accuracy you need by limiting the time interval you look at to say 10 or 20 seconds of trace.&lt;/li&gt;
&lt;li&gt;What error rate you can tolerate.&amp;nbsp;&amp;nbsp; If you are looking for 'big' things (e.g. 10% of the total trace), then 1K samples is enough.&amp;nbsp;&amp;nbsp; 10K samples allows you to see 1% regressions (100 samples), with 10% error (which is fine).&amp;nbsp; If you were looking for .1% regression you would need 100K samples to be able to find .1% regressions with 10% error.&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;br /&gt; The result of all of this is&lt;/p&gt;
&lt;ol start="1"&gt;
&lt;li&gt;What matters is the total number of samples in your scenario of interest.&lt;/li&gt;
&lt;li&gt;If you have a RECURRING scenario, you should simply collect for a longer period of time.&amp;nbsp;&lt;/li&gt;
&lt;li&gt;If you have a ONE SHOT scenario and that scenarios is short (e.g. 100Msec) you need to increase the sample rate AND/OR run the scenario multiple times (making it a RECURRING scenario).&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=10379897" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/b/vancem/archive/tags/Perf/">Perf</category><category domain="http://blogs.msdn.com/b/vancem/archive/tags/ETW/">ETW</category><category domain="http://blogs.msdn.com/b/vancem/archive/tags/PerfView/">PerfView</category><category domain="http://blogs.msdn.com/b/vancem/archive/tags/Perf+Tools/">Perf Tools</category></item><item><title>An End-To-End ETW Tracing Example: EventSource and TraceEvent </title><link>http://blogs.msdn.com/b/vancem/archive/2012/12/20/and-end-to-end-etw-tracing-example-eventsource-and-traceevent.aspx</link><pubDate>Thu, 20 Dec 2012 19:42:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:10379888</guid><dc:creator>Vance Morrison</dc:creator><slash:comments>1</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/vancem/rsscomments.aspx?WeblogPostID=10379888</wfw:commentRss><comments>http://blogs.msdn.com/b/vancem/archive/2012/12/20/and-end-to-end-etw-tracing-example-eventsource-and-traceevent.aspx#comments</comments><description>&lt;p&gt;I have already made a series of blogs about EventSource starting with my &lt;a href="http://blogs.msdn.com/b/vancem/archive/2012/07/09/logging-your-own-etw-events-in-c-system-diagnostics-tracing-eventsource.aspx"&gt;tutorial introduction to EventSource&lt;/a&gt;.&amp;nbsp; This gives you enough information&amp;nbsp;to generate events, and using the PerfView tool, lets you look at these events in a viewer.&amp;nbsp; This is great for a broad variety of ad-hoc scenarios.&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; However what if you want to go further and build automation that processes your EventSource events programmatically?&amp;nbsp;&amp;nbsp;&amp;nbsp; This is what this blog entry is about.&amp;nbsp;&amp;nbsp;&amp;nbsp;Here&amp;nbsp;I show you how to use the TraceEvent library (there is a&amp;nbsp;old version of the&amp;nbsp;code available &lt;a href="http://bcl.codeplex.com/wikipage?title=TraceEvent&amp;amp;referringTitle=Home"&gt;here&lt;/a&gt;, but&amp;nbsp;the version of this DLL that is included in the ZIP file associated with this blog is much newer, and I recommend using that until the codeplex site gets updated (hopefully soon).&amp;nbsp;&amp;nbsp;&amp;nbsp; The TraceEvent library is all about reading ETW data, and it is the library that the PerfView tool itself is built upon.&amp;nbsp;&amp;nbsp; Here we show you how easy it is to use this library to programmatically enable your EventSources and parse the results programmatically.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;You will notice that I have attached a SimpleMonitor.zip file to this blog entry.&amp;nbsp; This zip file contains the TraceEvent.dll library as well as a simple, one page demonstration&amp;nbsp;application called 'SimpleMonitor'.&amp;nbsp;&amp;nbsp; To demonstrate the 'end-to-end' scenario, this application contains both parts: the EventSource that generated the events as well as the logic that turns on the EventSource and parses the resulting events.&amp;nbsp;&amp;nbsp; Normally these two parts would be in different processes but to make the demo super-simple to run, both parts are in the same executable.&amp;nbsp;&amp;nbsp;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;The Event Generator generates 3 types of events, MyFirstEvent, MySecondEvent, and Stop.&amp;nbsp;&amp;nbsp; It happens to generate the first two once a second for 10 seconds then logs the Stop event and then goes silent.&amp;nbsp;&amp;nbsp;&amp;nbsp; The listener code turns on this provider, watches for these particular events, takes different actions on each of them, using the event payloads in the events in the processing.&amp;nbsp;&amp;nbsp; The processing consists of computing the time delay between the 'MyFirstEvent' and 'MySecondEvent'.&amp;nbsp;&amp;nbsp; When it sees the 'Stop' event the listener shuts down and the whole program exits.&amp;nbsp; This example is simple enough to demonstrate&amp;nbsp;the end-to-end process in a small amount of code.&amp;nbsp;&amp;nbsp; Here is a condensed version where I simplified it to highlight the essentials.&amp;nbsp;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&amp;nbsp; &lt;a href="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-38-00/8546.Capture.PNG"&gt;&lt;img src="http://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-38-00/8546.Capture.PNG" alt="" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;Basically you create a TraceEventSession which is a 'sink' which represents a stream of ETW events.&amp;nbsp; These sessions are KERNEL objects, and in particular they can live beyond the lifetime of the process that created them (thus you can have one process 'start' a session' and another 'stop' it.&amp;nbsp;&amp;nbsp;&amp;nbsp; You can create a session that logs to a file, but in this case we passed 'null' as the file name which means we don't want it to go to a file but we will read it in 'real time'.&amp;nbsp;&amp;nbsp;&amp;nbsp; Session are for CONTROLLING ETW sessions (thus you see that later we do an 'EnableProvider' on the session to turn on the particular EventSource we want.&amp;nbsp; You an turn on many providers on the same session, but in this case we did only one.&amp;nbsp;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Because we want to READ the data that is being logged to this session in real time, we attach a 'ETWTraceEventSource' to the session.&amp;nbsp; This knows how to READ etw events.&amp;nbsp; You can tell this to read from a file, but in our case we told it to read in real time directly from 'My session', so this is where it will get its data.&amp;nbsp;&amp;nbsp;&amp;nbsp; Now an ETWTraceEventSource knows how to read ETW events, but every different provider has its own different 'payloads' and you need something that understand the particular payload for the events you are interested in decoding completely.&amp;nbsp;&amp;nbsp; This is what a 'TraceEventParser' is: something that knows how to parse a PARTICULAR provider's events.&amp;nbsp;&amp;nbsp; We will see in later blog entries how we can create TraceEventParsers that are designed to decode just ONE EventSource's events, however in this case we are using the 'DynamicTraceEventParser' which knows how to decode ANY EventSource (but can only do so relatively inefficiently and is relatively cumbersome to code against).&amp;nbsp;&lt;/p&gt;
&lt;p&gt;One way you can get parsed events from a TraceEventParser is to ask the parser to call you back when a particular event happens.&amp;nbsp;&amp;nbsp; In this case we ask the DynamicTraceEventParser, to call us back whenever any event happens (by subscribing to the 'All' event).&amp;nbsp;&amp;nbsp; Thus the anonymous delegate shown above get a callback whenever any event happens that the 'DynamicTraceEventParser' knows how to parse (which includes all EventSources).&amp;nbsp;&amp;nbsp;&amp;nbsp; In the demo we simply print the event (which will show you all the payload fields printed out nicely as XML), and look for an event called 'Stop'.&amp;nbsp;&amp;nbsp; When that happens to close the source (which stops the listern).&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Once we have set up the callbacks for our READER, we turn our attention back to the SESSION and tell it to actually enable the EventSource that we want.&amp;nbsp;&amp;nbsp; From that point events are starting to accumulate in the session.&amp;nbsp;&amp;nbsp; We then call the 'Process()' event on the SOUCE (the reader), which will start reading events from the session and dispatching them to the parsers which dispatch them to our callback.&amp;nbsp;&amp;nbsp;&amp;nbsp; This continues until there are 'no more events'.&amp;nbsp; For files, this is the end of the file, but for real-time sessions, it only stops when the source is closed (which we do when we see the Stop() event).&amp;nbsp;&lt;/p&gt;
&lt;p&gt;So in recap to get at EventSource event programmatically you&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Create a session which allows you to turn on and off particular event sources&lt;/li&gt;
&lt;li&gt;Enable one or more EventSources in the session&lt;/li&gt;
&lt;li&gt;Connect up a ETWTraceEventSource to the seesion which can READ the events&lt;/li&gt;
&lt;li&gt;Connect up a TraceEventParser, that knows how to PARSE a Particular provider's events&lt;/li&gt;
&lt;li&gt;Subscribe to the TraceEventParser's events that you are interested in.&amp;nbsp; What you get back is a fully parsed event&lt;/li&gt;
&lt;li&gt;Call source.Process() which runs the dispatch loop and only returns when all events are read (or the source is closed())&lt;/li&gt;
&lt;li&gt;Call source.Close()&amp;nbsp; or source.Dispose() (They are synonyms) when you are done&lt;/li&gt;
&lt;li&gt;Call session.Dispose() when you are done with the session (this is what the using clause does)&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;You can see that you can do all of this in just a few lines of code.&amp;nbsp;&amp;nbsp; If this piques your interest, you should definitely download the source and take a look.&amp;nbsp; It is not long (2 pages), and most of it is comments that describes in detail what the code is doing.&amp;nbsp;&amp;nbsp; It is definitely worth a read.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Next time I will show you how this changes when you log to a file instead.&amp;nbsp;&amp;nbsp;&amp;nbsp; In later blog entries I will also show you how you can build parsers that are specific to your EventSource, and make building the processing code easier and significantly more efficient.&amp;nbsp;&amp;nbsp;&amp;nbsp; You can also turn on other providers that are built into the OS and the .NET Runtime, and capturing stack traces when event fire, which is where things really start to get interesting.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;span style="font-size: medium;"&gt;&lt;strong&gt;Source Code Guide&lt;/strong&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;To look at the complete source, simply&amp;nbsp;open the SimpleMonitor.zip file and copy it to your machine.&amp;nbsp;&amp;nbsp; You can build the solution in Visual Studio.&amp;nbsp;&amp;nbsp;All the interesting code is in Program.cs, and only consists of about 2 pages of code which hopefully you will recognize from the snippet above.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=10379888" width="1" height="1"&gt;</description><enclosure url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-components-postattachments/00-10-37-98-88/SimpleMonitor.zip" length="647078" type="application/zip" /><category domain="http://blogs.msdn.com/b/vancem/archive/tags/ETW/">ETW</category><category domain="http://blogs.msdn.com/b/vancem/archive/tags/EventSource/">EventSource</category><category domain="http://blogs.msdn.com/b/vancem/archive/tags/TraceEvent/">TraceEvent</category></item></channel></rss>