Отладка приложений в Windows Azure

advertisement
Практическая работа
Отладка приложений в Windows Azure
Версия работы:
1.0.0
Дата последнего изменения: 1/16/2016
Страница | 1
СОДЕРЖАНИЕ
ОБЩИЕ СВЕДЕНИЯ ................................................................................................................................... 3
УПРАЖНЕНИЕ 1. ОТЛАДКА ПРИЛОЖЕНИЯ В ОБЛАКЕ ....................................................................... 5
Задача 1. Подготовка приложения Fabrikam Insurance ................................................................... 5
Задача 2. Запуск приложения в качестве проекта Windows Azure ................................................. 7
Задача 3. Добавление в приложение поддержки трассировки ................................................... 14
Задача 4. Создание средства просмотра журнала ......................................................................... 25
Проверка ............................................................................................................................................ 33
СВОДКА ..................................................................................................................................................... 38
Страница | 2
Общие сведения
С помощью среды Visual Studio приложения можно отлаживать на локальном компьютере
путем пошагового прохождения кода, задания точек останова и анализа значений программных
переменных. При работе с приложениями Windows Azure эмулятор вычислений позволяет
выполнять код локально и отлаживать его с помощью тех же функций и методов, что делает
процесс отладки относительно несложным.
В идеале следует использовать эмулятор вычислений, а с помощью среды Visual Studio
определять и исправлять большинство ошибок в коде, поскольку это наиболее производительная
среда для отладки. Тем не менее некоторые ошибки могут остаться незамеченными и проявятся
только после развертывания приложения в облаке. Такие ошибки часто являются результатом
отсутствия зависимостей, либо их причина заключается в различиях среды выполнения.
Дополнительные сведения о проблемах, связанных со средой, см. в разделе Различия между
эмулятором вычислений и Windows Azure.
После развертывания приложения в облаке подключиться к нему из отладчика будет
невозможно. Вместо этого для диагностики и устранения неисправностей приложения придется
использовать сведения для отладки, заносимые в журналы. Windows Azure предоставляет все
возможности для диагностики, позволяющие записывать сведения из разных источников, включая
журналы приложений Windows Azure, журналы служб IIS, трассировки сбойных запросов,
журналы событий Windows, пользовательские журналы ошибок и аварийные дампы. Эти
диагностические сведения предоставляет Windows Azure Diagnostics Monitor, который собирает
данные от отдельных источников ролей и передает эти сведения в хранилище Windows Azure для
агрегата. После того как эти данные попали в хранилище, их можно получать и анализировать.
Цели
В рамках этой практической работы вы:

Узнаете, какие компоненты и технологии имеются в среде Visual Studio и Windows Azure
для отладки приложений, развернутых в Windows Azure.

Используете простой TraceListener для занесения данных непосредственно в хранилище
таблиц и средство просмотра для открытия этих журналов.
Предварительные требования
Для выполнения этой практической работы требуется:

IIS 7 (с ASP.NET, HTTP-активация WCF)

Microsoft .NET Framework 4.0

Microsoft Visual Studio 2010

