首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >应用程序洞察异常后请求中未显示的RequestTelemetry

应用程序洞察异常后请求中未显示的RequestTelemetry
EN

Stack Overflow用户
提问于 2020-06-21 14:49:04
回答 2查看 1.5K关注 0票数 4

我花了一段时间试图在RequestTelemetry上工作。当我第一次玩它的时候,它做到了,但奇怪的是,每当抛出异常时,它就会停止工作。我已经阅读了使用自定义事件和度量的应用程序洞察自定义操作跟踪的文档,并尝试添加所有的最佳实践,看看是否能够再次显示结果。我正在使用.NET Core3.1和Microsoft.ApplicationInsights.AspNetCore 2.14.0。

for应用程序的设置在Startup.cs中如下所示

代码语言:javascript
复制
services.AddApplicationInsightsTelemetry(new ApplicationInsightsServiceOptions { 
    EnableAdaptiveSampling = false
}); 

我有一个控制器后行动内部的遥测。我意识到Application已经在跟踪它的post操作,但我想看看是否可以跟踪内部方法。这是我的控制器中的代码:

代码语言:javascript
复制
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控制台输出中看到代码执行的情况,因为我得到了下面的日志,但它从未出现在Application Requests中。

代码语言:javascript
复制
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"
      }
    }
  }
}
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2020-06-22 19:09:52

有一个简单的解决方案,但我不知道为什么它是必要的,因为缺乏文档或错误。我发现,一旦提供了一个responseCode,一切都正常。有一个默认的responseCode of 200,它出现在一个成功的调用中。一旦我设定了失败的价值,一切都很好。

代码语言:javascript
复制
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);
    }
}
票数 8
EN

Stack Overflow用户

发布于 2021-04-13 06:29:47

这是为了在接受的答案中添加一些上下文,如果您好奇的话:

这是源代码 for RequestTelemetry

当它准备将数据发送到Azure服务器时,它显式地选择不设置默认响应代码,除非是success == true,在这种情况下,默认是200

代码语言:javascript
复制
// Required fields
if (!this.Success.HasValue)
{
    this.Success = true;
}

if (string.IsNullOrEmpty(this.ResponseCode))
{
    this.ResponseCode = this.Success.Value ? "200" : string.Empty;
}     

如果您对日志运行一个简单的Kusto查询:

union请求> where时间戳>ago(1小时)>在(“标识”)中customDimensions"CustomOperationCategory“的位置取100

只有在设置状态代码的情况下,才会看到不成功的结果:

我不知道是否有什么变化,但微软的例子有时也会这样做

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/62500162

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档