Kestrel 中的診斷
注意
這不是這篇文章的最新版本。 如需目前的版本,請參閱 本文的 .NET 9 版本。
警告
不再支援此版本的 ASP.NET Core。 如需詳細資訊,請參閱 .NET 和 .NET Core 支持原則。 如需目前的版本,請參閱 本文的 .NET 9 版本。
本文提供從 Kestrel 收集診斷資料的指引,以協助針對問題進行疑難排解。 涵蓋的主題包括:
- 記錄:寫入至 .NET Core 記錄的結構化記錄。 應用程式架構會使用 ILogger 來寫入記錄,而使用者則會用來在應用程式中自行記錄。
- 計量:時間間隔內資料量值的表示法,例如每秒的要求數。 計量是透過
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 的端點
度量
計量是時間間隔內資料量值的表示法,例如每秒的要求數。 計量資料可以讓您從高層次觀察應用程式的狀態。 Kestrel 計量是透過 EventCounter
所發出。
注意
connections-per-second
和 tls-handshakes-per-second
計數器的命名不正確。 計數器:
- 不一定總是包含每秒鐘的新連線數或 TLS 交握數
- 會根據事件取用者的要求,透過
filterPayload
到KestrelEventSource
中的EventCounterIntervalSec
引數,顯示上一個更新間隔中的新連線數或 TLS 交握數。
我們建議這些計數器的取用者根據一秒鐘的 DisplayRateTimeScale
來調整計量值。
名稱 | 顯示名稱 | 描述 |
---|---|---|
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 |
連線佇列長度 | 排入執行緒集區的連線總數。 在處於穩定狀態的狀況良好系統中,此數字應始終趨近零 |
request-queue-length |
要求佇列長度 | 排入執行緒集區的要求總數。 在處於穩定狀態的狀況良好系統中,此數字應始終趨近零。 此計量與 IIS/Http.Sys 要求佇列不同,無法進行比較 |
current-upgraded-requests |
目前的升級要求數 (WebSocket 數) | 作用中 WebSocket 要求的數目 |
DiagnosticSource
Kestrel 會針對伺服器層拒絕的 HTTP 要求 (例如格式錯誤的要求和通訊協定違規) 發出 DiagnosticSource
事件。 因此,這些要求永遠不會進入 ASP.NET Core 的裝載層。
Kestrel 使用 Microsoft.AspNetCore.Server.Kestrel.BadRequest
事件名稱和 IFeatureCollection
作為物件承載來發出這些事件。 藉由存取功能集合上的 IBadRequestExceptionFeature
,即可擷取基礎例外狀況。
解決這些事件的過程分為兩個步驟。 必須建立 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 處理序時,並不會強制執行某些逾時和速率限制。 如需詳細資訊,請參閱附加偵錯工具時的行為。