如何在使用OWIN的WebApi项目上启用Application Insights服务器遥测?

我们遇到了一堆问题(读取很长的响应时间)以及生产中的几个项目,并希望确切地看到服务器上发生了什么。 然后,我按照本文继续将Application Insights添加到我们的所有项目中。 问题是我们的两个WebAPI项目都没有将服务器数据发送到Azure门户,而所有其他项目(MVC 5)都是。

这是我在Azure上访问相应的Application Insights刀片时显示的内容:

在此处输入图像描述

我尝试在Azure VM中的Application Insights状态监视器中禁用并重新启用数据收集,在向API发出请求时重启IIS几次,但无济于事。 当我在MVC项目上启用它时,当我打开网站上的页面时,我几乎可以立即在Azure门户上看到数据。

当我看到我们的Azure VM没有为这些特定项目发送数据时,我尝试在我们的开发环境中设置相同的集合,该环境托管在我们自己的基础架构中,并且完全相同的情况重复出现,排除了可能性这与Azure VM中托管的项目有关。

我不确定是什么阻止这些项目向Azure发送数据,但通过查看工作项目与非工作项目,我认为它可能与我们的WebAPI项目使用新的OWIN这一事实有关管道虽然MVC是标准的MVC项目。 我检查了两个项目类型的web.config文件和bin文件夹,它们似乎被Insights Monitor正确修改(我可以看到添加到bin文件夹的相同新dll和添加到Web的相同http模块。配置)。

考虑到这一点,如何使用依赖于OWIN / Katana管道的WebAPI项目的Application Insights启用服务器端遥测? 在这种情况下,我该怎么做才能找出导致项目无法向Azure发送数据的确切原因?

AI使用httpmodule收集有关开始请求的信息,并在结束请求时发送。 如此处所述, Owin / Katana使用middelware来在不同的阶段执行逻辑。 由于大多数AI自动收集逻辑都是内部的,因此您无法在中间件中重复使用它。 但您可以自己检测代码。 从您的代码创建TelemetryClient并开始发送请求,跟踪和exception(如此处所述)

这是一个老问题,但它仍然在搜索“web api application insights owin”的前3名结果中。 经过大量的搜索,而不是很多答案,不需要我们编写自己的中间件或明确地检测一切。 我们遇到了一个扩展包,它使事情变得非常简单:

这是它的Github存储库和相关的NuGet包

对于那些懒得查看链接的人来说,需要添加的是:

public class Startup { public void Configuration(IAppBuilder app) { app.UseApplicationInsights(); // rest of the config here... } } 

并将其添加到您的ApplicationInsights.Config

     

以下是我们针对Application Insights的OWIN中间件的实现。

 ///  /// Extensions to help adding middleware to the OWIN pipeline ///  public static class OwinExtensions { ///  /// Add Application Insight Request Tracking to the OWIN pipeline ///  ///  public static void UseApplicationInsights(this IAppBuilder app) => app.Use(typeof(ApplicationInsights)); } ///  /// Allows for tracking requests via Application Insight ///  public class ApplicationInsights : OwinMiddleware { ///  /// Allows for tracking requests via Application Insight ///  ///  public ApplicationInsights(OwinMiddleware next) : base(next) { } ///  /// Tracks the request and sends telemetry to application insights ///  ///  ///  public override async Task Invoke(IOwinContext context) { // Start Time Tracking var sw = new Stopwatch(); var startTime = DateTimeOffset.Now; sw.Start(); await Next.Invoke(context); // Send tracking to AI on request completion sw.Stop(); var request = new RequestTelemetry( name: context.Request.Path.Value, startTime: startTime, duration: sw.Elapsed, responseCode: context.Response.StatusCode.ToString(), success: context.Response.StatusCode >= 200 && context.Response.StatusCode < 300 ) { Url = context.Request.Uri, HttpMethod = context.Request.Method }; var client = new TelemetryClient(); client.TrackRequest(request); } }