company_banner

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

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

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



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

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

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


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

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

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

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



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



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

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


    После этого в конфиге приложения автоматически появится секция:
    <nlog>
            <extensions>
                <add assembly="Microsoft.ApplicationInsights.NLogTarget"/>
            </extensions>
            <targets>
                <target type="ApplicationInsightsTarget" name="aiTarget"/>
            </targets>
            <rules>
                <logger name="*" minlevel="Trace" writeTo="aiTarget"/>
            </rules>
        </nlog>
    

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

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

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

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

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

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



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



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

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

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



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

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



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

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

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



    Кроме эксплуатации, такой подход очень полезен и при интеграционном тестировании.
    Я занимаюсь разработкой интеграционных тестов для наших облачных сервисов. Автоматизированные тестовые сценарии живут в 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, и поставить галочку напротив адаптера.



    Более подробно про диагностические адапторы, формы их конфигурации и настройки читайте здесь 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 дней.

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


    • +15
    • 12,6k
    • 3

    Microsoft

    279,17

    Microsoft — мировой лидер в области ПО и ИТ-услуг

    Поделиться публикацией
    Комментарии 3
      0
      А скажите, планируется ли поддержка AI в OWIN-Self Hosted сценариях. А то хочется чтобы была диагностика такая же как и для IIS, а не вручную вызывать API во всяких фильтрах. Даже для беты ASP.NET 5 уже есть, а для такого стабильного стека как OWIN — нету.
        0
        Можете раскрыть вопрос и рассказать подробнее, пожалуйста?
          0
          Сценарий очень простой — есть Worker Role, помимо всего остального, внутри ее крутится OWIN self-hosted WebAPI. Этот webapi используется как в Angular так и в настольном приложении. Хочется с него собирать телеметрию которая специфична для web — время от начала запроса до first-byte-sent, корреляцию по пользователю — какие запросы от него приходят, как активно он ходит по сайту итд. Ну и видеть статистику по клиентам, браузерам, ОС (это для web запросов, для desktop еще не думали что хотим видеть, но как минимум версию приложения, скорей всего X-Version или что-то такое будем слать).
          В общем ничего невозможного нету, но есть одна загвоздка, как я понял — есть nuget package для всего что хостится на IIS — т.е. в виде HttpHandler, вроде есть не очень понятная бета версия для очередной беты asp.net 5, реализации в виде owin middleware ( для self-hosted и non-IIS серверов) — я не нашел и судя по вот этому ответу от сотрудника MSFT — не сильно планируется.

          Я понимаю что можно написать свою middleware в которой надо дергать AI напрямую, через TelemetryClient или если чуток получше — через serilog +serilog.AI sink. Но так можно логгировать куда угодно, и потом долго и мучительно настраивать диаграммы и чарты в каком-нибудь портале. Но тогда зачем грызть гранит AI.

          Value Application Insights для меня в том что это настроенная связка — клиент который знает что собирать для web запросов и сервер с уже настроенным набором стандартных диаграмм и correlation id. И вот пока не понятно, как задействовать это на полную катушку, а не как «тупой логгер». Может я что-то не понимаю и можно взять версию для ASP.NET 5 и вкрутить в OWIN pipeline? Вроде как сигнатуры middleware похожи, но все- таки отличаются немного (поправьте если я тут не прав, глубоко в asp.net vNext еще не смотрел)…

      Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.

      Самое читаемое