Средства Windows Azure для Microsoft Visual Studio 1.6
Страница | 3
Установка
Для выполнения упражнений, приведенных в этой практической работе, необходимо установить
среду.
1. Откройте проводник Windows и перейдите в папку Source практической работы.
2. Дважды щелкните файл Setup.cmd в этой папке, чтобы запустить процесс установки,
который настроит среду и установит фрагменты кода Visual Studio для этой практической
работы.
3. Если откроется диалоговое окно контроля учетных записей, подтвердите выполнение
действия.
Примечание. Перед запуском программы установки удостоверьтесь в выполнении
предварительных условий для выполнения этой практической работы.
Использование фрагментов кода
По всему тексту практической работы имеются инструкции по вставке блоков кода. Для удобства
большая часть этого кода предоставляется в виде фрагментов кода Visual Studio, которые можно
использовать в Visual Studio 2010, чтобы не добавлять код вручную.
Если вы не знакомы с фрагментами кода Visual Studio, то научиться пользоваться ими можно
в документе Setup.docx в папке Assets обучающего набора, в котором есть раздел с описанием
использования таких фрагментов.
Упражнения
В этой практической работе есть следующие упражнения:
1. Отладка приложения в облаке
Предполагаемое время выполнения данной практической работы: 40 минут.
Примечание. При первом запуске Visual Studio необходимо выбрать одну из коллекций
стандартно заданных параметров. Каждая такая стандартная коллекция параметров
предназначена для определенного стиля разработки, она определяет расположение окон,
поведение редактора, фрагменты кода IntelliSense и параметры диалоговых окон. Приведенные
в этом практическом задании процедуры описывают действия, которые необходимо предпринять
для выполнения определенной задачи в Visual Studio с использованием коллекции Общие
параметры разработки. Если выбрать другую коллекцию параметров для среды разработки,
то эти процедуры могут оказаться для вас не совсем точными, это следует учитывать.
Страница | 4
Упражнение 1. Отладка приложения в
облаке
Поскольку средство Windows Azure Diagnostics предназначено главным образом для
отслеживания работы приложений и ему приходится выполнять сбор сведений от нескольких
экземпляров ролей, ему требуется, чтобы диагностические данные сначала передавались
из локального хранилища в каждую роль в хранилище Windows Azure, где выполняется их
статистическая обработка. Для этого требуется программная плановая передача, при которой
монитор диагностики копирует заносимые в журнал данные в хранилище Windows Azure
через определенные промежутки времени, либо для этого требуется передача журналов по
требованию. Более того, полученные таким образом сведения формируют моментальный снимок
диагностических данных, имевшихся на момент передачи. Для получения обновленных данных
требуется новая передача. При отладке одной роли, особенно на этапе разработки, эти действия
вносят ненужную сложность в процесс. Чтобы упростить получение диагностических данных
от развернутой роли, лучше считывать сведения непосредственно из хранилища Windows Azure,
потому что никаких дополнительных действий при этом не требуется.
В этом упражнении выполняется отладка простого приложения. Для этого настраивается специальный
прослушиватель трассировки, который может записывать свои выходные данные прямо в таблицу
в эмуляторе хранилища Windows Azure. Чтобы сформировать диагностические данные, в приложении
указывается, что оно должно записывать свои данные трассировки с помощью стандартных методов
пространства имен System.Diagnostics. И наконец, вы создадите простое приложение просмотра
журнала, способное получать и отображать содержимое таблицы диагностики.
Приложение, которое используется для этого упражнения, имитирует размещаемый на сайте
калькулятор стоимости полиса автострахования. Оно содержит одну форму, в которую пользователи
вводят данные своего автомобиля, затем эта форма отправляется с тем, чтобы получить примерную
сумму, в которую обойдется страховка. Затем действие контроллера, которое обрабатывает форму,
использует отдельную сборку для вычисления стоимости по введенным пользователем данным.
В этой сборке имеется ошибка, из-за которой она формирует исключение при получении входных
значений, находящихся за пределами определенного диапазона.
Задача 1. Подготовка приложения Fabrikam Insurance
В рамках этой задачи вы построите и запустите приложение на сервере веб-разработки, чтобы
познакомиться с его работой.
1. Откройте среду Visual Studio с правами администратора, выбрав Пуск | Все программы |
Microsoft Visual Studio 2010, щелкнув правой кнопкой мыши пункт Microsoft Visual Studio
2010 и выбрав команду Запуск от имени администратора.
2. Если откроется диалоговое окно Контроль учетных записей, нажмите кнопку Продолжить.
3. В меню Файл выберите пункт Открыть, затем щелкните Проект/Решение. В диалоговом окне
Открытие проекта перейдите в папку Ex1-LoggingToAzureStorage в каталоге Source
практической работы и выберите папку, соответствующую предпочитаемому вами языку
(Visual C# или Visual Basic). Выберите файл Begin.sln в папке Begin и нажмите кнопку Открыть.
Страница | 5
4. Выберите действие при запуске проекта. Для этого в обозревателе решений щелкните
правой кнопкой мыши проект FabrikamInsurance и выберите команду Свойства. В окне
свойств перейдите на вкладку Интернет и в разделе Действие при запуске выберите
параметр Указанная страница. Оставьте поле, в котором указывается страница, пустым.
Рис. 1
Задание действия при запуске проекта
5. Нажмите клавишу F5, чтобы построить и запустить решение. Приложение должно
запуститься на сервере веб-разработки и открыть свою страницу Стоимость полиса
автострахования в браузере.
6. Чтобы ознакомиться с работой приложения, заполните форму, выбрав любое сочетание
значений из раскрывающихся списков Данные автомобиля, а затем нажмите кнопку
Рассчитать, чтобы получить примерную стоимость страховки. Обратите внимание на то,
что после отправки формы страница обновится и на ней отобразится вычисленное
значение.
Страница | 6
Рис. 2
Ознакомление с приложением Fabrikam Insurance
7. Нажмите клавиши SHIFT + F5, чтобы остановить отладку и завершить работу приложения.
Задача 2. Запуск приложения в качестве проекта Windows Azure
В рамках выполнения этой задачи вы создадите новый проект Windows Azure, чтобы подготовить
приложение к развертыванию в Windows Azure.
1. Добавьте в решение новый проект Windows Azure. Для этого в меню Файл укажите пункт
Добавить и выберите команду Новый проект. В диалоговом окне Добавление нового
Страница | 7
проекта выберите предпочитаемый язык (Visual C# или Visual Basic) в списке Установленные
шаблоны, а затем выберите Облако. Выберите шаблон Проект Windows Azure, в качестве
имени проекта укажите FabrikamInsuranceService и примите предложенное расположение
в папке решения. Чтобы создать проект, нажмите кнопку ОК.
Рис. 3
Создание нового проекта Windows Azure (C#)
Страница | 8
Рис. 4
Создание нового проекта Windows Azure (Visual Basic)
2. В диалоговом окне Создание проекта Windows Azure нажмите кнопку ОК, не добавляя
в решение никаких новых ролей.
3. Теперь в обозревателе решений щелкните правой кнопкой мыши узел Роли в новом
проекте FabrikamInsuranceService, укажите пункт Добавить и выберите Проект веб-роли
в решение. Затем в диалоговом окне Связь с проектом роли выберите проект
FabrikamInsurance и нажмите кнопку ОК.
Страница | 9
Рис. 5
Установление связи между приложением MVC и проектом Windows Azure
4. Добавьте ссылки на необходимые сборки Windows Azure. Для этого в обозревателе
решений щелкните правой кнопкой мыши проект FabrikamInsurance и выберите команду
Добавить ссылку. В диалоговом окне Добавление ссылки перейдите на вкладку .NET,
выберите компоненты Microsoft.WindowsAzure.Diagnostics,
Microsoft.WindowsAzure.ServiceRuntime и Microsoft.WindowsAzure.StorageClient
и нажмите кнопку ОК.
Страница | 10
Рис. 6
Добавление ссылок на необходимые сборки Windows Azure в проект
5. Теперь добавьте точку входа роли в приложение MVC. Для этого в обозревателе решений
щелкните правой кнопкой мыши проект FabrikamInsurance, укажите пункт Добавить и
выберите команду Существующий элемент. В диалоговом окне Добавление
существующего элемента перейдите в папку Assets в папке Source практической работы.
В этой папке выберите папку, соответствующую языку проекта (Visual C# или Visual Basic),
выберите WebRole.cs или WebRole.vb и нажмите кнопку Добавить.
Примечание. Класс WebRole является производным классом RoleEntryPoint, который
содержит методы, вызываемые Windows Azure при запуске, выполнении и остановке
роли. Предоставленный код совпадает с кодом, который Visual Studio формирует при
создании нового проекта Windows Azure.
6. Теперь все готово к тому, чтобы начать тестирование приложения проекта Windows Azure.
Чтобы запустить приложение в эмуляторе вычислений, нажмите клавишу F5. Подождите
завершения развертывания, пока в браузере не откроется главная страница приложения.
7. Снова заполните форму, выбрав любое сочетание значений из раскрывающихся списков,
и нажмите кнопку Рассчитать. Вы должны получить допустимый ответ в виде
вычисленной стоимости полиса.
Страница | 11
8. Удостоверившись в том, что в эмуляторе вычислений все работает так же, как работало
при запуске приложения на сервере веб-разработки, создайте условия для формирования
исключения, заставив приложение обрабатывать неверные данные, с которыми оно
не может работать корректно. Для этого в списке Марка укажите значение «PORSCHE»,
а в списке Модель ― «BOXSTER (BAD DATA)».
Рис. 7
Выбор марки и модели для расчета стоимости страховки
9. Нажмите кнопку Рассчитать, чтобы отправить форму с новыми значениями. Обратите
внимание на то, что возникнет необработанное исключение, а выполнение в отладчике
Visual Studio остановится на строке, вызвавшей ошибку.
Рис. 8
Необработанное исключение в приложении, вызванное неверными данными
Страница | 12
Примечание. В отладчике среды Visual Studio код можно проходить пошагово, задавать
точки останова и анализировать значения переменных программы. Отладка приложений
в эмуляторе вычислений проходит так же, как она обычно выполняется при работе
с другими программами, к которым можно подключить отладчик Visual Studio.
Использование отладчика в этих условиях уже подробно описано, поэтому здесь оно
не рассматривается. Дополнительные сведения см. в разделе Отладка в среде Visual Studio.
10. Нажмите клавишу F5, чтобы продолжить выполнение и позволить ASP.NET обработать
исключение. Обратите внимание на то, что обработчик необработанных исключений
предоставляет сведения о выполнении, включая строку в исходном коде, вызвавшую
это исключение.
Рис. 9
Обработчик необработанных исключений ASP.NET по умолчанию
Примечание. Необработанные исключения обычно обрабатываются ASP.NET, которая
может сообщить об ошибке в своем ответе, указав подробные сведения об ошибке и место
в исходном коде, где это исключение возникло. Однако для общедоступных приложений
предоставление таких сведений нежелательно во избежание ненужного разглашения
внутренних данных о приложении, которые могут подвергнуть риску его защиту. Вместо
этого сведения об ошибках и другие данные диагностики следует записывать в журнал,
доступ к которому можно получить только после надлежащей авторизации.
Страница | 13
То, как ASP.NET отображает сведения при возникновении необработанного исключения
во время выполнения веб-запроса, можно настроить. Дополнительные сведения см.
в разделе Элемент customErrors в схеме параметров ASP.NET.
В данном случае страница с описанием необработанного исключения содержит все
данные ошибки, поскольку режимом по умолчанию для элемента customErrors является
remoteOnly и доступ к этой странице выполняется локально. Когда же приложение
развертывается в облаке и доступ к нему осуществляется удаленно, вместо этого
на странице отображается стандартное сообщение об ошибке.
11. Нажмите клавиши SHIFT + F5, чтобы остановить отладку и завершить работу приложения.
Задача 3. Добавление в приложение поддержки трассировки
В предыдущей задаче было вкратце показано, как отлаживать приложение с помощью среды
Visual Studio, когда оно выполняется локально в эмуляторе вычислений. Для отладки приложения
после его развертывания в облаке данные отладки необходимо записывать в журналы с тем,
чтобы потом диагностировать сбои приложения.
В этой задаче вы добавите в проект прослушиватель трассировки, способный заносить
диагностические данные непосредственно в хранилище таблиц, откуда их можно легко получить
с помощью простого запроса. Исходный код для этого проекта уже имеется в папке Assets
практической работы. Дополнительные сведения о прослушивателе трассировки приведены
здесь: http://msdn.microsoft.com/ru-RU/library/system.diagnostics.tracelistener.aspx
1. В обозревателе решений щелкните правой кнопкой мыши решение Begin, укажите пункт
Добавить и выберите команду Существующий проект. В диалоговом окне Добавление
существующего проекта перейдите в папку Assets в папке Source практической работы,
выберите папку, соответствующую предпочитаемому языку (Visual C# или Visual Basic),
перейдите в папку AzureDiagnostics внутри этой папки, выберите файл проекта
AzureDiagnostics и нажмите кнопку Открыть.
2. Добавьте ссылку на библиотеку AzureDiagnostics в проекте веб-роли. Для этого
в обозревателе решений щелкните правой кнопкой мыши проект FabrikamInsurance
и выберите команду Добавить ссылку. В диалоговом окне Добавление ссылки перейдите
на вкладку Проекты в списке проектов, выберите AzureDiagnostics и нажмите кнопку ОК.
3. Откройте Global.asax.cs (для проектов Visual C#) или Global.asax.vb (для проектов Visual
Basic) в проекте FabrikamInsurance и вставьте следующие директивы пространства имен.
C#
using Microsoft.WindowsAzure;
using Microsoft.WindowsAzure.ServiceRuntime;
VB
Imports Microsoft.WindowsAzure
Imports Microsoft.WindowsAzure.ServiceRuntime
Страница | 14
4. Добавьте следующий (выделенный) метод в класс MvcApplication.
(Фрагмент кода ― WindowsAzureDebugging-Ex1-ConfigureTraceListener-CS)
C#
public class MvcApplication : System.Web.HttpApplication
{
...
private static void ConfigureTraceListener()
{
bool enableTraceListener = false;
string enableTraceListenerSetting =
RoleEnvironment.GetConfigurationSettingValue("EnableTableStorageTraceListener"
);
if (bool.TryParse(enableTraceListenerSetting, out enableTraceListener))
{
if (enableTraceListener)
{
AzureDiagnostics.TableStorageTraceListener listener =
new
AzureDiagnostics.TableStorageTraceListener("Microsoft.WindowsAzure.Plugins.Dia
gnostics.ConnectionString")
{
Name = "TableStorageTraceListener"
};
System.Diagnostics.Trace.Listeners.Add(listener);
System.Diagnostics.Trace.AutoFlush = true;
}
else
{
System.Diagnostics.Trace.Listeners.Remove("TableStorageTraceListener");
}
}
}
}
(Фрагмент кода ― WindowsAzureDebugging-Ex1-ConfigureTraceListener-VB)
Visual Basic
Public Class MvcApplication
Inherits System.Web.HttpApplication
...
Private Shared Sub ConfigureTraceListener()
Dim enableTraceListener As Boolean = False
Страница | 15
Dim enableTraceListenerSetting As String =
RoleEnvironment.GetConfigurationSettingValue("EnableTableStorageTraceListener"
)
If Boolean.TryParse(enableTraceListenerSetting, enableTraceListener) Then
If enableTraceListener Then
Dim listener As New
AzureDiagnostics.TableStorageTraceListener("Microsoft.WindowsAzure.Plugins.Dia
gnostics.ConnectionString") With {.Name = "TableStorageTraceListener"}
System.Diagnostics.Trace.Listeners.Add(listener)
System.Diagnostics.Trace.AutoFlush = True
Else
System.Diagnostics.Trace.Listeners.Remove("TableStorageTraceListener")
End If
End If
End Sub
End Class
Примечание. Метод ConfigureTraceListener получает параметр конфигурации
EnableTableStorageTraceListener и, если его значение равно true, создает новый экземпляр
класса TableStorageTraceListener, определенного в проекте, который был ранее добавлен
в решение, а затем добавляет в коллекцию имеющихся прослушивателей трассировки.
Обратите внимание на то, что метод включает свойство AutoFlush объекта Trace, чтобы
обеспечить запись сообщений трассировки непосредственно в хранилище таблиц,
что позволяет получать их по мере их возникновения.
5. Теперь вставьте следующий (выделенный) код в метод Application_Start, чтобы настроить
издатель параметров конфигурации хранилища Windows Azure, а также включить
TableStorageTraceListener.
(Фрагмент кода ― WindowsAzureDebugging-Ex1- Application_Start-CS)
C#
public class MvcApplication : System.Web.HttpApplication
{
...
protected void Application_Start()
{
CloudStorageAccount.SetConfigurationSettingPublisher((configName,
configSetter) =>
{
configSetter(RoleEnvironment.GetConfigurationSettingValue(configName));
});
ConfigureTraceListener();
Страница | 16
AreaRegistration.RegisterAllAreas();
RegisterRoutes(RouteTable.Routes);
}
...
}
(Фрагмент кода ― WindowsAzureDebugging-Ex1-Application_Start-VB)
Visual Basic
Public Class MvcApplication
Inherits System.Web.HttpApplication
...
Sub Application_Start()
CloudStorageAccount.SetConfigurationSettingPublisher(Sub(configName,
configSetter)
configSetter(RoleEnvironment.GetConfigurationSettingValue(configName)))
ConfigureTraceListener()
AreaRegistration.RegisterAllAreas()
RegisterRoutes(RouteTable.Routes)
End Sub
...
End Class
Примечание. Прослушиватели трассировки можно добавлять путем их настройки
в разделе system.diagnostics файла конфигурации. Однако в данном случае роль создает
прослушиватель программно, что позволяет включать его только на тот период, когда
он нужен, и на время работы службы.
Рис. 10
Включение TableStorageTraceListener в файле конфигурации
Страница | 17
6. Теперь определите параметр конфигурации, который будет управлять записью
диагностических данных в журнал, выполняемой с помощью TableStorageTraceListener. Чтобы
создать этот параметр, разверните узел «Роли» в проекте FabrikamInsuranceService, а затем
дважды щелкните роль FabrikamInsurance. В окне свойств роли перейдите на страницу
Параметры, щелкните Добавить параметр, а затем задайте новому параметру имя
EnableTableStorageTraceListener, в качестве типа укажите String, а в качестве значения ― false.
Рис. 11
Создание параметра конфигурации для включения прослушивателя трассировки
7. Найдите обработчик событий RoleEnvironmentChanging внутри класса WebRole
и замените его код следующим фрагментом (выделенным) кода.
(Фрагмент кода ― WindowsAzureDebugging-Ex1-WebRole RoleEnvironmentChanging event
handler-CS)
C#
public class WebRole : RoleEntryPoint
{
...
private void RoleEnvironmentChanging(object sender,
RoleEnvironmentChangingEventArgs e)
{
// для изменения любого параметра конфигурации, кроме
EnableTableStorageTraceListener
if
(e.Changes.OfType<RoleEnvironmentConfigurationSettingChange>().Any(change =>
change.ConfigurationSettingName != "EnableTableStorageTraceListener"))
{
// Чтобы перезапустить этот экземпляр роли, задайте параметру e.Cancel
значение true
e.Cancel = true;
}
}
...
}
Страница | 18
(Фрагмент кода ― WindowsAzureDebugging-Ex1-WebRole RoleEnvironmentChanging event
handler-VB)
Visual Basic
Public Class WebRole
Inherits RoleEntryPoint
...
Private Sub RoleEnvironmentChanging(ByVal sender As Object, ByVal e As
RoleEnvironmentChangingEventArgs)
' для изменения любого параметра конфигурации, кроме
EnableTableStorageTraceListener
If e.Changes.OfType(Of
RoleEnvironmentConfigurationSettingChange)().Any(Function(change)
change.ConfigurationSettingName <> "EnableTableStorageTraceListener") Then
' Чтобы перезапустить этот экземпляр роли, задайте параметру e.Cancel
значение true
e.Cancel = True
End If
End Sub
...
End Class
Примечание. Событие RoleEnvironmentChanging возникает до того, как изменение
конфигурации службы будет применено к работающим экземплярам роли. Обновленный
обработчик просматривает коллекцию изменений и перезапускает экземпляр роли при
наличии любого изменения параметров конфигурации, если только такое изменение
не касается значения параметра EnableTableStorageTraceListener. Если изменяется именно
этот параметр, экземпляру роли разрешается применить это изменение без перезапуска.
8. Теперь добавьте следующий (выделенный) код, чтобы определить обработчик для
события RoleEnvironmentChanged, в файл Global.asax.cs (для проектов Visual C#) или
Global.asax.vb (для проектов Visual Basic).
(Фрагмент кода ― WindowsAzureDebugging-Ex1-Global RoleEnvironmentChanged event
handler-CS)
C#
public class MvcApplication : System.Web.HttpApplication
{
...
private void RoleEnvironmentChanged(object sender,
RoleEnvironmentChangedEventArgs e)
{
Страница | 19
// настройка прослушивателя трассировки EnableTableStorageTraceListener
на любые изменения
if
(e.Changes.OfType<RoleEnvironmentConfigurationSettingChange>().Any(change =>
change.ConfigurationSettingName == "EnableTableStorageTraceListener"))
{
ConfigureTraceListener();
}
}
...
}
(Фрагмент кода ― WindowsAzureDebugging-Ex1-Global RoleEnvironmentChanged event
handler-VB)
Visual Basic
Public Class MvcApplication
Inherits System.Web.HttpApplication
...
Private Sub RoleEnvironmentChanged(ByVal sender As Object, ByVal e As
RoleEnvironmentChangedEventArgs)
' настройка прослушивателя трассировки EnableTableStorageTraceListener
на любые изменения
If e.Changes.OfType(Of
RoleEnvironmentConfigurationSettingChange)().Any(Function(change)
change.ConfigurationSettingName = "EnableTableStorageTraceListener") Then
ConfigureTraceListener()
End If
End Sub
...
End Class
Примечание. Обработчик событий RoleEnvironmentChanged вызывается после того, как
изменение конфигурации службы было применено к работающим экземплярам роли.
Если это изменение касается параметра конфигурации EnableTableStorageTraceListener,
обработчик вызывает метод ConfigureTraceListener, чтобы включить или отключить
прослушиватель трассировки.
9. И наконец, вставьте следующую (выделенную) строку в метод Application_Start сразу
после вызова метода ConfigureTraceListener для подписки на событие Changed объекта
RoleEnvironment.
C#
public class MvcApplication : System.Web.HttpApplication
{
...
Страница | 20
protected void Application_Start()
{
CloudStorageAccount.SetConfigurationSettingPublisher((configName,
configSetter) =>
{
configSetter(RoleEnvironment.GetConfigurationSettingValue(configName));
});
ConfigureTraceListener();
RoleEnvironment.Changed += RoleEnvironmentChanged;
AreaRegistration.RegisterAllAreas();
RegisterRoutes(RouteTable.Routes);
}
...
}
Visual Basic
Public Class MvcApplication
Inherits System.Web.HttpApplication
...
Sub Application_Start()
CloudStorageAccount.SetConfigurationSettingPublisher(Sub(configName,
configSetter)
configSetter(RoleEnvironment.GetConfigurationSettingValue(configName)))
ConfigureTraceListener()
AddHandler RoleEnvironment.Changed, AddressOf RoleEnvironmentChanged
AreaRegistration.RegisterAllAreas()
RegisterRoutes(RouteTable.Routes)
End Sub
...
End Class
10. Чтобы приложение могло записывать диагностические данные в журнал ошибок,
добавьте в него глобальный обработчик ошибок. Для этого добавьте следующий метод
в класс MVCApplication.
(Фрагмент кода ― WindowsAzureDebugging-Ex1-Application_Error-CS)
C#
Страница | 21
public class MvcApplication : System.Web.HttpApplication
{
...
protected void Application_Error()
{
var lastError = Server.GetLastError();
System.Diagnostics.Trace.TraceError(lastError.Message);
}
}
(Фрагмент кода ― WindowsAzureDebugging-Ex1-Application_Error-VB)
Visual Basic
Public Class MvcApplication
Inherits System.Web.HttpApplication
...
Protected Sub Application_Error()
Dim lastError = Server.GetLastError()
System.Diagnostics.Trace.TraceError(lastError.Message)
End Sub
End Class
Примечание. Событие Application_Error формируется для записи любых необработанных
ошибок ASP.NET при обработке запроса. Показанный ранее обработчик событий
получает ссылку на объект необработанного исключения с помощью метода
Server.GetLastError, а затем с помощью метода TraceError класса System.Diagnostics.Trace
заносит сообщение об ошибке в журнал.
Обратите внимание, что объект Trace выдает сообщение всем прослушивателям из своей
коллекции Listeners, включая TableStorageTraceListener, если он был включен
в параметрах конфигурации. Как правило, в этой коллекции также есть экземпляры
класса DefaultTraceListener и DevelopmentFabricTraceListener (при выполнении решения
в эмуляторе вычислений). Последний записывает свои выходные данные в журнал,
который можно просматривать из пользовательского интерфейса эмулятора вычислений.
Для записи в журнал диагностики Windows Azure прослушиватель
DiagnosticMonitorTraceListener также можно добавить в файл роли Web.config или
App.config. При использовании прослушивателя трассировки этого типа журналы
собираются локально в каждой роли. Для их получения сначала необходимо указать,
чтобы монитор диагностики копировал эти сведения в службы хранения. В шаблонах
проектов ролей, имеющихся в инструментах Windows Azure для Microsoft Visual Studio,
уже есть параметры, необходимые для использования DiagnosticMonitorTraceListener
в формируемых файлах конфигурации.
Страница | 22
Рис. 12
Коллекция прослушивателей объекта трассировки с настроенными прослушивателями
трассировки
11. Откройте файл QuoteController.cs (для проектов Visual C#) или QuoteController.vb
(для проектов Visual Basic) из папки Controllers проекта FabrikamInsurance и добавьте
следующий метод.
(Фрагмент кода ― WindowsAzureDebugging-Ex1-Controller OnException method-CS)
C#
[HandleError]
public class QuoteController : Контроллер
{
...
protected override void OnException(ExceptionContext filterContext)
{
System.Diagnostics.Trace.TraceError(filterContext.Exception.Message);
}
}
(Фрагмент кода ― WindowsAzureDebugging-Ex1-Controller OnException method-VB)
Visual Basic
<HandleError()>
Public Class QuoteController
Inherits Controller
...
Protected Overrides Sub OnException(ByVal filterContext As ExceptionContext)
System.Diagnostics.Trace.TraceError(filterContext.Exception.Message)
End Sub
End Class
Страница | 23
Примечание. Метод OnException вызывается при возникновении необработанного
исключения во время обработки действия в контроллере. При работе с приложениями
MVC необработанные исключения обычно отслеживаются на уровне контроллера при
условии, что они возникают во время выполнения действия контроллера, а также при
наличии у действия (или контроллера) атрибута HandleErrorAttribute. Для занесения
в журнал исключений в действиях контроллера необходимо переопределить метод
OnException контроллера, поскольку событие Application_Error не формируется, когда
фильтр обработки ошибок отслеживает исключения.
По умолчанию, когда метод действия с атрибутом HandleErrorAttribute формирует
какое-либо исключение, MVC отображает представление Ошибка, расположенное
в папке ~/Views/Shared.
12. Помимо регистрации ошибок, трассировку можно использовать для записи других важных
событий, возникающих во время выполнения приложения. Например, для регистрации
вызовов определенных действий контроллера. Чтобы посмотреть, как это работает,
вставьте следующую (выделенную) инструкцию трассировки в начало метода Calculator,
чтобы заносить в журнал сообщение при каждом вызове этого действия.
C#
public class QuoteController : Контроллер
{
...
public ActionResult Calculator()
{
System.Diagnostics.Trace.TraceInformation("Calculator called...");
QuoteViewModel model = new QuoteViewModel();
PopulateViewModel(model, null);
return View(model);
}
...
}
Visual Basic
Public Class QuoteController
Inherits Controller
...
Public Function Calculator() As ActionResult
System.Diagnostics.Trace.TraceInformation("Calculator called...")
Dim model As New QuoteViewModel()
PopulateViewModel(model, Nothing)
Return View(model)
End Function
...
End Class
Страница | 24
13. Аналогичным образом добавьте инструкцию трассировки, приведенную (выделенную)
далее, в действие About.
C#
public class QuoteController : Контроллер
{
...
public ActionResult About()
{
System.Diagnostics.Trace.TraceInformation("About called...");
return View();
}
...
}
Visual Basic
Public Class QuoteController
Inherits Controller
...
Public Function About() As ActionResult
System.Diagnostics.Trace.TraceInformation("About called...")
Return View()
End Function
...
End Class
Задача 4. Создание средства просмотра журнала
К этому моменту приложение уже готово к трассировке, оно может передавать все свои
диагностические данные в таблицу, находящуюся в службах хранения. Теперь для просмотра
журналов трассировки нужно создать простое средство просмотра журналов, которое будет
периодически выполнять запросы к таблице и получать из нее все записи, добавленные
с момента выполнения последнего запроса.
1. Добавьте в решение новое консольное приложение. Чтобы создать проект, в меню Файл
укажите команду Добавить и выберите Новый проект. В диалоговом окне Добавление
нового проекта разверните узел, соответствующий выбранному языку (Visual C# или Visual
Basic) в представлении в виде дерева Установленные шаблоны, выберите категорию
Windows, а затем шаблон Консольное приложение. В качестве имени проекта укажите
LogViewer, примите предложенное местоположение внутри папки решения и нажмите
кнопку ОК.
2. Щелкните правой кнопкой мыши новый проект LogViewer в обозревателе решений
и выберите пункт Свойства.
Для проектов Visual C#.
В окне свойств перейдите на страницу Приложение и для параметра Целевая платформа
задайте значение .NET Framework 4.
Страница | 25
Рис. 13
Настройка целевой платформы для проекта (Visual C#)
Для проектов Visual Basic.
В окне свойств перейдите на страницу Компилятор и щелкните Дополнительные
параметры компилятора. В диалоговом окне Дополнительные параметры компилятора
выберите .NET Framework 4 в раскрывающемся списке Целевая платформа и нажмите
кнопку ОК.
Страница | 26
Рис. 14
Настройка целевой платформы для проекта (Visual Basic)
Примечание. Профиль клиента в данном случае не подходит, поскольку для получения
данных журнала из хранилища таблиц приложение будет использовать API-интерфейс
StorageClient. Этот API-интерфейс работает на основе функций, которые имеются только
в полной версии платформы .NET Framework 4.
3. Если на экране откроется диалоговое окно Изменение целевой платформы, нажмите
кнопку Да.
Страница | 27
Рис. 15
Изменение целевой платформы
4. Добавьте ссылки на сборки, которые требуются для этого проекта. Для этого
в обозревателе решений щелкните правой кнопкой мыши проект LogViewer и выберите
команду Добавить ссылку. В диалоговом окне Добавление ссылки перейдите на вкладку
.NET и, удерживая нажатой клавишу CTRL для выбора нескольких элементов, выберите
System.Configuration, Microsoft.WindowsAzure.StorageClient и System.Data.Services.Client,
а затем нажмите кнопку ОК.
5. Теперь добавьте в решение ссылку на диагностический проект. Повторите предыдущий
шаг и откройте диалоговое окно Добавление ссылки, только на этот раз перейдите
на вкладку Проекты, выберите проект AzureDiagnostics и нажмите кнопку ОК.
6. Добавьте в проект класс для отображения простого индикатора выполнения в окне
консоли. Для этого в обозревателе решений щелкните правой кнопкой мыши проект
LogViewer, укажите команду Добавить и выберите Существующий элемент. В диалоговом
окне Добавление существующего элемента перейдите в папку Assets в папке Source
практической работы, выберите папку, соответствующую языку проекта (Visual C# или
Visual Basic), выберите файл ProgressIndicator.[cs|.vb] и нажмите кнопку Добавить.
7. В обозревателе решений дважды щелкните файл Program.cs или Module1.vb, чтобы
открыть его и вставить в начало файла следующие объявления пространств имен.
(Фрагмент кода ― WindowsAzureDebugging-Ex1-LogViewer namespaces-CS)
C#
using
using
using
using
using
using
System.Configuration;
System.Data.Services.Client;
System.Threading;
Microsoft.WindowsAzure;
Microsoft.WindowsAzure.StorageClient;
AzureDiagnostics;
Страница | 28
(Фрагмент кода ― WindowsAzureDebugging-Ex1-LogViewer namespaces-VB)
Visual Basic
Imports
Imports
Imports
Imports
Imports
Imports
System.Configuration
System.Data.Services.Client
System.Threading
Microsoft.WindowsAzure
Microsoft.WindowsAzure.StorageClient
AzureDiagnostics
8. В проекте Visual Basic измените функцию Sub Main, сделав ее Public и добавив параметр
строкового массива с именем args.
Visual Basic
Module Module1
Public Sub Main(ByVal args() As String)
End Sub
End Module
9. Определите следующие (выделенные) элементы в классе Program (для проектов Visual C#)
или в модуле Module1 (для проектов Visual Basic).
(Фрагмент кода ― WindowsAzureDebugging-Ex1-LogViewer static members-CS)
C#
class Program
{
private static string lastPartitionKey = String.Empty;
private static string lastRowKey = String.Empty;
static void Main(string[] args)
{
}
}
(Фрагмент кода ― WindowsAzureDebugging-Ex1-LogViewer static members-VB)
Visual Basic
Module Module1
Private lastPartitionKey As String = String.Empty
Private lastRowKey As String = String.Empty
Страница | 29
Public Sub Main(ByVal args() As String)
End Sub
End Module
10. Затем вставьте метод QueryLogTable в этот класс или модуль.
(Фрагмент кода ― WindowsAzureDebugging-Ex1-QueryLogTable method-CS)
C#
class Program
{
...
private static void QueryLogTable(CloudTableClient tableStorage)
{
TableServiceContext context = tableStorage.GetDataServiceContext();
DataServiceQuery query =
context.CreateQuery<LogEntry>(TableStorageTraceListener.DIAGNOSTICS_TABLE)
.Where(entry =>
entry.PartitionKey.CompareTo(lastPartitionKey) > 0
|| (entry.PartitionKey ==
lastPartitionKey && entry.RowKey.CompareTo(lastRowKey) > 0))
as DataServiceQuery;
foreach (AzureDiagnostics.LogEntry entry in query.Execute())
{
Console.WriteLine("{0} - {1}", entry.Timestamp, entry.Message);
lastPartitionKey = entry.PartitionKey;
lastRowKey = entry.RowKey;
}
}
...
}
(Фрагмент кода ― WindowsAzureDebugging-Ex1-QueryLogTable method-VB)
Visual Basic
Module Module1
...
Private Sub QueryLogTable(ByVal tableStorage As CloudTableClient)
Dim context As TableServiceContext = tableStorage.GetDataServiceContext()
Dim query As DataServiceQuery = TryCast(context.CreateQuery(Of
LogEntry)(TableStorageTraceListener.DIAGNOSTICS_TABLE).Where(Function(entry)
entry.PartitionKey.CompareTo(lastPartitionKey) > 0 OrElse (entry.PartitionKey
Страница | 30
= lastPartitionKey AndAlso entry.RowKey.CompareTo(lastRowKey) > 0)),
DataServiceQuery)
For Each entry As AzureDiagnostics.LogEntry In query.Execute()
Console.WriteLine("{0} - {1}", entry.Timestamp, entry.Message)
lastPartitionKey = entry.PartitionKey
lastRowKey = entry.RowKey
Next
End Sub
...
End Module
Примечание. Строки в таблице журнала диагностики хранятся с первичным ключом,
состоящим из свойства ключа секции и строки, причем оба этих свойства основаны
на счетчике событий соответствующей записи журнала, поэтому они располагаются
в хронологическом порядке. Метод QueryLogTable выполняет запрос к таблице, чтобы
получить все строки, значение первичного ключа которых больше, чем последнее
значение, полученное при предыдущем вызове этого метода. Это гарантирует, что при
каждом вызове метод будет получать только новые записи, добавленные в журнал.
11. И наконец, чтобы завершить внесение изменений, вставьте следующий (выделенный)
код в метод Main.
(Фрагмент кода ― WindowsAzureDebugging-Ex1-LogViewer Main method-CS)
C#
class Program
{
...
static void Main(string[] args)
{
string connectionString = (args.Length == 0) ?
"Microsoft.WindowsAzure.Plugins.Diagnostics.ConnectionString" : args[0];
CloudStorageAccount account =
CloudStorageAccount.Parse(ConfigurationManager.AppSettings[connectionString]);
CloudTableClient tableStorage = account.CreateCloudTableClient();
tableStorage.CreateTableIfNotExist(TableStorageTraceListener.DIAGNOSTICS_TABLE
);
Utils.ProgressIndicator progress = new Utils.ProgressIndicator();
Timer timer = new Timer((state) =>
{
progress.Disable();
QueryLogTable(tableStorage);
progress.Enable();
Страница | 31
}, null, 0, 10000);
Console.ReadKey(true);
}
}
(Фрагмент кода ― WindowsAzureDebugging-Ex1-LogViewer Main method-VB)
Visual Basic
Module Module1
...
Public Sub Main(ByVal args() As String)
Dim connectionString As String = If((args.Length = 0),
"Microsoft.WindowsAzure.Plugins.Diagnostics.ConnectionString", args(0))
Dim account As CloudStorageAccount =
CloudStorageAccount.Parse(ConfigurationManager.AppSettings(connectionString))
Dim tableStorage As CloudTableClient = account.CreateCloudTableClient()
tableStorage.CreateTableIfNotExist(TableStorageTraceListener.DIAGNOSTICS_TABLE
)
Dim progress As New ProgressIndicator()
Dim timer As New Timer(Sub(state)
progress.Disable()
QueryLogTable(tableStorage)
progress.Enable()
End Sub, Nothing, 0, 10000)
Console.ReadKey(True)
End Sub
End Module
Примечание. Вставленный код инициализирует данные учетной записи хранилища
Windows Azure, при необходимости создает диагностическую таблицу, а затем запускает
таймер, который периодически вызывает метод QueryLogMethod, определенный
в предыдущем шаге, для отображения новых записей из журнала диагностики.
12. Чтобы завершить создание средства просмотра, откройте файл App.config из проекта
LogViewer и вставьте следующий (выделенный) раздел appSettings, чтобы определить
параметр DiagnosticsConnectionString, который требуется для инициализации данных
учетной записи хранилища.
(Фрагмент кода ― WindowsAzureDebugging-LogViewer DiagnosticConnectionString)
Страница | 32
XML
<configuration>
...
<appSettings>
<add key="Microsoft.WindowsAzure.Plugins.Diagnostics.ConnectionString"
value="UseDevelopmentStorage=true"/>
</appSettings>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0" />
</startup>
</configuration>
Проверка
Теперь все готово к выполнению решения в эмуляторе вычислений. Для обеспечения
возможности включать прослушиватель трассировки хранилища таблиц динамически,
не останавливая работающую службу, службу первоначально разворачивают с отключенным
параметром EnableTraceStorageTraceListener, а затем значение этого параметра изменяется в
файле конфигурации, чтобы включить прослушиватель, после чего файл передается на сервер,
чтобы перенастроить работающую службу. Просмотр сообщений трассировки, формируемых
приложением, выполняется с помощью приложения просмотра журнала.
1. Откройте файл Web.config проекта FabrikamInsurance и вставьте следующий
(выделенный) раздел customErrors в качестве прямого потомка элемента system.web.
XML
<configuration>
...
<system.web>
...
<customErrors mode="On" />
</system.web>
...
</configuration>
Примечание. Когда режиму customErrors задается значение On, ASP.NET отображает
стандартные сообщения об ошибке как для локального, так и для удаленного клиента.
Если же режим customErrors имеет параметр по умолчанию RemoteOnly, то после
развертывания приложения в Windows Azure и удаленного доступа к нему будут
отображаться стандартные сообщения об ошибках, поэтому эти шаги выполнять
не обязательно. Однако это позволяет воспроизвести локально то поведение,
которое можно было бы наблюдать после развертывания приложения в облаке.
Страница | 33
2. Чтобы протестировать решение, необходимо настроить проект Windows Azure
и приложение просмотра журнала, чтобы они запускались одновременно. Чтобы
определить проекты, запускаемые автоматически, щелкните правой кнопкой мыши
узел решения в обозревателе решений и выберите пункт Установить автоматически
запускаемые проекты. В окне Страницы свойств решения «Begin» выберите
Автоматически запускаемый проект в разделе Общие свойства, а затем выберите
параметр Несколько запускаемых автоматически проектов. Затем параметру Action
для проектов LogViewer и FabrikamInsuranceService задайте значение Start. У остальных
проектов этот параметр должен иметь значение None. Нажмите кнопку OК, чтобы
сохранить изменения, внесенные в настройки автоматического запуска.
Рис. 16
Настройка автоматически запускаемых проектов для решения
3. Нажмите клавиши CTRL + F5, чтобы запустить приложение, не подключая к нему отладчик.
Опять же при этом будут воссозданы условия, в которых приложение работает после
развертывания в облаке. Подождите завершения развертывания, пока в браузере
не откроется главная страница приложения.
4. Заполните открывшуюся в окне браузера форму, выбрав «PORSCHE» в качестве значения поля
Марка автомобиля и «BOXSTER (BAD DATA)» в качестве значения поля Модель. Обратите
внимание на то, что на этот раз, поскольку вы включили параметр customErrors в файле
Web.config, приложение отображает стандартную страницу с сообщением об ошибке вместо
подробных сведений об исключении, которые отображались ранее. Именно эту страницу
вы бы увидели, если бы приложение было развернуто в Windows Azure.
Страница | 34
Рис. 17
Ошибка приложения при включенном параметре customErrors
5. Ознакомьтесь с данными, отображаемыми в приложении просмотра журнала. Обратите
внимание, что, несмотря на ошибку, окно консоли все еще пусто, поскольку в настоящее
время прослушиватель трассировки хранилища таблиц отключен.
6. Переключитесь в среду Visual Studio и в обозревателе решений разверните узел Роли
проекта FabrikamInsuranceService, а затем дважды щелкните роль FabrikamInsurance,
чтобы открыть окно ее свойств. Перейдите на страницу Параметры и измените значение
параметра EnableTableStorageTraceListener на true.
7. Нажмите CTRL + S, чтобы сохранить внесенные в конфигурацию изменения.
8. Откройте консоль эмулятора вычислений, щелкнув ее значок, расположенный в области
уведомлений, правой кнопкой мыши и выбрав пункт Показать пользовательский
интерфейс эмулятора вычислений. Запишите идентификатор текущего развертывания. Это
заключенное в скобки числовое значение, которое указано рядом с меткой развертывания.
Страница | 35
Рис. 18
Пользовательский интерфейс эмулятора вычислений, в котором показан
идентификатор текущего развертывания
9. Теперь откройте командную строку пакета Windows Azure SDK, выбрав Пуск | Все
программы | Windows Azure SDK v1.X | Командная строка Windows Azure SDK. Чтобы
запустить командную строку от имени администратора, щелкните ее ярлык в меню
Пуск правой кнопкой мыши и выберите Запуск от имени администратора.
10. Измените текущий каталог на расположение облачного проекта FabrikamInsuranceService
внутри папки текущего решения. В этой папке находятся файлы конфигурации службы,
выберите ServiceConfiguration.Local.cscfg.
11. В командной строке выполните следующую команду, чтобы обновить конфигурацию
работающего развертывания. Замените заполнитель [DEPLOYMENTID] на значение,
которое вы записали ранее.
Командная строка Windows Azure
csrun /update:[DEPLOYMENTID];ServiceConfiguration.Local.cscfg
Страница | 36
Рис. 19
Обновление конфигурации работающей службы
Примечание. При работе с приложениями, развернутыми в облаке, конфигурация
действующего приложения обычно обновляется через портал разработчиков Windows
Azure или при помощи API-интерфейса управления Windows Azure, который используется
для передачи нового файла конфигурации.
12. После обновления конфигурации и включения прослушивателя трассировки вернитесь
в окно браузера, перейдите на страницу Калькулятор и снова введите те же параметры,
которые ранее вызвали ошибку (марка «PORSCHE», модель «BOXSTER (BAD DATA)»). Затем
нажмите кнопку Рассчитать, чтобы снова отправить форму. В ответ вы должны опять
получить страницу с сообщением об ошибке.
13. Перейдите в окно средства просмотра журнала и подождите несколько секунд, пока
оно не обновится. Обратите внимание на то, что теперь консоль показывает запись
с сообщением об ошибке для необработанного исключения, что свидетельствует о том,
что данные трассировки, сформированные работающим приложением, записываются
непосредственно в хранилище таблиц.
Рис. 20
Средство просмотра, отображающее ошибку, занесенную в хранилище таблиц
Страница | 37
14. Для просмотра данных других информационных сообщений трассировки вернитесь в окно
браузера и щелкните Сведения, а затем Калькулятор, чтобы выполнить оба действия
в контроллере. Напомним, что вы вставили сообщения трассировки в начало каждого
метода. Обратите внимание на то, что теперь в консоли средства просмотра отображается
сообщение для каждого из этих действий.
Рис. 21
Средство просмотра, отображающее информационные сообщения трассировки для
действий контроллера
15. Находясь в окне средства просмотра журнала, нажмите любую клавишу, чтобы закрыть
программу.
16. И наконец, удалите работающее в эмуляторе вычислений развертывание. Для этого
щелкните развертывание правой кнопкой мыши в представлении в виде дерева
Развертывания служб и выберите Удалить.
Сводка
Выполнение этой практической работы позволило вам познакомиться с простыми методами
отладки, предназначенными для устранения неисправностей приложения Windows Azure после
его развертывания в облаке. Вы узнали, как с помощью стандартных методов диагностики .NET
записывать диагностические данные непосредственно в хранилище таблиц с помощью
пользовательского прослушивателя трассировки.
Страница | 38
Download