Nguon: Microsoft Learn · .NET 8.0

Logging (ghi log) và diagnostics (chẩn đoán) trong gRPC trên .NET

Nguồn: Logging and diagnostics in gRPC on .NET

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 gRPC để giúp khắc phục sự cố. Các chủ đề được đề cập bao gồm:

Logging (ghi log)

gRPC services (dịch vụ) và gRPC client (máy khách) ghi log sử dụng .NET logging. Log là nơi tốt để bắt đầu khi debug (gỡ lỗi) hành vi không mong đợi trong ứng dụng service và client.

Logging trong gRPC services

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ì gRPC services được host trên ASP.NET Core, nó sử dụng hệ thống logging của ASP.NET Core. Trong cấu hình mặc định, gRPC ghi log tối thiểu thông tin, nhưng 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.

gRPC thêm log dưới category (danh mục) Grpc. Để bật log chi tiết từ gRPC, cấu hình tiền tố Grpc đến 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:

json
{
  "Logging": {
    "LogLevel": {
      "Default": "Debug",
      "System": "Information",
      "Microsoft": "Information",
      "Grpc": "Debug"
    }
  }
}

Logging cũng có thể được cấu hình trong Program.cs với ConfigureLogging:

csharp
public static IHostBuilder CreateHostBuilder(string[] args) =>
    Host.CreateDefaultBuilder(args)
        .ConfigureLogging(logging =>
        {
            logging.AddFilter("Grpc", LogLevel.Debug);
        })
        .ConfigureWebHostDefaults(webBuilder =>
        {
            webBuilder.UseStartup<Startup>();
        });

Khi không sử dụng cấu hình dựa trên JSON, đặt giá trị cấu hình sau trong hệ thống cấu hình:

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 (biến môi trường), hai ký tự _ được dùng thay cho : (ví dụ: Logging__LogLevel__Grpc).

Khuyến nghị sử dụng mức Debug khi thu thập diagnostics chi tiết cho ứng dụng. Mức Trace tạo ra diagnostics cấp thấp và hiếm khi cần thiết để chẩn đoán sự cố.

Ví dụ đầu ra logging

Đây là ví dụ đầu ra console ở mức Debug của một gRPC service:

console
info: Microsoft.AspNetCore.Hosting.Diagnostics[1]
      Request starting HTTP/2 POST https://localhost:5001/Greet.Greeter/SayHello application/grpc
info: Microsoft.AspNetCore.Routing.EndpointMiddleware[0]
      Executing endpoint 'gRPC - /Greet.Greeter/SayHello'
dbug: Grpc.AspNetCore.Server.ServerCallHandler[1]
      Reading message.
info: GrpcService.GreeterService[0]
      Hello World
dbug: Grpc.AspNetCore.Server.ServerCallHandler[6]
      Sending message.
info: Microsoft.AspNetCore.Routing.EndpointMiddleware[1]
      Executed endpoint 'gRPC - /Greet.Greeter/SayHello'
info: Microsoft.AspNetCore.Hosting.Diagnostics[2]
      Request finished in 1.4113ms 200 application/grpc

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 của ứng dụng.

Dạng console app

Nếu bạn đang chạy trong console app (ứng dụng dòng lệnh), Console logger sẽ được bật theo mặc định. Log gRPC sẽ xuất hiện trong console.

Các môi trường khác

Nếu ứng dụng được triển khai ở môi trường khác (ví dụ: Docker, Kubernetes hoặc Windows Service), xem Logging in .NET and ASP.NET Core để biết thêm thông tin về cách cấu hình logging providers phù hợp cho môi trường đó.

Logging trong gRPC client

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, đặt thuộc tính GrpcChannelOptions.LoggerFactory khi tạo channel của client. Khi gọi gRPC service từ ứng dụng ASP.NET Core, logger factory có thể được resolve từ dependency injection (DI - tiêm phụ thuộc):

csharp
[ApiController]
[Route("[controller]")]
public class GreetingController : ControllerBase
{
    private ILoggerFactory _loggerFactory;

    public GreetingController(ILoggerFactory loggerFactory)
    {
        _loggerFactory = loggerFactory;
    }

    [HttpGet]
    public async Task<ActionResult<string>> Get(string name)
    {
        var channel = GrpcChannel.ForAddress("https://localhost:5001",
            new GrpcChannelOptions { LoggerFactory = _loggerFactory });
        var client = new Greeter.GreeterClient(channel);

        var reply = await client.SayHelloAsync(new HelloRequest { Name = name });
        return Ok(reply.Message);
    }
}

Một cách khác để bật client logging là sử dụng gRPC client factory để tạo client. Một gRPC client được đăng ký với client factory và resolve từ DI sẽ tự động sử dụng logging đã cấu hình của ứng dụng.

Nếu ứng dụng không sử dụng DI, hãy tạo một instance ILoggerFactory mới với LoggerFactory.Create. Để truy cập phương thức này, thêm package Microsoft.Extensions.Logging vào ứng dụng.

csharp
var loggerFactory = LoggerFactory.Create(logging =>
{
    logging.AddConsole();
    logging.SetMinimumLevel(LogLevel.Debug);
});

var channel = GrpcChannel.ForAddress("https://localhost:5001",
    new GrpcChannelOptions { LoggerFactory = loggerFactory });

var client = Greeter.GreeterClient(channel);

Log scopes (phạm vi log) của gRPC client

gRPC client thêm một logging scope vào log được tạo trong một lần gọi gRPC. Scope có metadata liên quan đến lần gọi gRPC:

