Logging và Diagnostics trong ASP.NET Core SignalR
Tác giả: Andrew Stanton-Nurse
Bài viết này cung cấp hướng dẫn thu thập diagnostics (chẩn đoán) từ ứng dụng ASP.NET Core SignalR của bạn để giúp khắc phục sự cố.
Logging phía server
Cảnh báo: Log phía server có thể chứa thông tin nhạy cảm từ ứng dụng của bạn. Không bao giờ đăng log thô từ ứng dụng production lên các diễn đàn công khai như GitHub.
Vì SignalR là một phần của ASP.NET Core, nó sử dụng hệ thống logging của ASP.NET Core. Trong cấu hình mặc định, SignalR ghi log tối thiểu thông tin, nhưng mức logging có thể được cấu hình. Xem tài liệu về ASP.NET Core logging để biết chi tiết về cách cấu hình ASP.NET Core logging.
SignalR sử dụng hai danh mục logger:
Microsoft.AspNetCore.SignalR: Cho các log liên quan đến Hub Protocols, kích hoạt Hubs, gọi methods và các hoạt động liên quan đến Hub khác.Microsoft.AspNetCore.Http.Connections: Cho các log liên quan đến transports, chẳng hạn như WebSockets, Long Polling, Server-Sent Events và cơ sở hạ tầng SignalR cấp thấp.
Để bật các log chi tiết từ SignalR, hãy cấu hình cả hai prefix trên thành mức Debug trong file appsettings.json bằng cách thêm các mục sau vào phần LogLevel trong Logging:
{
"Logging": {
"LogLevel": {
"Default": "Debug",
"System": "Information",
"Microsoft": "Information",
"Microsoft.AspNetCore.SignalR": "Debug",
"Microsoft.AspNetCore.Http.Connections": "Debug"
}
}
}Các mức logging cho các danh mục logger SignalR cũng có thể được cấu hình trong code trong phương thức 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>();Nếu bạn không sử dụng cấu hình dựa trên JSON, hãy đặt các giá trị cấu hình sau trong hệ thống cấu hình của bạn:
Logging:LogLevel:Microsoft.AspNetCore.SignalR=DebugLogging:LogLevel:Microsoft.AspNetCore.Http.Connections=Debug
Kiểm tra tài liệu cho hệ thống cấu hình của bạn để xác định cách chỉ định các giá trị cấu hình lồng nhau. Ví dụ, khi sử dụng environment variables, hai ký tự _ được sử dụng thay vì : (ví dụ: Logging__LogLevel__Microsoft.AspNetCore.SignalR).
Chúng tôi khuyến nghị sử dụng mức Debug khi thu thập diagnostics chi tiết hơn cho ứng dụng của bạn. Mức Trace tạo ra diagnostics cấp thấp và hiếm khi cần thiết để chẩn đoán các vấn đề trong ứng dụng.
Truy cập log phía server
Cách truy cập log phía server phụ thuộc vào môi trường mà ứng dụng đang chạy.
Là console app bên ngoài IIS
Nếu bạn đang chạy trong console app, Console logger nên được bật theo mặc định. Log SignalR sẽ xuất hiện trong console.
Trong IIS Express từ Visual Studio
Visual Studio hiển thị đầu ra log trong cửa sổ Output. Chọn tùy chọn dropdown ASP.NET Core Web Server.
Azure App Service
Bật tùy chọn Application Logging (Filesystem) trong phần Diagnostics logs của cổng Azure App Service và cấu hình Level thành Verbose. Log sẽ có sẵn từ dịch vụ Log streaming và trong log trên hệ thống file của App Service. Để biết thêm thông tin, xem Azure log streaming.
Các môi trường khác
Để biết thêm thông tin về việc cấu hình các logging provider phù hợp cho các môi trường triển khai khác nhau, chẳng hạn như Docker, Kubernetes hoặc Windows Service, xem Logging in .NET and ASP.NET Core.
Logging JavaScript client
Cảnh báo: Log phía client có thể chứa thông tin nhạy cảm từ ứng dụng của bạn. Không bao giờ đăng log thô từ ứng dụng production lên các diễn đàn công khai như GitHub.
Khi sử dụng JavaScript client, bạn có thể cấu hình các tùy chọn logging bằng phương thức configureLogging trên HubConnectionBuilder:
let connection = new signalR.HubConnectionBuilder()
.withUrl("/my/hub/url")
.configureLogging(signalR.LogLevel.Debug)
.build();Tắt framework logging bằng cách chỉ định signalR.LogLevel.None trong phương thức configureLogging. Lưu ý rằng một số logging được phát ra trực tiếp bởi trình duyệt và không thể tắt thông qua việc đặt mức log.
Bảng sau đây hiển thị các mức log có sẵn cho JavaScript client. Đặt mức log thành một trong các giá trị này sẽ bật logging ở mức đó và tất cả các mức trên nó trong bảng.
| Mức | Mô tả |
|---|---|
None | Không có message nào được ghi log. |
Critical | Các message chỉ ra sự cố nghiêm trọng trong toàn bộ ứng dụng. |
Error | Các message chỉ ra sự cố trong thao tác hiện tại. |
Warning | Các message chỉ ra vấn đề không nghiêm trọng. |
Information | Các message thông tin. |
Debug | Các message chẩn đoán hữu ích để debug. |
Trace | Các message chẩn đoán rất chi tiết được thiết kế để chẩn đoán các vấn đề cụ thể. |
Sau khi bạn đã cấu hình mức độ chi tiết, các log sẽ được ghi vào Browser Console (hoặc Standard Output trong ứng dụng NodeJS).
Nếu bạn muốn gửi log đến một hệ thống logging tùy chỉnh, bạn có thể cung cấp một đối tượng JavaScript triển khai interface ILogger. Phương thức duy nhất cần được triển khai là log, nhận mức của sự kiện và message liên quan đến sự kiện. Ví dụ:
import { ILogger, LogLevel, HubConnectionBuilder } from "@microsoft/signalr";
export class MyLogger implements ILogger {
log(logLevel: LogLevel, message: string) {
// Sử dụng `message` và `logLevel` để ghi log message vào hệ thống của bạn
}
}
// sau đó, khi cấu hình kết nối của bạn...
let connection = new HubConnectionBuilder()
.withUrl("/my/hub/url")
.configureLogging(new MyLogger())
.build();Logging .NET client
Cảnh báo: Log phía client có thể chứa thông tin nhạy cảm từ ứng dụng của bạn. Không bao giờ đăng log thô từ ứng dụng production lên các diễn đàn công khai như GitHub.
Để nhận log từ .NET client, bạn có thể sử dụng phương thức ConfigureLogging trên HubConnectionBuilder. Phương thức này hoạt động theo cùng cách như phương thức ConfigureLogging trên WebHostBuilder và HostBuilder. Bạn có thể cấu hình các logging provider giống như bạn sử dụng trong ASP.NET Core. Tuy nhiên, bạn phải cài đặt và bật thủ công các NuGet package cho các logging provider riêng lẻ.
Logging Console
Để bật Console logging, thêm package Microsoft.Extensions.Logging.Console. Sau đó, sử dụng phương thức AddConsole để cấu hình console logger:
var connection = new HubConnectionBuilder()
.WithUrl("https://example.com/my/hub/url")
.ConfigureLogging(logging =>
{
// Ghi log vào Console
logging.AddConsole();
// Điều này sẽ đặt TẤT CẢ logging thành mức Debug
logging.SetMinimumLevel(LogLevel.Debug);
})
.Build();Logging cửa sổ Debug output
Các log có thể được cấu hình để đi vào cửa sổ Output trong Visual Studio. Cài đặt package Microsoft.Extensions.Logging.Debug và sử dụng phương thức AddDebug:
var connection = new HubConnectionBuilder()
.WithUrl("https://example.com/my/hub/url")
.ConfigureLogging(logging =>
{
// Ghi log vào Output Window
logging.AddDebug();
// Điều này sẽ đặt TẤT CẢ logging thành mức Debug
logging.SetMinimumLevel(LogLevel.Debug)
})
.Build();Các logging provider khác
SignalR hỗ trợ các logging provider khác như Serilog, Seq, NLog hoặc bất kỳ hệ thống logging nào tích hợp với Microsoft.Extensions.Logging. Nếu hệ thống logging của bạn cung cấp ILoggerProvider, bạn có thể đăng ký nó với AddProvider:
var connection = new HubConnectionBuilder()
.WithUrl("https://example.com/my/hub/url")
.ConfigureLogging(logging =>
{
// Ghi log vào provider tùy chỉnh của bạn
logging.AddProvider(new MyCustomLoggingProvider());
// Điều này sẽ đặt TẤT CẢ logging thành mức Debug
logging.SetMinimumLevel(LogLevel.Debug)
})
.Build();Kiểm soát mức độ chi tiết
Khi logging từ các nơi khác trong ứng dụng, việc thay đổi mức mặc định thành Debug có thể quá chi tiết. Filter có thể được sử dụng để cấu hình mức logging cho SignalR logs. Điều này có thể được thực hiện trong code, theo cách tương tự như trên server:
var connection = new HubConnectionBuilder()
.WithUrl("https://example.com/my/hub/url")
.ConfigureLogging(logging =>
{
// Đăng ký các provider của bạn
// Đặt mức log mặc định thành Information, nhưng thành Debug cho các logger liên quan đến SignalR.
logging.SetMinimumLevel(LogLevel.Information);
logging.AddFilter("Microsoft.AspNetCore.SignalR", LogLevel.Debug);
logging.AddFilter("Microsoft.AspNetCore.Http.Connections", LogLevel.Debug);
})
.Build();Tracing trong SignalR
Hub server của SignalR và SignalR client cung cấp thông tin về các kết nối và message SignalR bằng cách sử dụng DiagnosticSource và Activity. SignalR có ActivitySource cho cả hub server và client, có sẵn bắt đầu từ .NET 9.
ActivitySource là một component được sử dụng trong distributed tracing để tạo và quản lý các activities (hoặc spans) đại diện cho các thao tác trong ứng dụng của bạn. Các activities này có thể được sử dụng để:
- Theo dõi luồng của các request và thao tác qua các component và service khác nhau.
- Cung cấp thông tin quý giá về hiệu suất và hành vi của ứng dụng của bạn.
.NET SignalR server ActivitySource
SignalR ActivitySource có tên Microsoft.AspNetCore.SignalR.Server phát ra các sự kiện cho các lệnh gọi phương thức hub:
- Mỗi phương thức là activity riêng của nó, vì vậy bất kỳ thứ gì phát ra activity trong lệnh gọi phương thức hub đều nằm dưới hub method activity.
- Các hub method activities không có parent. Điều này có nghĩa là chúng không được gói trong kết nối SignalR chạy dài.
.NET SignalR client ActivitySource
SignalR ActivitySource có tên Microsoft.AspNetCore.SignalR.Client phát ra các sự kiện cho SignalR client:
- Các hub invocations (lời gọi hub) tạo ra client span. Các SignalR client khác, chẳng hạn như JavaScript client, không hỗ trợ tracing. Tính năng này sẽ được thêm vào nhiều client hơn trong các phiên bản tương lai.
- Các hub invocations trên client và server hỗ trợ context propagation. Việc truyền trace context cho phép distributed tracing thực sự. Bây giờ có thể thấy các invocations chảy từ client đến server và ngược lại.
Network traces
Cảnh báo: Network trace chứa đầy đủ nội dung của mỗi message được gửi bởi ứng dụng của bạn. Không bao giờ đăng raw network traces từ ứng dụng production lên các diễn đàn công khai như GitHub.
Nếu bạn gặp sự cố, network trace đôi khi có thể cung cấp thông tin có giá trị. Điều này đặc biệt hữu ích khi đăng sự cố trên issue tracker của chúng tôi.
Thu thập network trace với Fiddler (tùy chọn được ưa thích)
Phương pháp này hoạt động cho tất cả các ứng dụng.
Fiddler là công cụ mạnh mẽ để thu thập HTTP traces. Cài đặt từ telerik.com/fiddler, khởi động nó, sau đó chạy ứng dụng và tái hiện sự cố. Fiddler có sẵn cho Windows và có các phiên bản beta cho macOS và Linux.
Nếu bạn kết nối bằng HTTPS, có một số bước bổ sung để đảm bảo Fiddler có thể giải mã lưu lượng HTTPS. Để biết thêm thông tin, xem tài liệu Fiddler.
Sau khi thu thập trace, xuất nó bằng cách chọn File > Save > All Sessions từ thanh menu.
Thu thập network trace với tcpdump (chỉ macOS và Linux)
Phương pháp này hoạt động cho tất cả các ứng dụng.
Raw TCP traces có thể được thu thập bằng tcpdump bằng cách chạy lệnh sau từ command shell. Bạn có thể cần phải là root hoặc thêm prefix sudo vào lệnh nếu bạn gặp lỗi quyền truy cập:
tcpdump -i [interface] -w trace.pcap
Thay [interface] bằng giao diện mạng bạn muốn capture. Thường đây là thứ gì đó như /dev/eth0 (cho giao diện Ethernet tiêu chuẩn) hoặc /dev/lo0 (cho lưu lượng localhost). Để biết thêm thông tin, xem trang manual tcpdump trên hệ thống host của bạn.
Thu thập network trace trong trình duyệt
Phương pháp này chỉ hoạt động cho các ứng dụng dựa trên trình duyệt.
Hầu hết các console công cụ dành cho nhà phát triển của trình duyệt đều có tab "Network" cho phép hoạt động mạng được capture giữa trình duyệt và server. Tuy nhiên, những traces này không bao gồm các message WebSocket và Server-Sent Event. Khi sử dụng các transports đó, sử dụng công cụ như Fiddler hoặc TcpDump là cách tiếp cận tốt hơn.
Microsoft Edge và Internet Explorer
- Mở Dev Tools bằng cách nhấn F12
- Chọn tab Network
- Làm mới trang (nếu cần) và tái hiện sự cố
- Chọn biểu tượng Save trong thanh công cụ để xuất trace dưới dạng file "HAR"
Google Chrome
- Mở Dev Tools bằng cách nhấn F12
- Chọn tab Network
- Làm mới trang (nếu cần) và tái hiện sự cố
- Click chuột phải vào bất kỳ nơi nào trong danh sách requests và chọn "Save as HAR with content"
Mozilla Firefox
- Mở Dev Tools bằng cách nhấn F12
- Chọn tab Network
- Làm mới trang (nếu cần) và tái hiện sự cố
- Click chuột phải vào bất kỳ nơi nào trong danh sách requests và chọn "Save All As HAR"
Đính kèm file diagnostics vào GitHub issues
File diagnostics có thể được đính kèm vào GitHub issues bằng cách đổi tên chúng để có phần mở rộng .txt và sau đó kéo và thả chúng lên issue.
Lưu ý: Vui lòng không dán nội dung của file log hoặc network traces vào GitHub issue. Các log và trace này có thể lớn và GitHub thường cắt ngắn chúng.
Metrics
Metrics (số liệu) là biểu diễn của các số liệu dữ liệu theo các khoảng thời gian. Ví dụ, requests per second (request mỗi giây). Dữ liệu metrics cho phép quan sát trạng thái của ứng dụng ở mức độ cao. .NET gRPC metrics được phát ra bằng cách sử dụng EventCounter.
SignalR server metrics
SignalR server metrics được báo cáo trên nguồn sự kiện Microsoft.AspNetCore.Http.Connections.
| Tên | Mô tả |
|---|---|
connections-started | Tổng số kết nối đã bắt đầu |
connections-stopped | Tổng số kết nối đã dừng |
connections-timed-out | Tổng số kết nối đã hết hạn |
current-connections | Các kết nối hiện tại |
connections-duration | Thời gian kết nối trung bình |
Quan sát metrics
dotnet-counters là công cụ giám sát hiệu suất để theo dõi tình trạng ad-hoc và điều tra hiệu suất cấp đầu tiên. Giám sát ứng dụng .NET với Microsoft.AspNetCore.Http.Connections làm tên provider. Ví dụ:
> dotnet-counters monitor --process-id 37016 --counters 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