Click here to Skip to main content
15,887,676 members
Articles / Programming Languages / C#
Tip/Trick

To Help Create Provider Performance Counters v 2.0 in NET. Framework

Rate me:
Please Sign up or sign in to vote.
5.00/5 (2 votes)
17 Apr 2015CPOL1 min read 17.3K   3   5
This tip will help create Provider Performance Counters v 2.0 in NET. Framework

Introduction

I want to introduce you to a package in nuget DevUtils ETW IMBA, which will help you simply and quickly create performance counters that support the new architecture (2.0) introduced in Windows Vista..

Background

In .NET Framework 4.5, classes in the space System.Diagnostics.PerformanceData have been added, which allow you to create counters on this new architecture. But to use them, you must do the following:

  1. To describe counters in the XML manifest manually, these counters are logically grouped into sets of counters. The counter in the set defined by the numerical identifier, unique within the set of counters. The provider may define one or more sets of counters. Counter set is identified by a GUID unique to the provider.
  2. After recording a manifest, you need to compile it with the means CTRPP, which creates a .rc file. Next, create a compiled resource file (.res), which is added to the project.
  3. Sign-up counters in the computer by using the LodCtr.

This package does all of these steps for you.

Using

You need to simply describe their counters in the code:

C#
 [CounterSource(Guid = "{ab8e1320-965a-4cf9-9c07-fe25378c2a23}")]
 sealed class MyCounterSource
 {
     #region MyLogicalDiskSet

     [CounterSet(CounterSetInstances.Multiple,
         Name = "My LogicalDisk",
         Description = "This is a sample counter set with multiple instances.")]
     public enum MyLogicalDiskSet
     {
         [Counter(CounterType.PerfCounterRawcount,
             DefaultScale = 1,
             Name = "My Free Megabytes",
             Description = "First sample counter.",
             DetailLevel = CounterDetailLevel.Standard)]
         MyFreeMegabytes = 1,

         [CounterAttributeReference]
         [CounterAttributeDisplayAsReal]
         [Counter(CounterType.PerfAverageTimer,
             DefaultScale = 1,
             BaseId = (int)MyAvgDiskTransfer,
             Name = "My Avg. Disk sec/Transfer",
             Description = "Second sample counter.",
             DetailLevel = CounterDetailLevel.Advanced)]
         MyAvgDiskSec,

         [CounterAttributeNoDisplay]
         [Counter(CounterType.PerfAverageBase,
             DetailLevel = CounterDetailLevel.Advanced)]
         MyAvgDiskTransfer,
     }

     #endregion

     #region MySystemObjectsSet

     [CounterSet(CounterSetInstances.Single,
         Name = "My System Objects",
         Description = "My System Objects Help.")]
     public enum MySystemObjectsSet
     {
         [CounterAttributeDisplayAsHex]
         [CounterAttributeNoDigitGrouping]
         [Counter(CounterType.PerfCounterRawcount,
             DefaultScale = 1,
             Name = "Process Count",
             Description = "Process Count Help.")]
         ProcessCount = 1,

         [Counter(CounterType.PerfCounterRawcount,
             Name = "Thread Count",
             Description = "Thread Count Help.")]
         ThreadCount,

         [Counter(CounterType.PerfElapsedTime,
             DefaultScale = 1,
             PerfTimeId = (int)SystemTime,
             PerfFreqId = (int)SystemFreq,
             Name = "System Elapsed Time",
             Description = "System Elapsed Time Help.",
             DetailLevel = CounterDetailLevel.Advanced)]
         SystemElapsedTime,

         [CounterAttributeNoDisplay]
         [Counter(CounterType.PerfCounterLargeRawcount)]
         SystemTime,

         [CounterAttributeNoDisplay]
         [Counter(CounterType.PerfCounterLargeRawcount)]
         SystemFreq
     }

     #endregion
}

And provide data in these counters:

C#
public static void Test()
{
    using (var diskSet = new CounterSet<MyLogicalDiskSet>())
    using (var objectsSet = new CounterSet<MySystemObjectsSet>())
    using (var diskSetInst = diskSet.CreateInstance("Default"))
    using (var objectsSetInst = objectsSet.CreateInstance("Default"))
    {
        var processCount = objectsSetInst[MySystemObjectsSet.ProcessCount];
        var myAvgDiskSec = diskSetInst[MyLogicalDiskSet.MyAvgDiskSec];
        var myAvgDiskTransfer = diskSetInst[MyLogicalDiskSet.MyAvgDiskTransfer];

        processCount.Value = 2;

        for (var i = 0; i < 10; ++i)
        {
            var beginTicks = Stopwatch.GetTimestamp();

            // takes some work
            Thread.Sleep(1000);

            var endTicks = Stopwatch.GetTimestamp();

            myAvgDiskSec.IncrementBy(endTicks - beginTicks);
            myAvgDiskTransfer.IncrementBy(1);
        }
    }
}

And build a project.

After build, you will have two files in "bin\Debug\":

  1. <project name>.IM.xml: This is the manifest itself, automatically generated.
  2. <project name>.IM.dll: This is the file that contains only resources. These are the names of counters, set names, line description, etc.

Also, if you have a VS with administrator rights, your counter will be registered in the system and you can immediately see their results.

Image 1

Note: You can disable automatic registration by inserting section into the project file.

XML
<PropertyGroup>
    <IMBASkipInstallManifest>true</IMBASkipInstallManifest>
</PropertyGroup> 

History

  • Initial release

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer (Senior) Congree Language Technologies GmbH
Russian Federation Russian Federation
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
QuestionDefaultScale should be an int type Pin
sansegot7-Oct-16 5:08
sansegot7-Oct-16 5:08 
AnswerRe: DefaultScale should be an int type Pin
|\/|ax22-Mar-17 3:23
|\/|ax22-Mar-17 3:23 
GeneralMy vote of 5 Pin
sansegot7-Oct-16 1:24
sansegot7-Oct-16 1:24 
QuestionThanks for this great tool! Pin
sansegot7-Oct-16 1:21
sansegot7-Oct-16 1:21 
AnswerRe: Thanks for this great tool! Pin
|\/|ax22-Mar-17 3:26
|\/|ax22-Mar-17 3:26 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.