Defrag Tools: #82 - Performance Counters - Part 1

In this episode of Defrag Tools, Andrew Richards and Chad Beeder continue a 3-part series on how Performance Counters work and how to add them to an application. This episode focuses on the XML manifest that you develop, that turns in to code when compiled with CTRPP.
Resources:
Performance Counter Schema
Timeline:
[00:00] - XML Manifest
[01:56] - XSD
[02:33] - GUID Generator
[03:43] - *.man or *.manifest file
[06:06] - Provider
[08:06] - CounterSet
[11:30] - Counter
[13:30] - CounterAttribute
[18:00] - Default Scale - 10^N
[23:17] - Email us your issues at defragtools@microsoft.com
Example Manifest:
<?xml version='1.0' encoding='utf-8' standalone='yes'?> <instrumentationManifest xmlns="https://schemas.microsoft.com/win/2004/08/events" xmlns:win="https://manifests.microsoft.com/win/2004/08/windows/events" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" > <instrumentation> <counters xmlns="https://schemas.microsoft.com/win/2005/12/counters" schemaVersion="2.0" > <provider applicationIdentity = "c:\Demo\Counters.exe" providerGuid = "{781D84EC-6AFF-4adb-87C6-59A7D6D61CDC}" providerName = "MyApp" providerType = "userMode" symbol = "MyApp" > <counterSet guid = "{7033575E-88B4-4155-BE5B-9E09E120D811}" uri = "MyApp.PerfCounters.MyAppCounterSet" symbol = "MyAppCounterSet" name = "My App" nameID ="1002" description = "My App Counters" descriptionID = "1004" instances = "multipleAggregate" > <!-- Requests --> <counter id = "1" type = "perf_counter_large_rawcount" uri = "MyApp.PerfCounters.MyAppCounterSet.Requests" name = "Requests" nameID = "2012" description = "My App - Requests" descriptionID = "2014" aggregate = "sum" detailLevel = "standard" defaultScale = "-2"> </counter> <counter id = "2" type = "perf_counter_large_delta" uri = "MyApp.PerfCounters.MyAppCounterSet.RequestsSec" name = "Requests/period" nameID = "2022" description = "My App - Requests/period" descriptionID = "2024" aggregate = "avg" detailLevel = "standard" defaultScale = "0"> </counter> <!-- Request Duration --> <counter id = "3" type = "perf_average_timer" baseID = "4" uri = "MyApp.PerfCounters.MyAppCounterSet.RequestTimeAvg" name = "Request Duration (secs)/avg" nameID = "2032" description = "My App - Average Request Duration (secs)" descriptionID = "2034" aggregate = "avg" detailLevel = "standard" defaultScale = "1"> </counter> <counter id = "4" type = "perf_average_base" uri = "MyApp.PerfCounters.MyAppCounterSet.RequestTimeBase" name = "Request Duration/ops" nameID = "2042" description = "My App - Average Request Duration Operations" descriptionID = "2044" detailLevel = "standard"> <counterAttributes> <counterAttribute name = "noDisplay" /> </counterAttributes> </counter> </counterSet> </provider> </counters> </instrumentation> </instrumentationManifest>
Why don't you use ECManGen.exe (Event/Counter Manifest Generator) in the SDK for creating your manifest?
@BrianCatlin: I was going to mention it but decided not to. You need to know what the schema is to use the tool effectively. Personally, I think writing the XML directly is as easy as using the tools.
For GUID generation, I've found PowerShell is really handy:
PowerShell -c "[System.Guid]::NewGuid().ToString()"
This just dumps a new GUID any time I need one.