Reputation: 18526
I have an ASP.NET Core 2.1 WebApi running on a Service Fabric node behind a reverse proxy (Azure Application Gateway).
The Urls are something as follows:
Application Insights is added as usual.
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();
}))
So endpointConfig.PathSuffix
is not being added to the request telemetry. What can I do to fix this? I would prefer to to write a custom telemetry initializer or processor.
I tried adding this line to my WebHostBuilder, without any change in behavior:
.Configure(app => app.UsePathBase(endpointConfig.PathSuffix))
Edit: The PathBase
is identified correctly by ASP.NET Core, but it is missing from the Request Telemetry. If I set up a standalone project without Service Fabric, PathBase is added to Request Telemetry as expected.
Upvotes: 0
Views: 1158
Reputation: 18526
For the sake of completeness, this is what I implemented as a workaround based on LoekD's information:
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}");
}
}
}
Upvotes: 0
Reputation: 11470
According to the docs, you need to register a TelemetryInitializer
, and a call to 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();
...
To work around the issue, you can create a custom telemetry initializer, like this:
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
}
(Inspiration from this issue.)
Upvotes: 1