Использование Visual Studio Application Insights — опыт инженера по тестированию

Выражаем большое спасибо за подготовку статьи Игорю Щегловитову, старшему инженеру по тестированию из Лаборатории Касперского, за помощь в написании данной статьи и ценный практический опыт. Остальные наши статьи по теме Azure можно найти по тегу azureweek, а также по тегу mstesting — статьи по тестированию.


Application Insights (в дальнейшем просто AI)– это механизм для сбора и анализа пользовательской телеметрии: различных счетчиков производительности, пользовательских событий (логов) и тп. На текущий момент он поддеживает не только ASP.NET приложения, но и другие, в том числе Java, IOS, JavaScript и др.

d867aa7eb01dbb7eec7359723ef9e724.png
При подключении и настройки пакета AI он по умолчанию начинает собирать некоторые метрики, например для вебприложений это информация по запросам к веб серверу, а также различные серверные счетчики (например, время запроса, загрузка CPU). Помимо этого, AI имеет расширенное API, которое позволяет сохранять кастомные и бизнес-счетчики и логи.
Наша команда занимается разработкой облачных сервисов Azure. Логи сохраняются в Azure Storage, а счетчики производительности (серверные и перфоманс), читаются и анализируются в автоматическом режиме отдельным сервером мониторинга. Для логирования мы используем Serilog. В отличие от других логгеров, он (из коробки) позволяет писать структурные логи, выделяя отдельные свойства.
В настоящее время для множества популярых логгеров, таких как Serilog, log4net, Nlog существуют дополнения, которые позволяют перенаправлять логи в AI. Если вы пользуетесь данными логерами, а также имеете активную подписку Azure, то можете попробовать в бесплатном режиме возможности AI.

Ниже пример настройки Serilog для сохранения логов в AI:

Через NuGet подключаем пакет Serilog.Sinks.ApplicationInsights:

h6z2fnnqojut5duyo09jkc32
(данный пакет автоматически подключит зависимый от него Application Insights API)

Далее, при конфигурировании логера Serilog, надо указать расширение ApplicationInsights, например, вот так:

Log.Logger = new LoggerConfiguration().WriteTo.ApplicationInsights(string.Empty).CreateLogger();


В Azure портале предварительной версии создаем новый контейнер Application Insigts

s7n_vxlvc2cou2e_yy5s8n4x

После создания, на вкладке «Основное» копируем ключ инструментирования

1fgqpfwfizl_wl-carsu66awt

Теперь в коде перед стартом приложения следует прописать:

TelemetryConfiguration.Active.InstrumentationKey = "{ключ-инструментирования}";


Если же вы, например, используете логирование Nlog, то для перенапрвления логов в AI достаточно подключить пакет »Application Insights Nlog Target»
1orde6y9mp9obe2z_4qms1mok

После этого в конфиге приложения автоматически появится секция:


        
            
        
        
            
        
        
            
        
    


Основная проблема при использовании NLog — он позволяет писать только строки, без настраиваемых свойств. Кроме использования логеров, пользовательские события в AI можно отправлять и через API, вот пример:


