Reputation: 1109
I am doing some prototyping of Jaeger Tracing for an ASP.NET Core Web API and I am able to get it working using the All in One instance of Jaeger described in the Getting Started documentation and the following code in my Startup.ConfigureServices()
method:
services.AddOpenTracing();
services.AddSingleton<ITracer>(serviceProvider =>
{
string serviceName = serviceProvider.GetRequiredService<IWebHostEnvironment>().ApplicationName;
ILoggerFactory loggerFactory = serviceProvider.GetRequiredService<ILoggerFactory>();
// Using the UDP sender
Jaeger.Senders.Thrift.UdpSender udpSender = new Jaeger.Senders.Thrift.UdpSender();
var reporter = new RemoteReporter.Builder().WithLoggerFactory(loggerFactory).WithSender(udpSender).Build();
var sampler = new ConstSampler(true); //new GuaranteedThroughputSampler(samplingRate, lowerBound);
ITracer tracer = new Tracer.Builder(serviceName).WithLoggerFactory(loggerFactory).WithReporter(reporter).WithSampler(sampler).Build();
// Allows code that can't use DI to also access the tracer.
GlobalTracer.Register(tracer);
return tracer;
});
services.Configure<HttpHandlerDiagnosticOptions>(options =>
{
//options.IgnorePatterns.Add(x => false);
options.IgnorePatterns.Add(x => x.RequestUri.IsLoopback);
options.OnRequest = (span, request) =>
{
span.SetTag("MyCustomTag", request.RequestUri.AbsoluteUri);
};
options.OperationNameResolver = (request) =>
{
return "X-" + request.RequestUri.AbsoluteUri;
};
});
To use all this, you need to add a few packages to your project:
dotnet add package OpenTracing.Contrib.NetCore --version 0.6.2
dotnet add package Jaeger --version 0.4.1
So this works OK and I get Traces with their Spans showing up in my Jaeger Search UI (http://localhost:16686/search) but it just shows the Trace with my service name (in this case "MySuperCoolWebAPI") followed by "HTTP GET":
This is not terribly useful to see "HTTP GET" there. Instead, I want to see the Web API action name or something else that lets me know what kind of request this really is.
As you can see from my sample code above, I have tried setting the HttpHandlerDiagnosticOptions.OperationNameResolver
but this only affects HttpClient
calls I make from within my web service. It does not seem to affect how the Trace/Span associated with the request I received is named.
I also tried setting the Span OperationName in my Web API Controller method using the GlobalTracer like this but this affects an inner span and NOT the main Trace/Span that shows up on the main Jaeger UI search results page:
OpenTracing.Util.GlobalTracer.Instance.ActiveSpan.SetOperationName("My Web API Action Name");
Here you can see the first child Span has its name set to what I forced it to but the main level Span (the parent of the one I changed) is not affected:
Is there a way I can set the operation name of the main Span with the Jaeger C# Client?
Also, I am using .NET Core 3.1 in case that is relevant.
Upvotes: 1
Views: 2629
Reputation: 1109
After digging around in the OpenTracing C# .NET Core source (https://github.com/opentracing-contrib/csharp-netcore) I figured out how to override the top level Span.OperationName.
I had to update my Startup.ConfigureServices()
call to services.AddOpenTracing()
to the following:
services.AddOpenTracingCoreServices(otBuilder =>
{
otBuilder.AddAspNetCore()
.ConfigureAspNetCore(options =>
{
options.Hosting.OperationNameResolver = (httpContext) =>
{
return $"MySuperCoolOperationName ({httpContext.Request.Path.Value})";
};
})
.AddCoreFx()
.AddEntityFrameworkCore()
.AddLoggerProvider();
});
Upvotes: 2