ASP.NET Core SignalR 中的記錄和診斷

作者:Andrew Stanton-Nurse

本文提供從 ASP.NET Core SignalR 應用程式收集診斷的指引,以協助針對問題進行疑難排解。

伺服器端記錄

警告

伺服器端記錄可能包含來自您應用程式的敏感性資訊。 切勿將原始記錄從實際執行應用程式張貼至 GitHub 等公共論壇。

由於 SignalR 是 ASP.NET Core 的一部分,因此其會使用 ASP.NET Core 記錄系統。 在預設組態中,SignalR 會記錄很少的資訊,但您可以設定此設錄。 如需設定 ASP.NET Core 記錄的詳細資訊,請參閱有關 ASP.NET Core 記錄的文件。

SignalR 使用兩個記錄器類別:

  • Microsoft.AspNetCore.SignalR:適用於與中樞通訊協定、啟動中樞、叫用方法,以及其他中樞相關活動相關的記錄。
  • Microsoft.AspNetCore.Http.Connections:適用於與傳輸相關的記錄,例如 WebSocket、長期輪詢、伺服器傳送事件,以及低層級 SignalR 基礎結構。

若要從 SignalR 啟用詳細記錄,請將下列項目新增至 Logging 中的 LogLevel 子區段,以將上述兩個前置詞設定為 appsettings.json 檔案中的 Debug 層級:

{
    "Logging": {
        "LogLevel": {
            "Default": "Debug",
            "System": "Information",
            "Microsoft": "Information",
            "Microsoft.AspNetCore.SignalR": "Debug",
            "Microsoft.AspNetCore.Http.Connections": "Debug"
        }
    }
}

您也可以在 CreateWebHostBuilder 方法的程式碼中設定此項目:

public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
    WebHost.CreateDefaultBuilder(args)
        .ConfigureLogging(logging =>
        {
            logging.AddFilter("Microsoft.AspNetCore.SignalR", LogLevel.Debug);
            logging.AddFilter("Microsoft.AspNetCore.Http.Connections", LogLevel.Debug);
        })
        .UseStartup<Startup>();

如果您不是使用 JSON 型組態,請在組態系統中設定下列組態值:

  • Logging:LogLevel:Microsoft.AspNetCore.SignalR = Debug
  • Logging:LogLevel:Microsoft.AspNetCore.Http.Connections = Debug

請檢查組態系統的文件,以確定如何指定巢狀組態值。 例如,使用環境變數時,會使用兩個 _ 字元,而不是 : (例如, Logging__LogLevel__Microsoft.AspNetCore.SignalR)。

建議您在針對應用程式收集更詳細的診斷時使用 Debug 層級。 Trace 層級會產生非常低層級診斷,而且很少需要診斷您應用程式中的問題。

存取伺服器端記錄

存取伺服器端記錄的方式取決於您執行所在的環境。

作為 IIS 外部的主控台應用程式

如果您是在主控台應用程式中執行,則預設應該啟用主控台記錄器。 SignalR 記錄會出現在主控台中。

在來自 Visual Studio 的 IIS Express 內

Visual Studio 會在 [輸出] 視窗中顯示記錄輸出。 選取 [ASP.NET Core Web 伺服器] 下拉式清單選項。

Azure App Service

在 Azure App Service 入口網站的 [診斷記錄] 區段中啟用 [應用程式記錄 (檔案系統)] 選項,並將 [層級] 設定為 Verbose。 記錄應該可從 [記錄串流] 服務取得,以及在 App Service 檔案系統上的記錄中取得。 如需詳細資訊,請參閱 Azure 記錄串流

其他環境

如果應用程式部署至另一個環境 (例如,Docker、Kubernetes 或 Windows 服務),請參閱在 .NET Core 和 ASP.NET Core 中記錄,以取得如何設定適合環境的記錄提供者詳細資訊。

JavaScript 用戶端記錄

警告

用戶端記錄可能包含來自您應用程式的敏感性資訊。 切勿將原始記錄從實際執行應用程式張貼至 GitHub 等公共論壇。

使用 JavaScript 用戶端時,您可以使用 HubConnectionBuilder 上的 configureLogging 方法來設定記錄選項:

let connection = new signalR.HubConnectionBuilder()
    .withUrl("/my/hub/url")
    .configureLogging(signalR.LogLevel.Debug)
    .build();

若要停用架構記錄,請在 configureLogging 方法中指定 signalR.LogLevel.None。 請注意,某些記錄是由瀏覽器直接發出,而且無法透過設定記錄層級來停用。

下表顯示 JavaScript 用戶端可用的記錄層級。 將記錄層級設定為下列其中一個值,可在該層級和資料表中高於該層級的所有層級啟用記錄。