var telemetry = new TelemetryClient();
...
try 
{ 
var eventTelemetry = new EventTelemetry("log”); 
eventTelemetry. Properties["CustomProperty”] = "test”; 
telemetry.Track(eventTelemetry);
catch (Exception ex)
{
   var properties = new Dictionary  
     {{" CustomProperty ", "test”}};
   telemetry.TrackException(ex, properties);
} 


Теперь, после запуска приложения, логи будут перенаправляться в AI.

В отличие от лог-форвадеров, явное использование AI API позволяет писать телеметрию в разные контейнеры AI. Это удобно, когда у вас крупное приложение, состоящее из множества компонент: сервисов, веб интерфейса и тп. В этом случае при отправке телеметрии в AI, в экземплярах TelemetryClient вы можете явно задавать свойство InstrumentationKey.

Например, для вашего приложения вы создали три разных контейнера: один для анализа производительности, другой для логов, третий для мониторинга пользовательской активности. Что касается последнего, для анализа пользовательской активности UI приложений в AI API предусмотрен специальный метод TrackPageView. Вы можете сохранять данные, по каким страницам (вкладкам) заходил тот или иной пользователь (напомню, что сохранять события в AI можно и непосредственно в JavaScript-коде), на основе чего можно делать какие либо выводы.

Также добавлю, что вы можете настроить экспорт телеметрии AI для дальнейшего анализа в Azure Blobs. Удобный интерфейс поиска позволит вам находить нужные пользовательские события через Azure портал. На скриншоте видно, как в отображаются свойства одного из моих сохраненных логов.

r5c1s8s5o4qff93n-mkhcav3

Причем каждое логируемое отдельно свойство индексируется и вы можете фильтровать логи по конкретному его значению, через меню фильтра:

s7kl743t4giyp-_u8uj-c8n5

Это очень удобно, т.к. позволяет отслеживать появление новых событий, например, каких-то новых исключений.

Сам интерфейс поиска логов очень простой, кроме стандартных фильтров, вы можете писать различные запросы к вашим логам (более подробно в документации).

Помимо логов, если у вас веб-приложение (например MVC Web API), то, подключив Nuget пакет Application Insights Web (без каких либо дополнительных настроек), в AI будет попадать информация по всем веб запросам.

20osg3drn-gcim24ryn_a-615

Кроме этого, AI будет собирать зависимости, связанные с запросами. Например, при HTTP-запросе произошел вызов БД. В логах AI вы увидите данную связь, а также информацию по связанному запросу (URL, код возврата …).

Помимо этого, на вкладке «Серверы» будут доступны различные серверные счетчики производительности (CPU, Memory…). По умолчанию их не так много, но через ApplicationInsights.config вы можете добавить те счетчики, которые вам нужны.

29rtvw69hidz27gw6k8t4ut0

Используя функциональность правил оповещения, вы можете создать правило, при наступлении которого на заданный e-mail будет приходить соответсвующая нотификация (например, превышено пороговое значение CPU).

В нашей команде мы разрабатываем асинхронные сервисы. Мы не использует транзакции в прямом смысле этого слова. Для обеспечения целостности данных при выполнения длительных БП, когда при вызове одного API метода состояние объектов БД меняется более чем 1 раз, мы используем очереди и Service Bus (для примера: API-метод провалидировал данные, изменил состояние объекта, отправил сообщение-команду в очередь и вернул результат вызываемой стороне; обработчик очереди поднял сообщение, выполнил какое то действие и положил новое сообщение в очередь и так далее).

Количество логов, которые создаются при одном таком БП, может достигать десятков записей. Для их связки мы используем специальный кастомный хедер conversationId. Он пробрасывается во всех командах и сообщениях при выполнении всего процесса. Данный хедер может быть задан вызывающей стороной. Он логируется как настраиваемое свойство. Таким образом указав значение conversationId в окне поиска, можно получить всю цепочку логов БП:

bc9wmi3chchpf55dxvwo3uvh

Кроме эксплуатации, такой подход очень полезен и при интеграционном тестировании.
Я занимаюсь разработкой интеграционных тестов для наших облачных сервисов. Автоматизированные тестовые сценарии живут в MTM, запускаются через специальный билд. Тесты в большинстве случаев клиент-серверные. По сообщению с ошибкой в информации упавшего теста далеко не всегда понятна причина падения. Часто для диагностики нужны именно серверные логи. Отдельно искать и смотреть логи по каждому тесту не удобно и занимает много времени. Здесь мне на помощь пришла такая функциональность, как кастомные диагностические адаптеры MSTest.

Если вкратце, то под диагностическим адаптером в данном контексте понимается сборка, содержащая специальный класс, который наследуется от Microsoft.VisualStudio.TestTools.Execution.DataCollector. Если тест агент настроен на использование данного диагностического адаптера, то во время выполнения теста запускаются соответсвующие событие, логика которого определена в методах OnTestCaseStart, OnTestCaseEnd. В этих методах, у вас есть доступ к контексту теста, в том числе к его названию, состоянию и тп. Вот пример реализации диагностического адаптера:


[DataCollectorConfigurationEditor("configurationeditor://CompanyName/LogConfigEditor/4.0")]
[DataCollectorTypeUri("datacollector://CompanyName/LogCollector/4.0")]
[DataCollectorFriendlyName("log collector.")]
public class LogCollecter : DataCollector
{
public override void Initialize(
XmlElement configurationElement,
DataCollectionEvents events,
DataCollectionSink sink,
DataCollectionLogger logger,
DataCollectionEnvironmentContext environmentContext)
{
_stopwatch = new Stopwatch();

_dataEvents = events;  // The test events
_dataLogger = logger;  // The error and warning log
_dataSink = sink;

Configuration.Init(configurationElement);
events.TestCaseStart += OnTestCaseStart;
events.TestCaseEnd += OnTestCaseEnd;
}
private void OnTestCaseStart(object sender, TestCaseEventArgs e)
{
_stopwatch.Start();
}
private void OnTestCaseEnd(object sender, TestCaseEndEventArgs e)
{
Guard.CheckNotNull(e, "TestCaseFailedEventArgs is null");

var testCaseEndDate = DateTime.Now;
if (_stopwatch.IsRunning)
{
_stopwatch.Stop();
}
if (e.TestOutcome == TestOutcome.Failed)
{
//Здесь можно собрать логи и прикрепить их к результату теста.
            _dataSink.SendFileAsync(e.Context, Configuration.ZipFilePath, true);
}
}
private Stopwatch _stopwatch;
private DataCollectionEvents _dataEvents;
private DataCollectionLogger _dataLogger;
private DataCollectionSink _dataSink;
}


После реализации диагностического адаптера, сборку с ним надо подложить на все сервера с установленными тестовыми агентами (включая машину, на которой происходит конфигурирование настроек Lab Management), в папку %Microsoft Visual Studio 12.0\Common7\IDE\PrivateAssemblies\DataCollectors.

Далее запустить MTM, и поставить галочку напротив адаптера.

1j8vl1kc61oeg7a6l2kt-zg1_

Более подробно про диагностические адапторы, формы их конфигурации и настройки читайте здесь msdn.microsoft.com/en-us/library/dd286727.aspx.

В каждом тестовом классе, в методе TestInitialize был добавлен код инициализации conversationId, который в последствии проставлялся в хедерах при создании wcf и http клиентов. Данный сonversationId шарился с диагностическим адаптером. И при возникновении ошибки в результатах теста появлялся информации о conversationId. А зная conversationId через AI можно очень просто посмотреть все серверные события, связанные с конкретным тестом.

Application Insights — это очень мощный инструмент, который просто позволяет подключить к вашему приложению сбор различной диагностической телеметрии, а также упростить ее дальнейший визуальный анализ используя дружественный интерфейс портала. Если у вас есть подписка Azure, то вы можете использовать AI в двух режимах Free и Premium. Основное ограничения Free режима — максимальное количество пользовательских события — 5 млн в месяц, и добавляемые данные хранятся в течении 7 дней, после чего удаляются. В Premium версии данные ограничения сняты. Бесплатно можно использовать в течении 30 дней.

Разные полезные ресурсы


© Habrahabr.ru