Рекомендации по использованию API Application Insights

Я прочитал эту документацию: https://docs.microsoft.com/en-us/azure/application-insights/app-insights-api-custom-events-metrics

Существует множество различных методов API для отслеживания исключений, отслеживания трассировки и т. Д.

У меня есть приложение ASP.NET MVC 5. Например, у меня есть следующий метод контроллера (вызываемый ajax):

    [AjaxErrorHandling]
    [HttpPost]
    public async Task SyncDriverToVistracks(int DriverID)
    {
            if ([condition])
            {
                // some actions here

                try
                {
                    driver.VistrackId = await _vistracksService.AddNewDriverToVistrackAsync(domain);
                    await db.SaveChangesAsync();
                }
                catch (VistracksApiException api_ex)
                {
                    // external service throws exception type VistracksApiException 
                    throw new AjaxException("vistracksApiClient", api_ex.Response.Message);
                }
                catch (VistracksApiCommonException common_ex)
                {
                    // external service throws exception type VistracksApiCommonException 
                    throw new AjaxException("vistracksApiServer", "3MD HOS server is not available");
                }
                catch (Exception ex)
                {
                    // something wrong at all
                    throw new AjaxException("General", ex.Message);
                }
            }
            else
            {
                // condition is not valid
                throw new AjaxException("General", "AccountId is not found");
            }
    }

этот метод выдает AjaxException, если что-то не так (которое перехватывает AjaxErrorHandling, а затем возвращает что-то json-ответ клиенту).

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

Итак, я добавил следующее:

    [AjaxErrorHandling]
    [HttpPost]
    public async Task SyncDriverToVistracks(int DriverID)
    {
            telemetryClient.TrackEvent("Sync driver", new Dictionary<string, string> { { "ChangedBy", User.Identity.Name }, { "DriverID", DriverID.ToString() } }, null);
            if ([condition])
            {
                // some actions here

                try
                {
                    driver.VistrackId = await _vistracksService.AddNewDriverToVistrackAsync(domain);
                    await db.SaveChangesAsync();
                }
                catch (VistracksApiException api_ex)
                {
                    // external service throws exception type VistracksApiException 
                    telemetryClient.TrackTrace("VistracksApiException", new Dictionary<string, string> {
                        { "ChangedBy", User.Identity.Name },
                        { "DriverID", DriverID.ToString() },
                        { "ResponseCode", api_ex.Response.Code.ToString() },
                        { "ResponseMessage", api_ex.Response.Message },
                        { "ResponseDescription", api_ex.Response.Description }
                    });
                    telemetryClient.TrackException(api_ex);

                    throw new AjaxException("vistracksApiClient", api_ex.Response.Message);
                }
                catch (VistracksApiCommonException common_ex)
                {
                    // external service throws exception type VistracksApiCommonException 
                    telemetryClient.TrackTrace("VistracksApiCommonException", new Dictionary<string, string> {
                        { "ChangedBy", User.Identity.Name },
                        { "DriverID", DriverID.ToString() },
                        { "Message", common_ex.Message },
                    });
                    telemetryClient.TrackException(common_ex);
                    throw new AjaxException("vistracksApiServer", "3MD HOS server is not available");
                }
                catch (Exception ex)
                {
                    // something wrong at all
                    telemetryClient.TrackTrace("Exception", new Dictionary<string, string> {
                        { "ChangedBy", User.Identity.Name },
                        { "DriverID", DriverID.ToString() },
                        { "Message", ex.Message },
                    });
                    telemetryClient.TrackException(ex);
                    throw new AjaxException("General", ex.Message);
                }
            }
            else
            {
                telemetryClient.TrackTrace("ConditionWrong", new Dictionary<string, string> {
                    { "ChangedBy", User.Identity.Name },
                    { "DriverID", DriverID.ToString() },
                    { "Message", "AccountId is not found" },
                });
                // condition is not valid
                throw new AjaxException("General", "AccountId is not found");
            }
    }

следующей строкой:

        telemetryClient.TrackEvent("Sync driver", new Dictionary<string, string> { { "ChangedBy", User.Identity.Name }, { "DriverID", DriverID.ToString() } }, null);

Я просто "записываю" клиентское событие о том, что метод был вызван. Просто для статистики.

В каждом блоке "catch" я пытаюсь написать трассировку с разными параметрами и записать исключение:

                    telemetryClient.TrackTrace("trace name", new Dictionary<string, string> {
                        { "ChangedBy", User.Identity.Name },
                        ....
                    });
                    telemetryClient.TrackException(ex);

Это необходимо? Или просто нужно отслеживать только исключение? Затем я теряю различную информацию, например, кто пытается добавить эти изменения и т. Д. Когда следует использовать каждый из этих методов?


