API Application Insights 使用的良好实践

Posted

技术标签:

【中文标题】API Application Insights 使用的良好实践【英文标题】:API Application Insights good practice to use 【发布时间】:2018-08-27 11:10:32 【问题描述】:

我阅读了这份文档: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);

有必要吗?还是只需要跟踪异常?然后我会丢失不同的信息,比如谁尝试添加这些更改等...什么时候应该使用这些方法?

【问题讨论】:

您也可以跟踪自定义属性是否存在异常。因此,无需同时跟踪两者(除非您愿意)。 另外 Activity.Current.Tags 应该可以解决问题,但由于某种原因,它们对我不起作用。已打开github.com/Microsoft/ApplicationInsights-dotnet-server/issues/… 如果您的外部调用不是基于 HTTP 的,那么您可能希望将其包装在 this.telemetryClient.StartOperation("MyDependencyCall") 中使用。然后将收集“依赖项”。对于 HTTP AI SDK 会自动收集依赖项。 @ZakiMa 哪个更好(同时跟踪或分别跟踪异常和事件)?如果跟踪异常,跟踪错误事件是否有意义? 建议依赖Requests(传入请求)、Dependencies(传出请求)和Exceptions。自定义事件通常用于无法由请求表示的业务遥测。 【参考方案1】:

您可以独立跟踪所有指标/异常/跟踪/事件。要使信息事件相互关联,请使用TelemetryContext

有必要吗?还是只需要跟踪异常?然后我输了 不同的信息,例如谁尝试添加这些更改等...当每个 这些方法应该用吗?

这仅取决于您的需求。如果您需要该信息 - 请发送。

【讨论】:

因此我询问最佳实践:)【参考方案2】:

这是 2.5.1 AI SDK 的最佳实践。将突出显示即将发布的 AI SDK 版本中可能不需要的部分。

进行端到端跟踪的正确方法是依赖 .NET 框架中的新 Activity 类。在 AI 支持 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;
    

您应该有以下遥测数据:

    收到的请求 传出请求(依赖项) 失败请求的例外情况

所有遥测数据都将带有 ChangedBy 和 DriverID 标记

【讨论】:

我们如何在 azure 函数中使用Activity 有人在 azure 函数中使用它吗?会喜欢一个例子

以上是关于API Application Insights 使用的良好实践的主要内容,如果未能解决你的问题,请参考以下文章

Azure Application Insights REST API使用教程

Service Fabric Api Gateway 上的 Application Insights 端到端中断

Application Insights 请求计数指标与查询不匹配

Application Insights 数据采样

ILogger 到 Application Insights

Azure Application Insights 不显示数据