.NET 上 gRPC 中的日志记录和诊断Logging and diagnostics in gRPC on .NET
本文内容
本文提供从 gRPC 应用收集诊断以帮助解决问题的指南。涵盖的主题包括:
- 日志记录 - 写入 .NET Core 日志记录的结构化日志。应用框架使用 ILogger 来编写日志,用户使用它在应用中进行用户自己的日志记录。
- 跟踪 - 与使用
DiaganosticSource
和Activity
进行编写的操作相关的事件。来自诊断源的跟踪通常用于通过库(如 Application Insights 和 OpenTelemetry)收集应用遥测数据。 - 指标 - 一段时间间隔内数据度量值的表示形式,例如每秒请求数。指标是使用
EventCounter
发出的,可以使用 dotnet-counters 命令行工具或 Application Insights 进行观察。
LoggingLogging
gRPC 服务和 gRPC 客户端使用 .NET Core 日志记录编写日志。当你需要调试应用中的意外行为时,日志是一个不错的起点。
gRPC 服务日志记录gRPC services logging
警告
服务器端日志可能包含来自应用的敏感信息。切勿将来自生产应用的原始日志发布到 GitHub 等公共论坛 。
由于 gRPC 服务托管在 ASP.NET Core 上,因此它使用 ASP.NET Core 日志记录系统。在默认配置中,gRPC 只记录很少的信息,但这可以进行配置。有关配置 ASP.NET Core 日志记录的详细信息,请参阅 ASP.NET Core 日志记录上的文档。
gRPC 在 Grpc
类别下添加日志。若要启用来自 gRPC 的详细日志,请通过在 Logging
中的 LogLevel
子节中添加以下项目,将 Grpc
前缀配置为 appsettings.json 文件中的 Debug
级别 :
{
"Logging": {
"LogLevel": {
"Default": "Debug",
"System": "Information",
"Microsoft": "Information",
"Grpc": "Debug"
}
}
}
你也可以在具有 ConfigureLogging
的 Startup.cs 中配置此项 :
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureLogging(logging =>
{
logging.AddFilter("Grpc", LogLevel.Debug);
})
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup<Startup>();
});
如果不使用基于 JSON 的配置,请在配置系统中设置以下配置值:
Logging:LogLevel:Grpc
=Debug
查看配置系统的文档以确定如何指定嵌套的配置值。例如,使用环境变量时,使用两个 _
而不是 :
字符(例如 LoggingLogLevelGrpc
)。
建议在为应用收集更详细的诊断时使用 Debug
级别。Trace
级别产生的诊断级别很低,且很少需要它来诊断应用中的问题。
日志记录输出示例Sample logging output
下面是 Debug
级别的 gRPC 服务控制台输出示例:
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
访问服务器端日志Access server-side logs
访问服务器端日志的方式取决于在其中运行的环境。
作为控制台应用As a console app
如果在控制台应用中运行,则默认情况下应启用控制台记录器。gRPC 日志将在控制台中显示。
其他环境Other environments
如果将应用部署到另一个环境(例如 Docker、Kubernetes 或 Windows 服务),请参阅 .NET Core 和 ASP.NET Core 中的日志记录,了解有关如何配置适用于环境的日志记录提供程序的详细信息。
gRPC 客户端日志记录gRPC client logging
警告
客户端日志可能包含来自应用的敏感信息。切勿将来自生产应用的原始日志发布到 GitHub 等公共论坛 。
若要从 .NET 客户端获取日志,可以在创建客户端通道时设置 GrpcChannelOptions.LoggerFactory
属性。如果要从 ASP.NET Core 的应用调用 gRPC 服务,则可以通过依赖关系注入 (DI) 来解析记录器工厂:
[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);
}
}
启用客户端日志记录的另一种方法是使用 gRPC 客户端工厂创建客户端。已向客户端工厂注册且解析自 DI 的 gRPC 客户端将自动使用应用的已配置日志记录。
如果应用未使用 DI,则可以使用 LoggerFactory.Create 创建新的 ILoggerFactory
实例。若要访问此方法,请将 Microsoft.Extensions.Logging 包添加到应用。
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);
gRPC 客户端日志作用域gRPC client log scopes
gRPC 客户端可将日志记录作用域添加到在 gRPC 调用期间创建的日志。作用域具有与 gRPC 调用相关的元数据:
- GrpcMethodType - gRPC 方法类型。可能的值为来自
Grpc.Core.MethodType
枚举的名称,如一元 - GrpcUri - gRPC 方法的相对 URI,例如 /greet.Greeter/SayHellos
日志记录输出示例Sample logging output
下面是 Debug
级别的 gRPC 客户端控制台输出示例:
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
gRPC 服务和 gRPC 客户端使用 DiagnosticSource 和 Activity 提供有关 gRPC 调用的信息。
- .NET gRPC 使用活动来表示 gRPC 调用。
- 跟踪事件将在 gRPC 调用活动开始和结束时写入到诊断源。
- 跟踪不会捕获有关在 gRPC 流调用的生存期内消息何时发送的信息。
gRPC 服务跟踪gRPC service tracing
gRPC 服务托管在会报告有关传入 HTTP 请求事件的 ASP.NET Core 上。特定于 gRPC 的元数据将添加到 ASP.NET Core 提供的现有 HTTP 请求诊断。
- 诊断源名称为
Microsoft.AspNetCore
。 - 活动名称为
Microsoft.AspNetCore.Hosting.HttpRequestIn
。- gRPC 调用所调用的 gRPC 方法的名称将添加为标记,标记名称为
grpc.method
。 - gRPC 调用完成后,其状态代码将添加为标记,标记名称为
grpc.status_code
。
- gRPC 调用所调用的 gRPC 方法的名称将添加为标记,标记名称为
gRPC 客户端跟踪gRPC client tracing
.NET gRPC 客户端使用 HttpClient
进行 gRPC 调用。尽管 HttpClient
可编写诊断事件,但 .NET gRPC 客户端提供自定义诊断源、活动和事件,以便可以收集有关 gRPC 调用的完整信息。
- 诊断源名称为
Grpc.Net.Client
。 - 活动名称为
Grpc.Net.Client.GrpcOut
。- gRPC 调用所调用的 gRPC 方法的名称将添加为标记,标记名称为
grpc.method
。 - gRPC 调用完成后,其状态代码将添加为标记,标记名称为
grpc.status_code
。
- gRPC 调用所调用的 gRPC 方法的名称将添加为标记,标记名称为
收集跟踪Collecting tracing
使用 DiagnosticSource
的最简单方法是在应用中配置遥测库,如 Application Insights 或 OpenTelemetry。该库将与其他应用遥测一起处理有关 gRPC 调用的信息。
可以在托管服务(如 Application Insights)中查看跟踪,也可以选择运行自己的分布式跟踪系统。OpenTelemetry 支持将跟踪数据导出到 Jaeger 和 Zipkin。
DiagnosticSource
可以使用 DiagnosticListener
在代码中使用跟踪事件。有关使用代码侦听诊断源的信息,请参阅 DiagnosticSource 用户指南。
备注
遥测库当前不捕获特定于 gRPC 的 Grpc.Net.Client.GrpcOut
遥测。改进捕获此跟踪的遥测库的工作正在进行。
指标Metrics
指标是一段时间间隔内数据度量值的表示形式,例如每秒请求数。使用指标数据可以在高级别观察应用的状态。.NET gRPC 指标是使用 EventCounter
发出的。
gRPC 服务指标gRPC service metrics
gRPC 服务器指标在 Grpc.AspNetCore.Server
事件源上报告。
“属性” | 描述 |
---|---|
total-calls | 总调用数 |
current-calls | 当前调用 |
calls-failed | 失败调用总数 |
calls-deadline-exceeded | 超出截止时间的调用总数 |
messages-sent | 已发送消息总数 |
messages-received | 已接收消息总数 |
calls-unimplemented | 总未实现调用数 |
ASP.NET Core 还在 Microsoft.AspNetCore.Hosting
事件源上提供其自己的指标。
gRPC 客户端指标gRPC client metrics
gRPC 客户端指标在 Grpc.Net.Client
事件源上报告。
“属性” | 描述 |
---|---|
total-calls | 总调用数 |
current-calls | 当前调用 |
calls-failed | 失败调用总数 |
calls-deadline-exceeded | 超出截止时间的调用总数 |
messages-sent | 已发送消息总数 |
messages-received | 已接收消息总数 |
观察指标Observe metrics
dotnet-counters 是一个性能监视工具,用于临时运行状况监视和初级性能调查。使用 Grpc.AspNetCore.Server
或 Grpc.Net.Client
作为提供程序名称监视 .NET 应用。
> dotnet-counters monitor --process-id 1902 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
观察 gRPC 指标的另一种方法是使用 Application Insights 的 包捕获计数器数据。设置完成后,Application Insights 可在运行时收集常见的 .NET 计数器。默认情况下,不收集 gRPC 的计数器,但可以自定义 App Insights 以包括其他计数器。
为 Application Insight 指定 gRPC 计数器以在 Startup.cs 中收集 :
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"));
}
);
}