person Oleg Sh    schedule 18.03.2018    source источник
comment
Вы также можете отслеживать настраиваемые свойства для исключения. Таким образом, нет необходимости отслеживать и то, и другое (если вы этого не хотите).   -  person ZakiMa    schedule 19.03.2018
comment
Также Activity.Current.Tags должен помочь, но по какой-то причине они не работали для меня. Открыл github.com/Microsoft/ApplicationInsights-dotnet-server/issues/   -  person ZakiMa    schedule 19.03.2018
comment
Если ваш внешний вызов не основан на HTTP, вы можете заключить его в this.telemetryClient.StartOperation ‹DependencyTelemetry› (MyDependencyCall), используя. Тогда будет собрана зависимость. Для HTTP AI SDK автоматически собирает зависимости.   -  person ZakiMa    schedule 19.03.2018
comment
@ZakiMa, что лучше (отслеживать оба или отслеживать отдельно исключение и событие)? Имеет ли смысл отслеживать события ошибок, если отслеживает исключение?   -  person Oleg Sh    schedule 20.03.2018
comment
Рекомендуется полагаться на запросы (входящие запросы), зависимости (исходящие запросы) и исключения. Пользовательские события обычно используются для бизнес-телеметрии, которые не могут быть представлены запросами.   -  person ZakiMa    schedule 20.03.2018
comment
id интересно узнать, повезло ли кому-нибудь использовать Activity с функциями azure для выполнения сквозной распределенной трассировки   -  person Alex Gordon    schedule 11.10.2019


Ответы (2)


Это лучшая практика для 2.5.1 AI SDK. Выделит части, которые могут не потребоваться в следующих выпусках AI SDK.

Правильный способ выполнять сквозную трассировку - полагаться на новый класс Activity в .NET framework. Пока ИИ не поддерживает Activity.Tags (https://github.com/Microsoft/ApplicationInsights-dotnet/issues/562) вам необходимо распространить их вручную с помощью TelemetryInitializer:

public class ActvityTagsTelemetryInitializer : ITelemetryInitializer
{
    public void Initialize(ITelemetry telemetry)
    {
        Activity current = Activity.Current;

        if (current == null)
        {
            current = (Activity)HttpContext.Current?.Items["__AspnetActivity__"];
        }

        while (current != null)
        {
            foreach (var tag in current.Tags)
            {
                if (!telemetry.Context.Properties.ContainsKey(tag.Key))
                {
                    telemetry.Context.Properties.Add(tag.Key, tag.Value);
                }
            }

            current = current.Parent;
        }
    }
}

Затем зарегистрируйте его в ApplicationInsights.config:

  <TelemetryInitializers>
    ...
    <Add Type="<namespace>.ActvityTagsTelemetryInitializer, <assemblyname>"/>
  </TelemetryInitializers>

Затем вы можете заполнить правильные теги:

[AjaxErrorHandling]
[HttpPost]
public async Task SyncDriverToVistracks(int DriverID)
{
    Activity.Current.AddTag("DriverID", DriverID.ToString());
    Activity.Current.AddTag("UserID", User.Identity.Name);

    try
    {
        if ([condition])
        {
            // some actions here

            try
            {
                // If below call is HTTP then no need to use StartOperation
                using (telemetryClient.StartOperation<DependencyTelemetry>("AddNewDriverToVistrackAsync"))
                {
                    driver.VistrackId = await _vistracksService.AddNewDriverToVistrackAsync(domain);
                }

                // If below call is HTTP then no need to use StartOperation
                using (telemetryClient.StartOperation<DependencyTelemetry>("SaveChanges"))
                {
                    await db.SaveChangesAsync();
                }
            }
            catch (VistracksApiException api_ex)
            {
                // external service throws exception type VistracksApiException 
                throw new AjaxException("vistracksApiClient", api_ex.Response.Message);
            }
            catch (VistracksApiCommonException common_ex)
            {
                // external service throws exception type VistracksApiCommonException 
                throw new AjaxException("vistracksApiServer", "3MD HOS server is not available");
            }
            catch (Exception ex)
            {
                // something wrong at all
                throw new AjaxException("General", ex.Message);
            }
        }
        else
        {
            // condition is not valid
            throw new AjaxException("General", "AccountId is not found");
        }
    }
    catch (Exception ex)
    {
        // Upcoming 2.6 AI SDK will track exceptions for MVC apps automatically.
        telemetryClient.TrackException(ex);
        throw;
    }
}

У вас должна быть следующая телеметрия:

  1. Входящий запрос
  2. Исходящие запросы (зависимости)
  3. Исключения для неудавшихся запросов

Вся телеметрия будет помечена ChangedBy и DriverID.

person ZakiMa    schedule 20.03.2018
comment
как мы используем Activity в функциях лазурного? - person Alex Gordon; 11.10.2019
comment
кто-нибудь использует это в лазурных функциях? хотел бы пример - person Alex Gordon; 11.10.2019

Вы можете отслеживать все метрики / исключения / трассировки / события независимо. Чтобы информационные события были связаны друг с другом, используйте TelemetryContext

Это необходимо? Или просто нужно отслеживать только исключение? Затем я теряю различную информацию, например, кто пытается добавить эти изменения и т. Д. Когда следует использовать каждый из этих методов?

Это зависит только от ваших потребностей. Если вам нужна эта информация - отправьте ее.

person Evgeny Gorbovoy    schedule 18.03.2018
comment
поэтому я спрашиваю о лучшем опыте :) - person Oleg Sh; 20.03.2018