Defrag Tools: #84 - Performance Counters - Part 3

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 turning the XML manifest in to code (with CTRPP), and using the generated code in a sample application.

Resources:
Performance Counter Schema
Sample code

Timeline:
[00:00]//build/ 2014
[00:30] - [Talk is now at 12:30pm Friday]
[01:30] - [C9 Live is now at 2:30pm Thursday]
[02:42] - CTRPP - part of the Windows SDK
[04:18] - Custom Build Tool
[05:20] - ctrpp.exe -o <*.h> -rc <*.rc> -prefer <prefex> <*.man>
[11:45] - lodctr.exe /m:*.man
[13:00] - applicationIdentity path - resource strings
[14:02] - unlodctr.exe /m:*.man
[16:02] - HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Perflib\_V2Providers
[16:02] - lodctr.exe /r
[17:00] - <Prefix>CountersInitialize/Uninitialize
[21:07] - PerfSetULongCounterValue
[24:22] - PerfIncrementULongCounterValue
[28:13] - Next week, adding ETW Events
[30:26] - 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

Add Your 2 Cents