В помощь создания поставщика счётчиков производительности v 2.0 в NET. Framework

в 7:19, , рубрики: .net

Здравствуйте друзья!
Хочу познакомить вас с пакетом в nuget DevUtils ETW IMBA, который поможет вам просто и быстро создавать счётчики производительности, поддерживающие новую архитектуру (версии 2.0) введенную в Windows Vista.

В .NET Framework 4.5 были добавлены классы в пространстве System.Diagnostics.PerformanceData, которые позволяют создавать счётчики на этой новой архитектуре, но для их использования необходимо:

  1. Описать счётчики в XML манифесте вручную, эти счетчики логически сгруппированы в наборы счетчиков. Счетчик в наборе определяется числовым идентификатором, уникальным в пределах данного набора счетчиков. Для поставщика может определяться один или более наборов счетчиков. Набор счетчиков идентифицируется по идентификатору GUID, уникальному для данного поставщика.
  2. После записи манифеста необходимо скомпилировать его с помощью средства CTRPP, которая создаёт файл .rc далее создается скомпилированный файл ресурсов (.res), который добавляется в проект.
  3. Зарегистрировать счетчики в компьютере с помощью средства LodCtr

Эта тулза делает все эти шаги за вас. Вам необходимо просто описать свои счётчики в коде:

	[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
}

И обеспечить эти счётчики данными:

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();
			// происходит какая-то работа
			Thread.Sleep(1000);
			var endTicks = Stopwatch.GetTimestamp();

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

И запустить программу.

После компиляции у вас в binDebug будут созданы два файла:

  1. <имя проекта>.IM.xml Это сам манифест, сгенерированный автоматический.
  2. <имя проекта>.IM.dll Это файл, который содержит только ресурсы. Это имена счетчиков, имена наборов, строки описание и т.д.

Так же, если у вас студия имеет права администратора, ваши счётчики будут зарегистрированы в системе и вы может сразу смотреть их результаты.

Возможность автоматической регистрации может быть отключена с помощью вставки в файл проекта.

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

Вот несколько слов, которые я хотел написать для быстрого старта использования этого пакета. Буду рад ответить на все ваши вопросы.

Автор: Gargoni

Источник


* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js