Исходники.Ру - Программирование
Исходники
Статьи
Книги и учебники
Скрипты
Новости RSS
Магазин программиста

Главная » Статьи по программированию » .NET - Все статьи »

Обсудить на форуме Обсудить на форуме

Performance Counters - посчитаем в наших программах.

В состав Win2000 входит элемент управления ActiveX под названием System Monitor(SM). Он позволяет администраторам просматривать сведения о производительности. Чтобы поэкспериментировать с контролом выберите в меню Administrative Tools пункт Performance. Кроме того, системный монитор можно добавить в Microsoft Management Console(MMC):
  • запустите Microsoft Management Console(mmc.exe)
  • в меню Console выберите пункт Add/Remove snap-in и щёлкните кнопку Add
  • в диалоговом окне Add Standalone Snap-in выберите ActiveX Control и щёлкните кнопку Add
  • в первом экране мастера щёлкните кнопу Next, а затем кнопку Finish
  • в диалоговом окне Add/Remove Snap-in щёлкните кнопку Ok
  • выберите узел System Monitor Control в левой панели окна

В начале SM не знает какую информацию ему отслеживать, для этого нужно вызвать диалоговое окно AddCounters, щёлкнув правой кнопочкой мышки или нажать на “+“ на тулбаре.

Сперва нужно выбрать компьютер, с которого будут собираться данные, но так как это и будет наш компьютер - там ничего не трогаем. Выбрав компьютер, нужно определить объект измерений, т.е. компонент системы, для которого можно получить сведения о производительности. Есть куча объектов, для которых можно получать эти сведения. Выберем, например, PhysicalDisk. Этот объект имеет несколько счётчиков. Мы можем их выбрать из списка Select Counters From List.

Каждая запись определяет один из типов измерений производительности жёсткого диска. Выбрав объект измерений, можно перейти к другой части диалогового окна - списку Select instances from list. Экземпляр(instance) - это название экземпляра объекта. Например, если это жёсткие диски, то их может быть несколько если процессы, то в системе их может быть запущено сколько угодно. Экземпляры поддерживаются большинством объектов, но не всеми.

Существует много причин, по которым стоит рассмотреть возможность добавления информации счётчиков производительности в ваши приложения. Первая, и самая главная - упрощение работы администраторов и служб сопровождения по проверке компьютерных систем. Далее, пользователи большинства приложений вряд ли захотят погрязнуть в огромном количестве информации совершенно не нужной им. Намного удобнее передавать эти сведения через счётчики.

Проектируя своё приложение, точно определитесь, какую информацию вы хотите отслеживать. Если, например, в программе есть цикл, в котором производятся расчёты, то там лучше счётчики не обновлять. С другой стороны, если вы разрабатываете серверную часть клиент-серверного приложения, тогда вам могут понадобиться счётчики для отслеживания количества подключённых клиентов, размеры данных полученных от клиентов и передаваемых им и т.д. Раньше создание счётчиков на VC++ было весьма сложным делом (про создание счётчиков на Visual C++ читать Рихтера "Программирование серверных приложений для Windows 2000"), но с выходом .Net всё изменилось. В .Net уже встроены объекты, которые позволяют очень быстро создавать счётчики. Мы на примере постараемся создать счётчики которые бы подсчитывали количество принятых байт в секунду(объяснять как перехватывать пакеты я не буду – для этого читайте MSDN и PSDK, там кажется есть про Raw сокеты, если лень там искать читайте на www.firststeps.ru). Эти счетчики могут понадобиться в нескольких случаях, приведу один из них.

К примеру у нас есть машина, используемая как роутер для доступа в Интернет. Доступ осуществляется через двух провайдеров. Всё хорошо, но может возникнуть ситуация, когда на один канал ложится основная нагрузка, а второй канал при этом простаивает, и администратору нужно будет изменить таблицу роутинга. Чтобы узнать нагрузку на каналы можно использовать эту программу.

Попытаюсь отобразить на схеме, что мы хотим получить:

  Category: Traffic
IGMP ICMP TCP UDP Unknown
Counter:
10.100.100.130
yes Yes Yes yes yes
Counter:
80.1.0.73
yes Yes Yes yes yes

То есть нам нужно создать категорию Traffic(Performance object), далее создать счётчики по IP (у меня на машине их на самом деле больше, чем указано в таблице) и потом несколько экземпляров счетчиков для каждого ip адреса (icmp, tcp и т.д. пакеты).

Для работы с категориями используются объекты System.Diagnostics.PerformanceCounterCategory.

