HTTP 経由で通信するアプリケーションを構築するときは、要求のパフォーマンス特性を観察することが重要です。
AddHttpClientLatencyTelemetry拡張機能を使用すると、呼び出し元のコードに変更を加えず、送信 HTTP 呼び出しの詳細なタイミング情報を収集できます。
既存の HttpClientFactory パイプラインに接続して、要求ライフサイクル全体のステージタイミングをキャプチャし、HTTP プロトコルの詳細を記録し、ランタイムがそのデータを公開するガベージ コレクションへの影響を測定し、パフォーマンス分析とチューニングに適した均一なテレメトリ形状を出力します。
AddHttpClientLatencyTelemetry()拡張メソッドを呼び出して、このテレメトリを有効にします。
組み込みハンドラーは、送信要求ごとに ILatencyContext を作成し、内部パイプラインが完了するまでにメジャーを設定します。 消費した後に、await base.SendAsync(...) を後で追加した委任ハンドラー (テレメトリ後に追加) で処理し、メトリックバックエンドにエクスポートします。 例:
レジスター拡張メソッド:
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Http.Diagnostics;
using Microsoft.Extensions.Hosting;
var builder = Host.CreateApplicationBuilder(args);
// An example of some accessor that is able to read latency context
builder.Services.AddSingleton<ILatencyContextAccessor, LatencyContextAccessor>();
// Register HTTP client latency telemetry first so its delegating handler runs earlier.
builder.Services.AddHttpClientLatencyTelemetry();
// Register export handler (runs after telemetry; sees finalized ILatencyContext).
builder.Services.AddTransient<HttpLatencyExportHandler>();
// Register an HttpClient that will emit and export latency measures.
builder.Services
.AddHttpClient("observed")
.AddHttpMessageHandler<HttpLatencyExportHandler>();
var host = builder.Build();
await host.RunAsync();
コンテキストにアクセスします。
public sealed class HttpLatencyExportHandler : DelegatingHandler
{
// ILatencyContextAccessor is just an example of some accessor that is able to read latency context
private readonly ILatencyContextAccessor _latency;
public HttpLatencyExportHandler(ILatencyContextAccessor latency) => _latency = latency;
protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken ct)
{
var rsp = await base.SendAsync(request, ct).ConfigureAwait(false);
var ctx = _latency.Current;
if (ctx != null)
{
var data = ctx.LatencyData;
// Record/export gc and conn with version as a dimension here.
}
return rsp;
}
}
パッケージを追加する
dotnet add package Microsoft.Extensions.Http.Diagnostics --version 9.10.0
詳細については、「.NET アプリケーションでの dotnet パッケージの追加 または パッケージの依存関係の管理」を参照してください。
HTTP クライアント待機時間テレメトリを登録する
HTTP クライアント待機時間テレメトリをアプリケーションに追加するには、サービスを構成するときに AddHttpClientLatencyTelemetry 拡張メソッドを呼び出します。
var builder = WebApplication.CreateBuilder(args);
// Add HTTP client factory
builder.Services.AddHttpClient();
// Add HTTP client latency telemetry
builder.Services.AddHttpClientLatencyTelemetry();
この登録により、DelegatingHandlerによって作成されたすべての HTTP クライアントにIHttpClientFactoryが追加され、各要求の詳細な待機時間情報が収集されます。
テレメトリ オプションを構成する
テレメトリ収集は、 HttpClientLatencyTelemetryOptions (標準オプション パターン) を使用して構成します。
値は、デリゲートを使用するか、バインド構成 ( appsettings.json など) で指定できます。
オプション インスタンスはハンドラー パイプラインごとに 1 回解決されるため、変更は新しいクライアント/ハンドラーに適用されます。
// Configure with delegate
builder.Services.AddHttpClientLatencyTelemetry(options =>
{
options.EnableDetailedLatencyBreakdown = true;
});
// Or configure from configuration
builder.Services.AddHttpClientLatencyTelemetry(
builder.Configuration.GetSection("HttpClientTelemetry"));
構成オプション
HttpClientLatencyTelemetryOptions クラスには、次の設定が用意されています。
| Option | タイプ | 既定値 | Description | 無効にするタイミング |
|---|---|---|---|---|
| 詳細なレイテンシーブレークダウンを有効にする (EnableDetailedLatencyBreakdown) | ブール値 | true |
各 HttpClient 要求 (接続の確立、送信されたヘッダー、最初のバイト、完了など) の詳細なフェーズ タイミングを有効にして、合計待機時間の内訳を生成します。 追加される CPU/時間測定コストはごくわずかで、ネットワークオーバーヘッドは発生しません。 |
falseに設定するのは、最小限のオーバーヘッドが必要で、合計時間だけで十分な、非常に高スループットなシナリオの場合のみです。 |
収集されたテレメトリ データ
HTTP クライアント待機時間テレメトリを有効にすると、フェーズ タイムスタンプ、選択したメジャー (サポートされている場合)、およびパフォーマンス分析に使用されるプロトコル属性がキャプチャされます。
タイミング チェックポイント
タイムスタンプは、HTTP 要求ライフサイクルの主要なステージについて記録されます。
| Phase | 開始イベント | 終了イベント | 注記 |
|---|---|---|---|
| DNS の解決 | Http.NameResolutionStart | Http.NameResolutionEnd | ホスト名の参照 (キャッシュおよびスキップされる可能性があります)。 |
| ソケット接続 | Http.SocketConnectStart | Http.SocketConnectEnd | CP (ハンドラーによって結合された場合は TLS ハンドシェイク)。 |
| 接続の確立 | Http.ConnectionEstablished | ハンドシェイク後に使用可能な接続をマークします。 | |
| 要求ヘッダー | Http.RequestHeadersStart(リクエストヘッダーの開始) | Http.要求ヘッダー終了(Http.RequestHeadersEnd) | ワイヤ/バッファーへの要求ヘッダーの書き込み。 |
| コンテンツを要求する | Http.RequestContentStart | Http.RequestContentEnd | 要求本文のストリーミングまたはバッファリング。 |
| 応答ヘッダー | Http.ResponseHeadersStart | Http.ResponseHeadersEnd | ヘッダーの解析が完了するまでの最初のバイト。 |
| 応答コンテンツ | Http.ResponseContentStart | Http.ResponseContentEnd | 完全な応答本文を読み取ります (完了または破棄)。 |
対策 (プラットフォーム依存)
未加工フェーズのチェックポイントでは不可能な待機時間に寄与する要因(GC の一時停止の重複、接続のチャーン、その他の累積カウントや期間)を定量化します。 これらは、 AddHttpClientLatencyTelemetry()を呼び出したときに作成されたメモリ内待機時間コンテキストで収集されます。 何も自動的に出力されません。コンテキストは、要求が完了するまでチェックポイント、メジャー、タグを蓄積するだけです。
AddExtendedHttpClientLogging()を使用して HTTP クライアント ログ エンリッチメントを有効にした場合、完了したコンテキストは、LatencyInfoという名前の 1 つの構造化ログ フィールドにフラット化されます (バージョン マーカー、使用可能な場合はサーバー名、タグ、チェックポイント、メジャー名/値シーケンス)。
そのログ フィールドは、唯一の組み込みの出力成果物です。独自のエクスポーターを追加しない限り、メトリックまたはトレースは生成されません。 それらをメトリクスとして表示するには、要求パイプラインが返された後にコンテキストを読み込み、たとえば、GC の一時停止の重複をヒストグラムに記録し、接続開始をカウンターに記録します。必要に応じて、プロトコルバージョン別にディメンションを追加することもできます。
| 名前 | Description |
|---|---|
| Http.GCPauseTime | 要求と重複する GC 一時停止期間の合計。 |
| HTTP. 接続開始 | 新しい基になる接続 (プールされた再利用ではない) が作成されたときに生成されます。 |
タグ
タグを使用して各要求に安定したカテゴリ ディメンションをアタッチし、生データを再処理せずにメトリックとログをセグメント化、フィルター処理、集計できるようにします。 これらは待機時間コンテキストでキャプチャされる (タイミングではなく) カーディナリティの低い分類ラベルであり、HTTP クライアント ログ エンリッチメントが有効な場合は、単一の LatencyInfo ログ フィールドにシリアル化されます。 (すべてのクライアントまたはクライアントごとに) ログ拡張機能と待機時間テレメトリを追加することで、アプリケーションの起動時にエンリッチメントを有効にします。次に例を示します。
var builder = Host.CreateApplicationBuilder(args);
builder.Services.AddHttpClientLatencyTelemetry(); // enables latency context + measures/tags
builder.Services.AddExtendedHttpClientLogging();
var app = builder.Build();
その後、構造化ログ パイプラインを介してログに記録された送信要求には、フラット化されたタグ、チェックポイント、メジャーを含む LatencyInfo プロパティが含まれます。 タグのメトリックまたはトレースは自動的に出力されません。ログの外部で必要な場合は、それらを自分でエクスポートします (たとえば、タグ値をメトリック ディメンションまたは Activity タグに変換します)。
| タグ | Description |
|---|---|
| Http.Version | HTTP プロトコルのバージョンがネゴシエート/使用されます (例: 1.1、2、3)。 |
使用例
これらのコンポーネントにより、HTTP クライアント要求処理の待機時間の追跡とレポートが可能になります。
サービスは、次の方法で登録できます。
public static IServiceCollection AddHttpClientLatencyTelemetry(
this IServiceCollection services);
public static IServiceCollection AddHttpClientLatencyTelemetry(
this IServiceCollection services,
IConfigurationSection section);
public static IServiceCollection AddHttpClientLatencyTelemetry(
this IServiceCollection services,
Action<HttpClientLatencyTelemetryOptions> configure);
例えば次が挙げられます。
var builder = Host.CreateApplicationBuilder(args);
// Register IHttpClientFactory:
builder.Services.AddHttpClient();
// Register redaction services:
builder.Services.AddRedaction();
// Register latency context services:
builder.Services.AddLatencyContext();
// Register HttpClient logging enrichment & redaction services:
builder.Services.AddExtendedHttpClientLogging();
// Register HttpClient latency telemetry services:
builder.Services.AddHttpClientLatencyTelemetry();
var host = builder.Build();
プラットフォームに関する考慮事項
HTTP クライアント待機時間テレメトリは、サポートされているすべてのターゲット (.NET 9、.NET 8、.NET Standard 2.0、および .NET Framework 4.6.2) で実行されます。 コア タイミング チェックポイントは常に収集されます。 GC 一時停止メトリック (Http.GCPauseTime) は、.NET 8 または .NET 9 で実行されている場合にのみ生成されます。 この実装では、実行時にプラットフォームの機能が検出され、追加の構成なしでサポートされる機能が有効になります。
.NET