Ví dụ đầu ra logging

Đây là ví dụ đầu ra console ở mức Debug của một gRPC client:

console
dbug: Grpc.Net.Client.Internal.GrpcCall[1]
      Starting gRPC call. Method type: 'Unary', URI: 'https://localhost:5001/Greet.Greeter/SayHello'.
dbug: Grpc.Net.Client.Internal.GrpcCall[6]
      Sending message.
dbug: Grpc.Net.Client.Internal.GrpcCall[1]
      Reading message.
dbug: Grpc.Net.Client.Internal.GrpcCall[4]
      Finished gRPC call.

Tracing (theo dõi)

gRPC services và gRPC client cung cấp thông tin về các lần gọi gRPC sử dụng DiagnosticSourceActivity.

Tracing của gRPC service

gRPC services được host trên ASP.NET Core, báo cáo các sự kiện về các HTTP request đến. Metadata đặc thù của gRPC được thêm vào diagnostics HTTP request hiện có mà ASP.NET Core cung cấp.

Tracing của gRPC client

.NET gRPC client sử dụng HttpClient để thực hiện các lần gọi gRPC. Mặc dù HttpClient ghi diagnostic events, .NET gRPC client cung cấp một custom diagnostic source, activity và events để có thể thu thập thông tin đầy đủ về một lần gọi gRPC.

Thu thập tracing

Cách dễ nhất để sử dụng DiagnosticSource là cấu hình một thư viện telemetry như Application Insights hoặc OpenTelemetry trong ứng dụng của bạn. Thư viện sẽ xử lý thông tin về các lần gọi gRPC cùng với telemetry ứng dụng khác.

Tracing có thể được xem trong một managed service như Application Insights, hoặc chạy như hệ thống distributed tracing (theo dõi phân tán) của riêng bạn. OpenTelemetry hỗ trợ xuất dữ liệu tracing sang JaegerZipkin.

DiagnosticSource có thể tiêu thụ tracing events trong code sử dụng DiagnosticListener. Để biết thêm thông tin về việc nghe một diagnostic source bằng code, xem DiagnosticSource user's guide.

Các thư viện telemetry hiện tại không nắm bắt telemetry Grpc.Net.Client.GrpcOut đặc thù của gRPC. Công việc cải thiện các thư viện telemetry để nắm bắt tracing này đang được tiến hành.

Metrics (chỉ số)

Metrics là biểu diễn đo lường dữ liệu theo các khoảng thời gian, ví dụ: số 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 sử dụng EventCounter.

Metrics của gRPC service

Metrics của gRPC server được báo cáo trên event source Grpc.AspNetCore.Server.

TênMô tả
total-callsTổng số lần gọi
current-callsSố lần gọi hiện tại
calls-failedTổng số lần gọi thất bại
calls-deadline-exceededTổng số lần gọi vượt quá deadline
messages-sentTổng số message đã gửi
messages-receivedTổng số message đã nhận
calls-unimplementedTổng số lần gọi chưa được triển khai

ASP.NET Core cũng cung cấp các metrics riêng trên event source Microsoft.AspNetCore.Hosting.

Metrics của gRPC client

Metrics của gRPC client được báo cáo trên event source Grpc.Net.Client.

TênMô tả
total-callsTổng số lần gọi
current-callsSố lần gọi hiện tại
calls-failedTổng số lần gọi thất bại
calls-deadline-exceededTổng số lần gọi vượt quá deadline
messages-sentTổng số message đã gửi
messages-receivedTổng số message đã nhận

Quan sát metrics

dotnet-counters là công cụ theo dõi hiệu suất dành cho việc kiểm tra sức khỏe ad-hoc và điều tra hiệu suất cấp đầu tiên. Theo dõi một ứng dụng .NET với Grpc.AspNetCore.Server hoặc Grpc.Net.Client là tên provider.

console
> dotnet-counters monitor --process-id 1902 --counters Grpc.AspNetCore.Server

Press p to pause, r to resume, q to quit.
    Status: Running
[Grpc.AspNetCore.Server]
    Total Calls                                 300
    Current Calls                               5
    Total Calls Failed                          0
    Total Calls Deadline Exceeded               0
    Total Messages Sent                         295
    Total Messages Received                     300
    Total Calls Unimplemented                   0

Một cách khác để quan sát gRPC metrics là nắm bắt dữ liệu counter sử dụng package Microsoft.ApplicationInsights.EventCounterCollector của Application Insights. Sau khi thiết lập, Application Insights thu thập các .NET counter phổ biến lúc runtime. Các counter của gRPC không được thu thập theo mặc định, nhưng App Insights có thể được tùy chỉnh để bao gồm các counter bổ sung.

Chỉ định các gRPC counters cho Application Insight thu thập trong Startup.cs:

csharp
    using Microsoft.ApplicationInsights.Extensibility.EventCounterCollector;

    public void ConfigureServices(IServiceCollection services)
    {
        //... other code...

        services.ConfigureTelemetryModule<EventCounterCollectionModule>(
            (module, o) =>
            {
                // Configure App Insights to collect gRPC counters gRPC services hosted in an ASP.NET Core app
                module.Counters.Add(new EventCounterCollectionRequest("Grpc.AspNetCore.Server", "current-calls"));
                module.Counters.Add(new EventCounterCollectionRequest("Grpc.AspNetCore.Server", "total-calls"));
                module.Counters.Add(new EventCounterCollectionRequest("Grpc.AspNetCore.Server", "calls-failed"));
            }
        );
    }

Tài nguyên bổ sung