層級 描述
None 不會記錄任何訊息。
Critical 指出整個應用程式失敗的訊息。
Error 指出目前作業失敗的訊息。
Warning 指出非嚴重問題的訊息。
Information 告知性訊息。
Debug 適用於偵錯的診斷訊息。
Trace 專為診斷特定問題而設計的非常詳細診斷訊息。

一旦設定了詳細程度,記錄就會寫入瀏覽器主控台 (或 NodeJS 應用程式中的標準輸出)。

如果想要將記錄傳送至自訂記錄系統,您可以提供實作 ILogger 介面的 JavaScript 物件。 唯一需要實作的方法是 log,其會取得事件層級以及與事件相關聯的訊息。 例如:

import { ILogger, LogLevel, HubConnectionBuilder } from "@microsoft/signalr";

export class MyLogger implements ILogger {
    log(logLevel: LogLevel, message: string) {
        // Use `message` and `logLevel` to record the log message to your own system
    }
}

// later on, when configuring your connection...

let connection = new HubConnectionBuilder()
    .withUrl("/my/hub/url")
    .configureLogging(new MyLogger())
    .build();
import { ILogger, LogLevel, HubConnectionBuilder } from "@aspnet/signalr";

export class MyLogger implements ILogger {
    log(logLevel: LogLevel, message: string) {
        // Use `message` and `logLevel` to record the log message to your own system
    }
}

// later on, when configuring your connection...

let connection = new HubConnectionBuilder()
    .withUrl("/my/hub/url")
    .configureLogging(new MyLogger())
    .build();

.NET 用戶端記錄

警告

用戶端記錄可能包含來自您應用程式的敏感性資訊。 切勿將原始記錄從實際執行應用程式張貼至 GitHub 等公共論壇。

若要從 .NET 用戶端取得記錄,您可以在 HubConnectionBuilder 上使用 ConfigureLogging 方法。 其運作方式與 WebHostBuilderHostBuilder 上的 ConfigureLogging 方法相同。 您可以設定您在 ASP.NET Core 中使用的相同記錄提供者。 不過,您必須針對個別記錄提供者手動安裝並啟用 NuGet 套件。

若要將 .NET 用戶端記錄新增至 Blazor WebAssembly 應用程式,請參閱 ASP.NET Core Blazor 記錄

主控台記錄

為了啟用主控台記錄,請新增 Microsoft.Extensions.Logging.Console 套件。 然後,使用 AddConsole 方法來設定主控台記錄器:

var connection = new HubConnectionBuilder()
    .WithUrl("https://example.com/my/hub/url")
    .ConfigureLogging(logging =>
    {
        // Log to the Console
        logging.AddConsole();

        // This will set ALL logging to Debug level
        logging.SetMinimumLevel(LogLevel.Debug);
    })
    .Build();

偵錯輸出視窗記錄

您也可以將記錄設定為移至 Visual Studio 中的 [輸出] 視窗。 安裝 Microsoft.Extensions.Logging.Debug 套件,並使用 AddDebug 方法:

var connection = new HubConnectionBuilder()
    .WithUrl("https://example.com/my/hub/url")
    .ConfigureLogging(logging =>
    {
        // Log to the Output Window
        logging.AddDebug();

        // This will set ALL logging to Debug level
        logging.SetMinimumLevel(LogLevel.Debug)
    })
    .Build();

其他記錄提供者

SignalR 支援其他記錄提供者,例如 Serilog、Seq、NLog 或任何其他與 Microsoft.Extensions.Logging 整合的記錄系統。 如果您的記錄系統提供 ILoggerProvider,您可以使用 AddProvider 進行註冊:

var connection = new HubConnectionBuilder()
    .WithUrl("https://example.com/my/hub/url")
    .ConfigureLogging(logging =>
    {
        // Log to your custom provider
        logging.AddProvider(new MyCustomLoggingProvider());

        // This will set ALL logging to Debug level
        logging.SetMinimumLevel(LogLevel.Debug)
    })
    .Build();

控制詳細程度

如果您要從應用程式中的其他位置記錄,將預設層級變更為 Debug 可能太過詳細了。 您可以使用篩選條件來設定 SignalR 記錄的記錄層級。 這可以在程式碼中完成,這與伺服器上的方式大致相同:

var connection = new HubConnectionBuilder()
    .WithUrl("https://example.com/my/hub/url")
    .ConfigureLogging(logging =>
    {
        // Register your providers

        // Set the default log level to Information, but to Debug for SignalR-related loggers.
        logging.SetMinimumLevel(LogLevel.Information);
        logging.AddFilter("Microsoft.AspNetCore.SignalR", LogLevel.Debug);
        logging.AddFilter("Microsoft.AspNetCore.Http.Connections", LogLevel.Debug);
    })
    .Build();

網路追蹤

警告

