Follow Me Widget

воскресенье, 20 марта 2011 г.

Разработка приложений под Windows Azure. Знакомство с Windows Azure Diagnostics.

Добрый день. Итак мы дошли с вами до очень важной стадии разработки облачного приложения, а именно его диагностики. Естественно, что после успешного запуска любого приложения нам необходимо каким-то образом отслеживать его состояние, а также состояние ресурсов, которые оно использует. В стандартном случае, когда приложение функционирует на наших собственных серверах, как правило диагностика не вызывает особых затруднений. Мы просто заходим на машину, к примеру, через службу терминалов, и смотрим на ее состояние (загрузку процессоров, количество используемой памяти, логи операционной системы и т.д. и т.п.). В случае же использования Windows Azure не совсем понятно как это делать. Во-первых сервера могут находиться очень далеко от нас, во-вторых их может быть несколько в случае запуска приложения в более чем одном экземпляре. Поэтому логически возникает вопрос: “Можно ли каким-то образом собирать диагностическую информацию с таких приложений и можно ли делать это одновременно для всех экземпляров приложения ?”. Ответ: “Конечно же можно, именно для этого предназначена технология Windows Azure Diagnostics”. В данной публикации я постараюсь раскрыть
основные принципы по работе с этой технологией.
Что собственно мы подразумеваем под словом диагностика? Как правило это следующие вещи:
  • Измерение производительности
  • Использование ресурсов
  • Отладка и выявление проблемных мест
  • Качество предоставляемых услуг
  • Аудит
  • Анализ траффика (количество пользователей, периоды пиковой нагрузки и т.д.)
  • др. немаловажные метрики
Вы уже наверное поняли, что все вышеперечисленные метрики можно получать при помощи Azure Diagnostics. На рисунке ниже можно увидеть как работает данная технология.
Windows Azure Diagnostics
Работает это следующим образом. Как только стартует наша роль, параллельно с ней запускается отдельный процесс, называемый диагностическим монитором. В задачи этого монитора входит сбор все необходимой информации  об окружающей роль среде: о операционной системе, о счетчиках производительности и тд. и тп. По умолчанию такие данные сохраняются локально, очень близко к запущенной роли. По истечению определенного промежутка времени или по требованию из внешнего мира монитор может загрузить собранную на данный момент статистику во внешнее хранилище, откуда мы уже имеем возможность ее напрямую достать. Получается, что механизм трансфера собранных данных может быть инициирован вручную либо это может происходить периодически.
Давайте посмотрим, что собственно можно собирать и что влияет на процесс сбора.
Windows Azure Diagnostics Counters
Как видим собирать можно практически все, что душе угодно и доступно из подпространства System.Diagnostics. В зависимости от типа метрики сохраняться она будет в соответствующих хранилищах данных. Например ивент логи операционной системы пойдут в Table Storage, а креш дампы IIS отправятся в Blob Storage.
Для того, чтобы сконфигурировать монитор достаточно выполнить нескольких несложных телодвижений:
  • Получить текущую конфигурацию
  • Изменить полученную конфигурацию. добавить или убрать определенные метрики
  • Настроить интервал трансфера статистики в хранилище данных
  • Запустить монитор с новой конфигурацией
Простейший пример такого сценария представлен ниже.

Configuring Diagnostics Monitor

В продолжение хотел бы продемонстрировать небольшое приложение, позволяющей лучше понять принципы реализации диагностики в ваших приложениях. Единственная страница приложения представлена чуть ниже:

Event Log App

Давайте посмотрим на обработчик события, возникающего по клику на кнопку “Submit”.
switch (ddlType.SelectedItem.ToString())
{
case "Error":
EventLog.WriteEntry("Azure Demo", tbxMessage.Text, EventLogEntryType.Error);
break;
case "Information":
EventLog.WriteEntry("Azure Demo", tbxMessage.Text, EventLogEntryType.Information);
break;
case "Warning":
EventLog.WriteEntry("Azure Demo", tbxMessage.Text, EventLogEntryType.Warning);
break;

default:
EventLog.WriteEntry("Azure Demo", tbxMessage.Text, EventLogEntryType.Information);
break;
}
Как видите мы используем знакомое всем API из подпространства System.Diagnostics. Больший интерес вызывает фрагмент кода ответственный за конфигурацию и запуск диагностического монитора. Его можно найти в файле WebRole.cs в теле метода SetDiagnostics.
// Get default initial configuration.
var diagConfig = DiagnosticMonitor.GetDefaultInitialConfiguration();

// Capture complete crash dumps 
Microsoft.WindowsAzure.Diagnostics.CrashDumps.EnableCollection(true); 

//Set filter and sampling persistence rate.
diagConfig.DiagnosticInfrastructureLogs.ScheduledTransferLogLevelFilter = LogLevel.Error;
diagConfig.DiagnosticInfrastructureLogs.ScheduledTransferPeriod = TimeSpan.FromMinutes(1);
diagConfig.Directories.ScheduledTransferPeriod = TimeSpan.FromMinutes(1.0);
diagConfig.Logs.ScheduledTransferPeriod = TimeSpan.FromMinutes(1.0);
diagConfig.WindowsEventLog.ScheduledTransferPeriod = TimeSpan.FromMinutes(1.0);
diagConfig.PerformanceCounters.ScheduledTransferPeriod = TimeSpan.FromMinutes(1.0); 



