Application Insights 请求遥测缺少基本路径
Application Insights Request Telemetry missing base path
我在反向代理(Azure 应用程序网关)后面的 Service Fabric 节点上有一个 ASP.NET Core 2.1 WebApi 运行。
网址如下:
- https://mycustomdomain.demo/product/api/controller/action (Public)
- http://myinternalserver:12345/product/api/controller/action(内部)
- https://mycustomdomain.demo/controller/action(应用程序洞察请求遥测)
Application Insights 照常添加。
public void ConfigureServices(IServiceCollection services)
{
services.AddApplicationInsightsTelemetry();
new ServiceInstanceListener(serviceContext => new HttpSysCommunicationListener(serviceContext, "ServerServiceEndpoint",
(url, listener) =>
{
var endpointConfig = serviceContext.CodePackageActivationContext.GetEndpoint("ServerServiceEndpoint");
return new WebHostBuilder()
.UseHttpSys()
.ConfigureServices(services => services.AddSingleton(serviceContext))
.UseContentRoot(Directory.GetCurrentDirectory())
.UseServiceFabricIntegration(listener, ServiceFabricIntegrationOptions.None)
.UseStartup<Startup>()
.UseUrls($"{url}{endpointConfig.PathSuffix}") // "/product/api"
.Build();
}))
所以 endpointConfig.PathSuffix
没有被添加到请求遥测中。我该怎么做才能解决这个问题?我更愿意编写自定义遥测初始化器或处理器。
我尝试将此行添加到我的 WebHostBuilder,但行为没有任何变化:
.Configure(app => app.UsePathBase(endpointConfig.PathSuffix))
编辑:PathBase
被 ASP.NET 核心正确识别,但请求遥测中缺少它。如果我在没有 Service Fabric 的情况下设置独立项目,PathBase 会按预期添加到 Request Telemetry。
根据docs,你需要注册一个TelemetryInitializer
,并调用UseApplicationInsights
:
.UseKestrel()
.ConfigureServices(
services => services
.AddSingleton<HttpClient>(new HttpClient())
.AddSingleton<FabricClient>(new FabricClient())
.AddSingleton<StatelessServiceContext>(serviceContext)
.AddSingleton<ITelemetryInitializer>((serviceProvider) => FabricTelemetryInitializerExtension.CreateFabricTelemetryInitializer(serviceContext)))
.UseContentRoot(Directory.GetCurrentDirectory())
.UseStartup<Startup>()
.UseApplicationInsights()
.UseServiceFabricIntegration(listener, ServiceFabricIntegrationOptions.None)
.UseUrls(url)
.Build();
...
要解决此问题,您可以创建自定义遥测初始化程序,如下所示:
class RewriteUriInitializer : ITelemetryInitializer
{
private const int SegmentsToSkip = 3;
public void Initialize(ITelemetry telemetry)
{
var requestTelemetry = telemetry as RequestTelemetry;
if (requestTelemetry != null)
{
//change requestTelemetry.Url and requestTelemetry.Name
}
(灵感来源于此issue。)
为了完整起见,这是我根据 LoekD 的信息实施的解决方法:
new ServiceInstanceListener(serviceContext => new HttpSysCommunicationListener(serviceContext, "ServerServiceEndpoint",
(url, listener) =>
{
var endpointConfig = serviceContext.CodePackageActivationContext.GetEndpoint("ServerServiceEndpoint");
return new WebHostBuilder()
.UseHttpSys()
.ConfigureServices(services => services
.AddSingleton(serviceContext)
.AddSingleton<ITelemetryInitializer>(c => new RewriteUriInitializer(endpointConfig.PathSuffix)))
.UseContentRoot(Directory.GetCurrentDirectory())
.UseServiceFabricIntegration(listener, ServiceFabricIntegrationOptions.None)
.UseStartup<Startup>()
.UseUrls($"{url}{endpointConfig.PathSuffix}") // "/product/api"
.Build();
}))
class RewriteUriInitializer : ITelemetryInitializer
{
private readonly string _EndpointConfigPathSuffix;
public RewriteUriInitializer(string endpointConfigPathSuffix)
{
_EndpointConfigPathSuffix = endpointConfigPathSuffix;
}
public void Initialize(ITelemetry telemetry)
{
if (telemetry is RequestTelemetry requestTelemetry && requestTelemetry.Url != null)
{
// https://localhost:1234/controller/action => https://localhost:1234/product/api/controller/action
requestTelemetry.Url = new Uri(
new Uri(requestTelemetry.Url.AbsoluteUri.Substring(0,
requestTelemetry.Url.AbsoluteUri.IndexOf(requestTelemetry.Url.PathAndQuery,
StringComparison.OrdinalIgnoreCase))),
$"{_EndpointConfigPathSuffix}{requestTelemetry.Url.PathAndQuery}");
}
}
}
我在反向代理(Azure 应用程序网关)后面的 Service Fabric 节点上有一个 ASP.NET Core 2.1 WebApi 运行。
网址如下:
- https://mycustomdomain.demo/product/api/controller/action (Public)
- http://myinternalserver:12345/product/api/controller/action(内部)
- https://mycustomdomain.demo/controller/action(应用程序洞察请求遥测)
Application Insights 照常添加。
public void ConfigureServices(IServiceCollection services)
{
services.AddApplicationInsightsTelemetry();
new ServiceInstanceListener(serviceContext => new HttpSysCommunicationListener(serviceContext, "ServerServiceEndpoint",
(url, listener) =>
{
var endpointConfig = serviceContext.CodePackageActivationContext.GetEndpoint("ServerServiceEndpoint");
return new WebHostBuilder()
.UseHttpSys()
.ConfigureServices(services => services.AddSingleton(serviceContext))
.UseContentRoot(Directory.GetCurrentDirectory())
.UseServiceFabricIntegration(listener, ServiceFabricIntegrationOptions.None)
.UseStartup<Startup>()
.UseUrls($"{url}{endpointConfig.PathSuffix}") // "/product/api"
.Build();
}))
所以 endpointConfig.PathSuffix
没有被添加到请求遥测中。我该怎么做才能解决这个问题?我更愿意编写自定义遥测初始化器或处理器。
我尝试将此行添加到我的 WebHostBuilder,但行为没有任何变化:
.Configure(app => app.UsePathBase(endpointConfig.PathSuffix))
编辑:PathBase
被 ASP.NET 核心正确识别,但请求遥测中缺少它。如果我在没有 Service Fabric 的情况下设置独立项目,PathBase 会按预期添加到 Request Telemetry。
根据docs,你需要注册一个TelemetryInitializer
,并调用UseApplicationInsights
:
.UseKestrel()
.ConfigureServices(
services => services
.AddSingleton<HttpClient>(new HttpClient())
.AddSingleton<FabricClient>(new FabricClient())
.AddSingleton<StatelessServiceContext>(serviceContext)
.AddSingleton<ITelemetryInitializer>((serviceProvider) => FabricTelemetryInitializerExtension.CreateFabricTelemetryInitializer(serviceContext)))
.UseContentRoot(Directory.GetCurrentDirectory())
.UseStartup<Startup>()
.UseApplicationInsights()
.UseServiceFabricIntegration(listener, ServiceFabricIntegrationOptions.None)
.UseUrls(url)
.Build();
...
要解决此问题,您可以创建自定义遥测初始化程序,如下所示:
class RewriteUriInitializer : ITelemetryInitializer
{
private const int SegmentsToSkip = 3;
public void Initialize(ITelemetry telemetry)
{
var requestTelemetry = telemetry as RequestTelemetry;
if (requestTelemetry != null)
{
//change requestTelemetry.Url and requestTelemetry.Name
}
(灵感来源于此issue。)
为了完整起见,这是我根据 LoekD 的信息实施的解决方法:
new ServiceInstanceListener(serviceContext => new HttpSysCommunicationListener(serviceContext, "ServerServiceEndpoint",
(url, listener) =>
{
var endpointConfig = serviceContext.CodePackageActivationContext.GetEndpoint("ServerServiceEndpoint");
return new WebHostBuilder()
.UseHttpSys()
.ConfigureServices(services => services
.AddSingleton(serviceContext)
.AddSingleton<ITelemetryInitializer>(c => new RewriteUriInitializer(endpointConfig.PathSuffix)))
.UseContentRoot(Directory.GetCurrentDirectory())
.UseServiceFabricIntegration(listener, ServiceFabricIntegrationOptions.None)
.UseStartup<Startup>()
.UseUrls($"{url}{endpointConfig.PathSuffix}") // "/product/api"
.Build();
}))
class RewriteUriInitializer : ITelemetryInitializer
{
private readonly string _EndpointConfigPathSuffix;
public RewriteUriInitializer(string endpointConfigPathSuffix)
{
_EndpointConfigPathSuffix = endpointConfigPathSuffix;
}
public void Initialize(ITelemetry telemetry)
{
if (telemetry is RequestTelemetry requestTelemetry && requestTelemetry.Url != null)
{
// https://localhost:1234/controller/action => https://localhost:1234/product/api/controller/action
requestTelemetry.Url = new Uri(
new Uri(requestTelemetry.Url.AbsoluteUri.Substring(0,
requestTelemetry.Url.AbsoluteUri.IndexOf(requestTelemetry.Url.PathAndQuery,
StringComparison.OrdinalIgnoreCase))),
$"{_EndpointConfigPathSuffix}{requestTelemetry.Url.PathAndQuery}");
}
}
}