MiniAPI(二十八)：Tracing

ログ、メトリクス、トレーシングは、サービスの正常な稼働を保証する三つ組です。以前、ログとメトリクスについて紹介しましたが、今回はトレーシングについて説明します。トレーシングの考え方はメトリクスと同じで、サードパーティのサービスを通じて効果を実現します。ここではJaegerを選択し、MiniAPIプロジェクトにJaegerとOpenTracingのライブラリを導入することで、Jaegerへの追跡データのプッシュを行い、http://localhost:16686/search にアクセスして追跡結果を確認します。
Jaegerダウンロードアドレス：
https://www.jaegertracing.io/download/
次に、OrderプロジェクトとStockプロジェクトの２つを定義します。Orderはhttpclientを通じてStockを呼び出し、商品在庫を確認します。このようにして、2つのプロジェクトは1つの呼び出しチェーンを形成します。
Orderプロジェクト
```csharp
using Jaeger;
using OpenTracing.Propagation;
using OpenTracing;
using OpenTracing.Util;
using Jaeger.Samplers;
using Jaeger.Senders.Thrift;
using Jaeger.Senders;
using Jaeger.Reporters;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddHttpClient(); // OpenTracingサービスを注入
builder.Services.AddOpenTracing();
builder.Services.AddSingleton<ITracer>(serviceProvider =>{
    var serviceName = serviceProvider.GetRequiredService<IWebHostEnvironment>().ApplicationName;
    var loggerFactory = serviceProvider.GetRequiredService<ILoggerFactory>();
    // トレーシングの設定
    Jaeger.Configuration.SenderConfiguration.DefaultSenderResolver = new SenderResolver(loggerFactory)
        .RegisterSenderFactory<ThriftSenderFactory>();
    var tracer = new Tracer.Builder(serviceName)
        // ロギングフレームワークを追加
        .WithLoggerFactory(loggerFactory)
        // データ収集器を追加
        .WithSampler(new ConstSampler(true))
        .Build();
    // グローバルトレーサーを登録
    GlobalTracer.Register(tracer);
    return tracer;
});
var app = builder.Build();
app.MapGet("/order", async (ILogger<Program> logger, IHttpClientFactory clientFactory, ITracer tracer) =>{
    using (var scope = tracer.BuildSpan("订单系统").StartActive(true))
    {
        logger.LogInformation("订单查询库存");
        var client = clientFactory.CreateClient();
        var content = await client.GetStringAsync("http://localhost:5160/stock/D0001");
        return $"stock调用结果：{content}";
    }
});
app.Run();
```
Stockプロジェクト
```csharp
using Jaeger;
using Jaeger.Reporters;
using Jaeger.Samplers;
using Jaeger.Senders;
using Jaeger.Senders.Thrift;
using OpenTracing;
using OpenTracing.Util;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddOpenTracing();
builder.Services.AddSingleton<ITracer>(serviceProvider =>{
    var serviceName = serviceProvider.GetRequiredService<IWebHostEnvironment>().ApplicationName;
    var loggerFactory = serviceProvider.GetRequiredService<ILoggerFactory>();
    Jaeger.Configuration.SenderConfiguration.DefaultSenderResolver = new SenderResolver(loggerFactory)
        .RegisterSenderFactory<ThriftSenderFactory>();
    var tracer = new Tracer.Builder(serviceName)
        .WithLoggerFactory(loggerFactory)
        .WithSampler(new ConstSampler(true))
        .Build();
    GlobalTracer.Register(tracer);
    return tracer;
});
var app = builder.Build();
app.MapGet("/stock/{no}", (string no, ILogger<Program> logger, ITracer tracer) =>{
    using (var scope = tracer.BuildSpan("库存系统").StartActive(true))
    {
        logger.LogInformation("按{0}查询库存", no);
        return new Product { No = no, Quantity = 1324, Name = "Surface Go 3" };
    }
});
app.Run();
public class Product{
    public string? No { get; set; }
    public string? Name { get; set; }
    public int Quantity { get; set; }
}
```
コマンドラインでダウンロードしたjaeger-all-in-one.exeを実行し、ブラウザーやpostmanでOrderプロジェクトの/orderアドレスにアクセスし、その後Jaegerで結果を確認します：http://localhost:16686/search
![alt 画像](https://mmbiz.qpic.cn/mmbiz_jpg/4CAA63nvHRATR51ZYbsQIeENXnQqibOiaTia0Qkg1JooIoOmbdiamsaMXdibpdVIAUdRiclBjmduia8hSZ8UIJbXCNKww/640?wx_fmt=jpeg)
![alt 画像](https://mmbiz.qpic.cn/mmbiz_png/4CAA63nvHRATR51ZYbsQIeENXnQqibOiaTCtkKN9rVSq0nvHoE9EaYgFPkYfciaic8DbtoENXNiaHIloHayP6rGibqpQ/640?wx_fmt=png)
![alt 画像](https://mmbiz.qpic.cn/mmbiz_png/4CAA63nvHRATR51ZYbsQIeENXnQqibOiaT80o2UmcibzfDPTriboXvH0MukvxC42a4TgGS0XdD16RfbQf1rnAz3VVw/640?wx_fmt=png)
![alt 画像](https://mmbiz.qpic.cn/mmbiz_png/4CAA63nvHRATR51ZYbsQIeENXnQqibOiaT4gbdM7sg1PDdJ3lf527W4sR9d1bx2ZegHFjIJYRyzVQQoBoRjSibcFQ/640?wx_fmt=png)
上記のUIを通じて、リクエストチェーン上の呼び出しを便利に確認できます。呼び出し関係が複雑な場合に特に有用です。

(Translated by GPT)

元のリンク：https://mp.weixin.qq.com/s?__biz=MzA3NDM1MzIyMQ==&mid=2247485038&idx=1&sn=954f703023794928668343298de289ff&chksm=9f005944a877d05278831ef741fbbd5ee502bd463040f6fe30cd8753cdb82ef813179396ed56&token=732480897&lang=zh_CN#rd