Kestrel での診断
Note
これは、この記事の最新バージョンではありません。 現在のリリースについては、この記事の .NET 8 バージョンを参照してください。
警告
このバージョンの ASP.NET Core はサポート対象から除外されました。 詳細については、「.NET および .NET Core サポート ポリシー」を参照してください。 現在のリリースについては、この記事の .NET 8 バージョンを参照してください。
重要
この情報はリリース前の製品に関する事項であり、正式版がリリースされるまでに大幅に変更される可能性があります。 Microsoft はここに示されている情報について、明示か黙示かを問わず、一切保証しません。
現在のリリースについては、この記事の .NET 8 バージョンを参照してください。
Sourabh Shirhatti による投稿
この記事では、問題のトラブルシューティングに役立つ診断情報を Kestrel から収集するためのガイダンスを提供します。 取り上げるトピックは次のとおりです。
- ログ: .NET Core ログに書き込まれる構造化ログ。 ILogger は、ログを書き込むためにアプリケーション フレームワークによって使用され、アプリで独自のログ記録を行うためユーザーによって使用されます。
- メトリック: 1 秒あたりの要求数など、一定期間にわたるデータ測定値を表します。 メトリックは
EventCounter
を使用して出力され、dotnet-counters コマンド ライン ツールまたは Application Insights を使用して観察できます。 - DiagnosticSource:
DiagnosticSource
は、プロセス内での使用に関する、リッチ データ ペイロードを含む運用時のログ記録を行うためのメカニズムです。 データがプロセスから移動することが前提であり、シリアル化可能なデータを必要とするログとは異なり、DiagnosticSource
は複雑なデータに適しています。
ログの記録
ASP.NET Core のほとんどのコンポーネントと同様に、Kestrel では Microsoft.Extensions.Logging
を使用してログ情報を出力します。 Kestrel では、複数のカテゴリを使用することにより、リッスンするログを選択できます。
ログ記録のカテゴリ名 | ログ記録のイベント |
---|---|
Microsoft.AspNetCore.Server.Kestrel |
ApplicationError 、ConnectionHeadResponseBodyWrite 、ApplicationNeverCompleted 、RequestBodyStart 、RequestBodyDone 、RequestBodyNotEntirelyRead 、RequestBodyDrainTimedOut 、ResponseMinimumDataRateNotSatisfied 、InvalidResponseHeaderRemoved 、HeartbeatSlow |
Microsoft.AspNetCore.Server.Kestrel.BadRequests |
ConnectionBadRequest 、RequestProcessingError 、RequestBodyMinimumDataRateNotSatisfied |
Microsoft.AspNetCore.Server.Kestrel.Connections |
ConnectionAccepted , ConnectionStart , ConnectionStop , ConnectionPause , ConnectionResume , ConnectionKeepAlive , ConnectionRejected , ConnectionDisconnect , NotAllConnectionsClosedGracefully , NotAllConnectionsAborted , ApplicationAbortedConnection |
Microsoft.AspNetCore.Server.Kestrel.Http2 |
Http2ConnectionError 、Http2ConnectionClosing 、Http2ConnectionClosed 、Http2StreamError 、Http2StreamResetAbort 、HPackDecodingError 、HPackEncodingError 、Http2FrameReceived 、Http2FrameSending 、Http2MaxConcurrentStreamsReached |
Microsoft.AspNetCore.Server.Kestrel.Http3 |
Http3ConnectionError , Http3ConnectionClosing , Http3ConnectionClosed , Http3StreamAbort , Http3FrameReceived , Http3FrameSending |
接続のログ記録
Kestrel では、バイトレベルの通信用に Debug
レベルのログを出力する機能もサポートされます。これはエンドポイントごとに有効にできます。 接続のログ記録を有効にするには、Kestrel のエンドポイントの構成に関する記事を参照してください
メトリック
メトリックは、1 秒あたりの要求数など、一定期間にわたるデータ測定値を表します。 メトリック データを使用すると、アプリの状態を高レベルで監視できます。 Kestrel メトリックは EventCounter
を使用して出力されます。
Note
connections-per-second
カウンターと tls-handshakes-per-second
カウンターの名前は正しく指定されていません。 これらのカウンターには以下の条件が適用されます。
- 1 秒あたりの新しい接続または TLS ハンドシェイクの数が必ずしも含まれているわけでは "ありません"。
KestrelEventSource
に対してfilterPayload
のEventCounterIntervalSec
引数を使用してイベントのコンシューマーとして要求された、前回の更新期間における新しい接続または TLS ハンドシェイクの数が表示されます。
これらのカウンターのコンシューマーでは、1 秒の DisplayRateTimeScale
に基づいてメトリック値を拡大縮小することをお勧めします。
Name | 表示名 | 説明 |
---|---|---|
connections-per-second |
接続速度 | 更新間隔ごとの新しい着信接続の数 |
total-connections |
合計接続数 | 接続の総数 |
tls-handshakes-per-second |
TLS ハンドシェイク速度 | 更新間隔ごとの新しい TLS ハンドシェイクの数 |
total-tls-handshakes |
合計 TLS ハンドシェイク数 | TLS ハンドシェイクの総数 |
current-tls-handshakes |
現在の TLS ハンドシェイク数 | プロセス内の TLS ハンドシェイクの数 |
failed-tls-handshakes |
失敗した TLS ハンドシェイク数 | 失敗した TLS ハンドシェイクの合計数 |
current-connections |
現在の接続数 | 接続の総数 (アイドル状態の接続を含む) |
connection-queue-length |
接続キューの長さ | スレッド プールのキューに登録された接続の総数。 状態が安定した正常なシステムでは、これが常に 0 に近い数値であることが必要です。 |
request-queue-length |
要求キューの長さ | スレッド プールのキューに登録された要求の総数。 状態が安定した正常なシステムでは、これが常に 0 に近い数値であることが必要です。 このメトリックは IIS/Http.Sys 要求キューとは異なり、比較できません。 |
current-upgraded-requests |
現在アップグレードされている要求数 (WebSocket) | アクティブな WebSocket の要求の数 |
DiagnosticSource
Kestrel では、形式に誤りがある要求やプロトコル違反など、サーバー レイヤーで拒否された HTTP 要求に対して DiagnosticSource
イベントを出力します。 そのため、これらの要求が ASP.NET Core のホスティング レイヤーに到達することはありません。
Kestrel では、Microsoft.AspNetCore.Server.Kestrel.BadRequest
イベントの名前と IFeatureCollection
をオブジェクトのペイロードとして使用して、これらのイベントを出力します。 基になる例外は、機能コレクションの IBadRequestExceptionFeature
にアクセスすることで取得できます。
これらのイベントの解決は、2 つのステップから成るプロセスです。 DiagnosticListener
のオブザーバーを作成する必要があります。
class BadRequestEventListener : IObserver<KeyValuePair<string, object>>, IDisposable
{
private readonly IDisposable _subscription;
private readonly Action<IBadRequestExceptionFeature> _callback;
public BadRequestEventListener(DiagnosticListener diagnosticListener, Action<IBadRequestExceptionFeature> callback)
{
_subscription = diagnosticListener.Subscribe(this!, IsEnabled);
_callback = callback;
}
private static readonly Predicate<string> IsEnabled = (provider) => provider switch
{
"Microsoft.AspNetCore.Server.Kestrel.BadRequest" => true,
_ => false
};
public void OnNext(KeyValuePair<string, object> pair)
{
if (pair.Value is IFeatureCollection featureCollection)
{
var badRequestFeature = featureCollection.Get<IBadRequestExceptionFeature>();
if (badRequestFeature is not null)
{
_callback(badRequestFeature);
}
}
}
public void OnError(Exception error) { }
public void OnCompleted() { }
public virtual void Dispose() => _subscription.Dispose();
}
オブザーバーを使用して ASP.NET Core DiagnosticListener
をサブスクライブします。 次の例では、基になる例外をログに記録するコールバックを作成します。
var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();
var diagnosticSource = app.Services.GetRequiredService<DiagnosticListener>();
using var badRequestListener = new BadRequestEventListener(diagnosticSource, (badRequestExceptionFeature) =>
{
app.Logger.LogError(badRequestExceptionFeature.Error, "Bad request received");
});
app.MapGet("/", () => "Hello world");
app.Run();
デバッガーがアタッチされているときの動作
デバッガーが Kestrel プロセスにアタッチされているときは、適用されないタイムアウトとレート制限があります。 詳しくは、「デバッガーがアタッチされているときの動作」をご覧ください。
ASP.NET Core