Defrag Tools: #83 - Performance Counters - Part 2

Sign in to queue

Description

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>

Embed

Download

The Discussion

  • User profile image
    BrianCatlin

    Why don't you use ECManGen.exe (Event/Counter Manifest Generator) in the SDK for creating your manifest?

  • User profile image
    windev

    @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.

  • User profile image
    Seth Moore

    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.

Add Your 2 Cents