If you only add HttpClient instrumentation to an ASP.NET Core app, no spans from HttpClient are collected.
The issue is not specific to HttpClient instrumentation. I have also reproduced this when adding only Grpc.Net.Client instrumentation.
dotnet new webapi
dotnet add package --version 0.5.0-beta.2 OpenTelemetry.Instrumentation.Http
dotnet add package --version 0.5.0-beta.2 OpenTelemetry.Exporter.Console
dotnet add package --version 0.5.0-beta.2 OpenTelemetry.Instrumentation.AspNetCore
# Replace contents of Startup.cs with code below
dotnet run
# Navigate to https://localhost:5001/WeatherForecast
# This example uses the Console exporter. Observe no spans generated.
# Follow the instructions in the code comments to resolve the issue.
using System.Net.Http;
using Microsoft.AspNetCore.Builder;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using OpenTelemetry.Trace;
public class Startup
{
public void ConfigureServices(IServiceCollection services)
{
services.AddOpenTelemetryTracerProvider(builder => {
builder
// Uncomment the following line enabling AspNetCore instrumentation
// This will result in seeing a span for both AspNetCore requests and the HttpClient invocation
// .AddAspNetCoreInstrumentation()
.AddHttpClientInstrumentation()
.AddConsoleExporter();
});
services.AddControllers();
}
public void Configure(IApplicationBuilder app)
{
app.Use(async (context, next) =>
{
await next.Invoke();
using var client = new HttpClient();
await client.GetStringAsync("https://opentelemetry.io");
});
app.UseRouting();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
}
}
See my analysis below for the reason why this occurs. Some thoughts come to my mind on how best to address this issue.
ParentBasedSampler.Did some investigation, the reason the HttpClient span does not show up without adding the ASP.NET Core instrumentation is because the ParentBasedSampler _always_ makes a NotRecord decision.
It _does_ have a parent (the ASP.NET Core HTTP IN activity), so parentContext.SpanId != default here
https://github.com/open-telemetry/opentelemetry-dotnet/blob/32fb7c12f1269147bea1080f04ea4ba489aa0f63/src/OpenTelemetry/Trace/ParentBasedSampler.cs#L43-L49
The parent's TraceFlags do not indicate Recorded here
https://github.com/open-telemetry/opentelemetry-dotnet/blob/32fb7c12f1269147bea1080f04ea4ba489aa0f63/src/OpenTelemetry/Trace/ParentBasedSampler.cs#L51-L55
So the sampling decision always falls through to here
https://github.com/open-telemetry/opentelemetry-dotnet/blob/32fb7c12f1269147bea1080f04ea4ba489aa0f63/src/OpenTelemetry/Trace/ParentBasedSampler.cs#L69-L70
I guess this behavior is expected, but it does seem a bit unintuitive. That is, as a user I explicitly decide I only want HttpClient instrumentation, but that does not prevent ASP.NET Core from creating activities which will often be the root activity in a trace and influence downstream sampling decisions.
I suppose a work around would be to not use the ParentBasedSampler...
I also can see an argument that it is an unlikely scenario that someone wants to use OpenTelemetry with their ASP.NET Core and _not_ enable ASP.NET Core instrumentation.
Same issue reported differently:
As reported in gitter channel this is an issue if you try to start own activity inside an AspNetCore application without enabling the AspNetCoreInstrumentation.
@alanwest The root of the issue is some libraries (eg: Asp.Net Core) is creating activity irrespective of whether Otel asked is to do so. This is a "by design" behaviour for Asp.Net Core. Will try to see if Asp.Net Core has plans to disable this feature by default.
The best we can do is to document this behaviour. Tagging this as a documentation issue.
I've just hit that issue. I just need to trace my custom Activities (effectively I have AddSource in place of AddHttpClientInstrumentation of the example) and don't care about AspNetCoreInstrumentation but still, I can't turn it off or nothing is logged. I've tried to turn it on and filter everything out (.AddAspNetCoreInstrumentation(c => c.Filter = ctx => false)) but it's not working in that case also. That's sad. Is there a way to "turn on" tracing in ASP .NET Core without listening to "built-in" activities?
@mitoihs You can use a diff. sampler other than the default ParentBased sampler. This should give you the required solution for you.