Сначала мы должны проверить, создана ли уже категория Traffic. Для этого воспользуемся статическим методом Exists.

if(!PerformanceCounterCategory.Exists(_CategoryName))
{
 ...
}

Далее нам нужно создать счётчики для этой категории. Для этого воспользуемся классом System.Diagnostics.CounterCreationData, описывающим счётчик. Попробуем создать описание счётчика:

   CounterCreationData ccd = new CounterCreationData();
   ccd.CounterType = PerformanceCounterType.NumberOfItems32;
   ccd.CounterName = _ip;

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

Особое внимание стоит уделить свойству CounterType, которое определяет тип счётчика. Тип PerformanceCounterType, с помощью которого задается свойство CounterCreationData.CounterType, является перечисленим. Некоторые типы счётчиков представляют собой просто данные, в то время как другие могут представлять вычисляемые значения на основе нескольких других счётчиков. Сейчас я попробую описать основные категории:

  • Average: обычно отображает среднее значение последних двух значений.
  • Difference: обычно разница между двумя последними значениями. Если эта разница положительная, то всё в порядке иначе 0
  • Instantaneous: отображают последние значение измерения
  • Percentage: отображает вычисляемое значение в процентах
  • Rate: обычно используется для отображения увеличивающихся данных. Эти счетчики похожи на Average, но полезны в случае увеличения показателя того, как используется ресурс. Вычисляется по формуле ((Xn -X 0)/(T n -T 0))/ frequency, где Xn - это N значение, Tn - время когда было получено Xn, а frequency - количество тиков в секунду (обычно они используются для счётчиков типа "операций в секунду")

Для каждого типа счётчика используются свои формулы или используется несколько счётчиков (сперва должен идти счётчик одного типа, за ним – другого, и на основе их значений вычисляется значение). Более подробно вы можете почитать про это в SDK. Так как нам ничего такого не надо мы будем использовать просто счётчики типа NumberOfItems32.

Итак, после создания класса описания счётчика мы добавляем его в коллекцию типа CounterCreationDataCollection.

ccds = new CounterCreationDataCollection();
for(…)
{
ccds.Add(ccd);
}

И создаём категорию

PerformanceCounterCategory.Create(_CategoryName, _CategoryHelp,ccds);

Теперь для работы со счётчиками нам нужно создать экземпляры класса PerformanceCounter.

Для этого воспользуемся конструктором типа

PerformanceCounter(_CategoryName, _CounterName,  _Instance, _readwrite);

где
_CategoryName - имя категории
_CounterName - имя счётчика
_Instance - имя экземпляра счётчика (если его не указывать, то почему-то получаем доступ к счётчику и не можем создавать экземпляры)
_readwrite - если этот параметр true, то мы можем только получать значения счётчика, если false, то можно изменять (системные счётчики изменять нельзя)

у меня данный конструктор вызывается следующим образом

PerformanceCounter(_CategoryName, _ip, "IGMP", false);

после чего я вызываю метод UpdateInstances() для создания остальных экземпляров:

      public void UpdateInstances()
      {
          if(_counter != null)
          {
            _counter.InstanceName = "IGMP";
            _counter.RawValue = igmp_total;

            _counter.InstanceName = "ICMP";
            _counter.RawValue = icmp_total;

            _counter.InstanceName = "TCP";
            _counter.RawValue = tcp_total;

            _counter.InstanceName = "UDP";
            _counter.RawValue = udp_total;

          }
      }

Для обращения к экземпляру счётчика следует указать имя экземпляра через InstanceName:

_counter.InstanceName = "UDP";

после чего мы будем обращаться к экземпляру UDP. А изменить значение можно через свойство RawValue:

_counter.RawValue = udp_total;

Либо же можно использовать методы IncrementBy, Increment или Decrement для изменения значения счётчика.

Нам остаётся только каждую, секунду обновлять значение счётчика(я для этого воспользовался объектом Timer).

        private void OnTimer(object sender, System.EventArgs e)
        {
         _PerformanceObject.UpdateAllCounters();
        }

Текст примеров данной статьи можно выкачать здесь


Может пригодится:


Автор: Леонид Молочный
Прочитано: 6885
Рейтинг:
Оценить: 1 2 3 4 5

Комментарии: (0)

Добавить комментарий
Ваше имя*:
Ваш email:
URL Вашего сайта:
Ваш комментарий*:
Код безопастности*:

Рассылка новостей
Рейтинги
© 2007, Программирование Исходники.Ру