1

我正在为 ASP.NET Core Web API 进行 Jaeger Tracing 的一些原型设计,并且我能够使用入门文档中描述的 Jaeger 的多合一实例Startup.ConfigureServices()以及我的方法中的以下代码使其工作:

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;
    };
});

要使用所有这些,您需要在项目中添加一些包:

  1. dotnet add package OpenTracing.Contrib.NetCore --version 0.6.2
  2. dotnet add package Jaeger --version 0.4.1

所以这工作正常,我的 Jaeger Search UI (http://localhost:16686/search) 中显示了带有 Spans 的 Trace,但它只显示带有我的服务名称的 Trace(在本例中为“MySuperCoolWebAPI”),后跟“ HTTP 获取”:

jaeger ui截图

在那里看到“HTTP GET”并不是非常有用。相反,我想查看 Web API 操作名称或其他内容,让我知道这到底是什么类型的请求。

正如您从上面的示例代码中看到的那样,我尝试设置HttpHandlerDiagnosticOptions.OperationNameResolver但这只会影响HttpClient我从我的 Web 服务中进行的调用。它似乎不会影响与我收到的请求关联的 Trace/Span 的命名方式。

我还尝试使用这样的 GlobalTracer 在我的 Web API Controller 方法中设置 Span OperationName ,但这会影响内部跨度,而不是 Jaeger UI 搜索结果页面上显示的主 Trace/Span:

OpenTracing.Util.GlobalTracer.Instance.ActiveSpan.SetOperationName("My Web API Action Name");

在这里,您可以看到第一个子 Span 的名称设置为我强制设置的名称,但主级别 Span(我更改的那个的父级)不受影响:

带有子跨度的 jaeger ui 屏幕截图

有没有办法可以使用 Jaeger C# Client 设置主 Span 的操作名称?

另外,我正在使用 .NET Core 3.1,以防万一。

4

1 回答 1

2

在挖掘 OpenTracing C# .NET Core 源代码 ( https://github.com/opentracing-contrib/csharp-netcore ) 之后,我想出了如何覆盖顶级 Span.OperationName。

我不得不将我的Startup.ConfigureServices()调用更新services.AddOpenTracing()为以下内容:

services.AddOpenTracingCoreServices(otBuilder =>
{
    otBuilder.AddAspNetCore()
        .ConfigureAspNetCore(options =>
        {
            options.Hosting.OperationNameResolver = (httpContext) =>
            {
                return $"MySuperCoolOperationName ({httpContext.Request.Path.Value})";
            };
        })
        .AddCoreFx()
        .AddEntityFrameworkCore()
        .AddLoggerProvider();
});
于 2020-09-24T03:22:45.070 回答