網路追蹤包含應用程式所傳送的每則訊息完整內容。 切勿將原始網路追蹤從實際執行應用程式張貼至 GitHub 等公共論壇。

如果您遇到問題,網路追蹤有時會提供許多有用的資訊。 如果您即將在我們的問題追蹤器上提出問題,這會特別有用。

使用 Fiddler 收集網路追蹤 (慣用選項)

這個方法適用於所有檔案。

Fiddler 是收集 HTTP 追蹤的強大工具。 從 telerik.com/fiddler 安裝 Fiddler、將其啟動,然後執行您的應用程式並重現問題。 Fiddler 適用於 Windows,且對於 macOS 和 Linux,有搶鮮版 (Beta)。

如果您使用 HTTPS 進行連線,有一些額外的步驟,確保 Fiddler 可以解密 HTTPS 流量。 如需詳細資訊,請參閱 Fiddler 文件

一旦收集了追蹤,您就可以從功能表列中選擇 [檔案]>[儲存]>[所有工作階段] 來匯出追蹤。

Exporting all sessions from Fiddler

使用 tcpdump 收集網路追蹤 (僅限 macOS 和 Linux)

這個方法適用於所有檔案。

您可以從命令殼層執行下列命令,以使用 tcpdump 收集原始 TCP 追蹤。 如果收到權限錯誤,您可能需要成為 root 或在命令前面加上 sudo 前置詞:

tcpdump -i [interface] -w trace.pcap

[interface] 取代為您想要擷取的網路介面。 通常,這類似於 /dev/eth0 (代表標準乙太網路介面)或 /dev/lo0 (代表 localhost 流量)。 如需詳細資訊,請參閱主機系統上的 tcpdump 手冊頁。

在瀏覽器中收集網路追蹤

這個方法僅適用於瀏覽器型應用程式。

大部分的瀏覽器開發人員工具主控台都有 [網路] 索引標籤,可讓您擷取瀏覽器與伺服器之間的網路活動。 不過,這些追蹤不包含 WebSocket 和伺服器傳送事件訊息。 如果您要使用這些傳輸,則使用 Fiddler 或 TcpDump 之類的工具 (如下所述) 是更好的方法。

Microsoft Edge 和 Internet Explorer

(對於 Edge 和 Internet Explorer,指示都相同)

  1. 按 F12 開啟開發人員工具
  2. 按一下 [網路] 索引標籤
  3. 重新整理頁面 (如有需要) 並重現問題
  4. 按一下工具列中的 [儲存] 圖示,將追蹤匯出為 "HAR" 檔案:

The Save Icon on the Microsoft Edge Dev Tools Network Tab

Google Chrome

  1. 按 F12 開啟開發人員工具
  2. 按一下 [網路] 索引標籤
  3. 重新整理頁面 (如有需要) 並重現問題
  4. 以滑鼠右鍵按一下要求清單中的任意位置,然後選擇 [另存為含內容的 HAR]:

Mozilla Firefox

  1. 按 F12 開啟開發人員工具
  2. 按一下 [網路] 索引標籤
  3. 重新整理頁面 (如有需要) 並重現問題
  4. 以滑鼠右鍵按一下要求清單中的任何位置,然後選擇 [全部儲存為 HAR]

將診斷檔案附加至 GitHub 問題

您可以將診斷檔案附加至 GitHub 問題,方法是將這些檔案重新命名,讓其具有 .txt 副檔名,然後將其拖放至問題。

注意

請不要將記錄檔或網路追蹤的內容貼入 GitHub 問題中。 這些記錄和追蹤可能相當大,因此 GitHub 通常會將其截斷。

Dragging log files on to a GitHub issue

度量

計量是時間間隔內資料度量的表示法。 例如,每秒要求數。 計量資料允許在高層級觀察應用程式的狀態。 .NET gRPC 計量是使用 EventCounter 發出的。

SignalR 伺服器計量

SignalR 伺服器計量會在 Microsoft.AspNetCore.Http.Connections 事件來源上報告。

名稱 描述
connections-started 已啟動的連線總數
connections-stopped 已停止的連線總數
connections-timed-out 逾時連線總數
current-connections 目前連線數
connections-duration 平均連線持續時間

觀察計量

dotnet-counters 是效能監控工具,適用於特定的狀況監控和第一層級效能調查。 使用 Microsoft.AspNetCore.Http.Connections 作為提供者名稱來監視 .NET 應用程式。 例如:

> dotnet-counters monitor --process-id 37016 Microsoft.AspNetCore.Http.Connections

Press p to pause, r to resume, q to quit.
    Status: Running
[Microsoft.AspNetCore.Http.Connections]
    Average Connection Duration (ms)       16,040.56
    Current Connections                         1
    Total Connections Started                   8
    Total Connections Stopped                   7
    Total Connections Timed Out                 0

其他資源