Application Insights RequestTelemetry не отображается в запросах после исключения

Я потратил некоторое время, пытаясь заставить RequestTelemetry работать. Так было, когда я впервые с ним поигрался, но потом, как ни странно, просто перестало работать всякий раз, когда возникает исключение. Я прочитал документацию с использованием Application Insights для настраиваемые события и показатели, а также Отслеживание пользовательских операций и попытался добавить все передовые методы, чтобы увидеть, смогу ли я снова получить результат. Я использую .NET Core 3.1 и Microsoft.ApplicationInsights.AspNetCore 2.14.0.

Настройка для Webapp выглядит так в Startup.cs

services.AddApplicationInsightsTelemetry(new ApplicationInsightsServiceOptions { 
    EnableAdaptiveSampling = false
}); 

У меня есть телеметрия внутри действия Controller Post. Я понимаю, что Application Insights уже отслеживает действие публикации, но я хотел посмотреть, могу ли я отслеживать внутренний метод. Это код в моем контроллере:


public MyController(IMyService myService, TelemetryClient telemetryClient, ILogger<MyController> logger) {
    _myService = myService;
    _telemetryClient = telemetryClient;
    _logger = logger;
}

[HttpPost]
[ProducesResponseType(StatusCodes.Status204NoContent)]
[ProducesResponseType(StatusCodes.Status400BadRequest)]
[ProducesResponseType(StatusCodes.Status401Unauthorized)]
public async Task<IActionResult> PostAsync([FromBody] MyModel model) {
    using var scope = _logger.BeginScope(new Dictionary<string, object> {
        { $"{nameof(PostAsync)}.Scope", Guid.NewGuid() },
        { nameof(model.Name), model.Name }
    });

    model.AuthenticatedUserId = User.GetUserIdFromClaims();

    var requestTelemetry = new RequestTelemetry { Name = nameof( _myService.MyFunctionAsync) };
    var operation = _telemetryClient.StartOperation(requestTelemetry);
    operation.Telemetry.Properties.Add("User", model.AuthenticatedUserId);

    try {
        await _myService.MyFunctionAsync(model).ConfigureAwait(false); // <-- throws exception
        operation.Telemetry.Success = true;
        return NoContent();
    } catch (Exception e) {
        operation.Telemetry.Success = false;
        throw;
    } finally {
        _telemetryClient.StopOperation(operation);
    }
}

В выводе консоли Visual Studio я вижу, что код выполняется, поскольку я получаю следующий журнал, но он никогда не отображается в Application Insights Requests.

Application Insights Telemetry: {
  "name": "AppRequests",
  "time": "2020-06-21T14:29:08.7469588Z",
  "iKey": "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX",
  "tags": {
    "ai.application.ver": "1.0.0.0",
    "ai.cloud.roleInstance": "DESKTOP-K74PNCU",
    "ai.operation.id": "0443259d660125498cf28f8f7a275dab",
    "ai.operation.parentId": "1dea6f9b27220c4c",
    "ai.operation.name": "POST EventEmitter/Post",
    "ai.location.ip": "::1",
    "ai.internal.sdkVersion": "dotnetc:2.14.0-17971",
    "ai.internal.nodeName": "DESKTOP-K74PNCU"
  },
  "data": {
    "baseType": "RequestData",
    "baseData": {
      "ver": 2,
      "id": "2b7900eedfb7c34d",
      "name": "MyFunctionAsync",
      "duration": "00:00:00.3766937",
      "success": false,
      "properties": {
        "DeveloperMode": "true",
        "User": "pobl-dev",
        "_MS.ProcessedByMetricExtractors": "(Name:'Requests', Ver:'1.1')",
        "AspNetCoreEnvironment": "Development"
      }
    }
  }
}

person scottrudy    schedule 21.06.2020    source источник
comment
и как инициализировать _telemetryClient? и при инициализации _telemetryClient вы использовали другой ключ инструментария?   -  person Ivan Yang    schedule 22.06.2020
comment
и является ли throw обязательным здесь, в блоке catch?   -  person Ivan Yang    schedule 22.06.2020
comment
@IvanYang Я обновил код с помощью конструктора, чтобы вы могли видеть инициализацию. Бросок необходим, чтобы глобальный обработчик ошибок улавливал ошибку, а не отслеживал исключение в контроллере.   -  person scottrudy    schedule 22.06.2020


Ответы (2)


Есть простое решение, но я не уверен, зачем оно нужно, из-за отсутствия документации или из-за ошибки. Я обнаружил, что как только был предоставлен responseCode, все работает нормально. По умолчанию responseCode = 200, которое появляется при успешном вызове. Как только я установил значение сбоя, все работало нормально.


public MyController(IMyService myService, TelemetryClient telemetryClient, ILogger<MyController> logger) {
    _myService = myService;
    _telemetryClient = telemetryClient;
    _logger = logger;
}

[HttpPost]
[ProducesResponseType(StatusCodes.Status204NoContent)]
[ProducesResponseType(StatusCodes.Status400BadRequest)]
[ProducesResponseType(StatusCodes.Status401Unauthorized)]
public async Task<IActionResult> PostAsync([FromBody] MyModel model) {
    using var scope = _logger.BeginScope(new Dictionary<string, object> {
        { $"{nameof(PostAsync)}.Scope", Guid.NewGuid() },
        { nameof(model.Name), model.Name }
    });

    model.AuthenticatedUserId = User.GetUserIdFromClaims();

    var requestTelemetry = new RequestTelemetry { Name = nameof( _myService.MyFunctionAsync) };
    var operation = _telemetryClient.StartOperation(requestTelemetry);
    operation.Telemetry.Properties.Add("User", model.AuthenticatedUserId);

    try {
        await _myService.MyFunctionAsync(model).ConfigureAwait(false); // <-- throws exception
        operation.Telemetry.Success = true;
        operation.Telemetry.ResponseCode = "Roses";
        return NoContent();
    } catch (Exception e) {
        operation.Telemetry.Success = false;
        operation.Telemetry.ResponseCode = "Funky"; // <-- seems to be required on a failure
        throw;
    } finally {
        _telemetryClient.StopOperation(operation);
    }
}
person scottrudy    schedule 22.06.2020
comment
На самом деле, вам не нужно устанавливать responseCode (менять код ответа не рекомендуется). Пожалуйста, попробуйте мое решение :). - person Ivan Yang; 23.06.2020
comment
@IvanYang, что ты имеешь в виду, это плохая практика? Можете ли вы указать на справочный документ, в котором говорится об этом? Я вижу примеры этого в обеих ссылках на Microsoft Docs, которые я предоставил в вопросе. - person scottrudy; 24.06.2020
comment
github.com/microsoft/ApplicationInsights- Home / blob / master / Возможно, ResultCode является обязательным полем, и без него серверная часть отклоняет элемент. Это можно проверить, запустив Fiddler и наблюдая за ответом серверной части. - person cijothomas; 12.07.2020
comment
@IvanYang, какое у тебя решение? - person gukoff; 23.06.2021