// Adding performance counters to the default diagnostic configuration
PerformanceCounterConfiguration procTimeConfig = new PerformanceCounterConfiguration();
procTimeConfig.CounterSpecifier = @"\Processor(*)\% Processor Time";
procTimeConfig.SampleRate = System.TimeSpan.FromSeconds(1.0);
diagConfig.PerformanceCounters.DataSources.Add(procTimeConfig);

// Adding performance counters to the default diagnostic configuration
PerformanceCounterConfiguration diskBytesConfig = new PerformanceCounterConfiguration();
diskBytesConfig.CounterSpecifier = @"\LogicalDisk(*)\Disk Bytes/sec";
diskBytesConfig.SampleRate = System.TimeSpan.FromSeconds(1.0);
diagConfig.PerformanceCounters.DataSources.Add(diskBytesConfig);

// Buffer event logs locally
diagConfig.WindowsEventLog.DataSources.Add("System!*");
diagConfig.WindowsEventLog.DataSources.Add("Application!*");


//custom logs                    
LocalResource localResource = RoleEnvironment.GetLocalResource("MyCustomLogs");
DirectoryConfiguration dirConfig = new DirectoryConfiguration();
dirConfig.Container = "wad-my-custom-container";
dirConfig.DirectoryQuotaInMB = localResource.MaximumSizeInMegabytes;
dirConfig.Path = localResource.RootPath;
diagConfig.Directories.DataSources.Add(dirConfig);

roleInstanceDiagnosticManager.SetCurrentConfiguration(diagConfig); 


// Start the diagnostic monitor with the modified configuration.
DiagnosticMonitor.Start("DiagnosticsConnectionString", diagConfig); 
Давайте рассмотрим этот метод более детально. Для начала, как я и говорил выше, нам необходимо получить текущую конфигурацию монитора. Делается это при помощи этой строки кода:
var diagConfig = DiagnosticMonitor.GetDefaultInitialConfiguration();
Далее следует код настройки уровня захватываемых сообщений, а также периоды трансфера статистики в постоянное хранилище. Можно догадаться, что захватывать мы будем только ошибки и переносить их в постоянное хранилище будем каждую минуту.
diagConfig.DiagnosticInfrastructureLogs.ScheduledTransferLogLevelFilter = LogLevel.Error;
diagConfig.DiagnosticInfrastructureLogs.ScheduledTransferPeriod = TimeSpan.FromMinutes(1);
diagConfig.Directories.ScheduledTransferPeriod = TimeSpan.FromMinutes(1.0);
diagConfig.Logs.ScheduledTransferPeriod = TimeSpan.FromMinutes(1.0);
diagConfig.WindowsEventLog.ScheduledTransferPeriod = TimeSpan.FromMinutes(1.0);
diagConfig.PerformanceCounters.ScheduledTransferPeriod = TimeSpan.FromMinutes(1.0); 
Кроме того, в данном приложении мы решаем, что было бы неплохо собирать и хранить некоторые метрики производительности, поэтому для этого мы добавляем в конфигурацию счетчики, отслеживающие параметры процессора и диска.
// Adding performance counters to the default diagnostic configuration
PerformanceCounterConfiguration procTimeConfig = new PerformanceCounterConfiguration();
procTimeConfig.CounterSpecifier = @"\Processor(*)\% Processor Time";
procTimeConfig.SampleRate = System.TimeSpan.FromSeconds(1.0);
diagConfig.PerformanceCounters.DataSources.Add(procTimeConfig);

// Adding performance counters to the default diagnostic configuration
PerformanceCounterConfiguration diskBytesConfig = new PerformanceCounterConfiguration();
diskBytesConfig.CounterSpecifier = @"\LogicalDisk(*)\Disk Bytes/sec";
diskBytesConfig.SampleRate = System.TimeSpan.FromSeconds(1.0);
diagConfig.PerformanceCounters.DataSources.Add(diskBytesConfig); 
Также желательно было бы получать информацию из системных датасорсов.
// Buffer event logs locally
diagConfig.WindowsEventLog.DataSources.Add("System!*");
diagConfig.WindowsEventLog.DataSources.Add("Application!*");
В конце концов в Windows Azure Diagnostics присутствует возможность настроить свои кастомные логи, что можно увидеть в следующем фрагменте кода:
//custom logs                    
LocalResource localResource = RoleEnvironment.GetLocalResource("MyCustomLogs");
DirectoryConfiguration dirConfig = new DirectoryConfiguration();
dirConfig.Container = "wad-my-custom-container";
dirConfig.DirectoryQuotaInMB = localResource.MaximumSizeInMegabytes;
dirConfig.Path = localResource.RootPath;
diagConfig.Directories.DataSources.Add(dirConfig);
После того, как конфигурация полностью настроена, необходимо установить ее как единственно верную и запустить монитор с новыми настройками:
roleInstanceDiagnosticManager.SetCurrentConfiguration(diagConfig);
// Start the diagnostic monitor with the modified configuration.
DiagnosticMonitor.Start("DiagnosticsConnectionString", diagConfig); 
Для того, чтобы увидеть наши диагностические сообщения, откроем локальное хранилище (таблица с именем WADWindowsEventLogsTable) в Visual Studio, где мы с легкостью сможем их найти.

Azure Tables As Logs Storage

Итак, как видите Windows Azure располагает прекрасными возможностями по диагностированию и анализу ваших приложений, запущенных в облаке. Причем набор средств для осуществления диагностики остался неизменным – это все те же наборы классов из подпространства System.Configuration, что значительно облегчает и ускоряет разработку таких решений.
На этом я хотел бы закончить данную публикацию. Исходный код представленного здесь приложения можно скачать по следующей ссылке: Забрать

Комментариев нет: