通过 Azure SDK for .NET 启用日志记录

Azure SDK for .NET 的客户端库包括记录客户端库操作的功能。 此日志记录使你可以监视客户端库对 Azure 服务进行的 I/O 请求和响应。 通常,日志用于调试或诊断通信问题。 本文介绍了使用 Azure SDK for .NET 启用日志记录的以下方法:

重要

本文适用于使用最新版 Azure SDK for .NET 的客户端库。 若要查看库是否受支持,请参阅包含 Azure SDK 最新版本的列表。 如果应用使用的是旧版 Azure SDK 客户端库,请参阅适用服务文档中的具体说明。

记录信息

SDK 记录每个 HTTP 请求和响应,清理参数查询和标头值以删除个人数据。

HTTP 请求日志条目:

  • 唯一 ID
  • HTTP 方法
  • URI
  • 传出请求标头

HTTP 响应日志条目:

  • I/O 操作的持续时间(已用时间)
  • 请求 ID
  • HTTP 状态代码
  • HTTP 原因短语
  • 响应头
  • 错误信息(如果适用)

HTTP 请求和响应内容:

  • 内容流是文本形式还是字节形式,取决于 Content-Type 标头。

    注意

    内容日志记录默认处于禁用状态。 若要启用它,请参阅记录 HTTP 请求和响应正文。 此功能仅适用于使用 HTTP 与 Azure 服务通信的库。 基于备用协议(如 AMQP)的库不支持内容日志记录。 不受支持的示例包括事件中心、服务总线和 Web PubSub 等 Azure 服务的库。

通常以以下三个级别之一输出事件日志:

  • 有关请求和响应事件的信息
  • 错误警告
  • 详细消息和内容记录的详细信息

使用内置方法启用日志记录

Azure SDK for .NET 客户端库通过 System.Diagnostics.Tracing.EventSource 类将事件记录到 Windows 事件跟踪 (ETW),这是 .NET 的典型功能。 事件源使你能够以最小的性能开销在应用中使用结构化日志记录。 要访问事件日志,需要注册事件侦听器。

SDK 包括 Azure.Core.Diagnostics.AzureEventSourceListener 类,其中包含两个可简化 .NET 应用的综合日志记录的静态方法:CreateConsoleLoggerCreateTraceLogger。 其中的每个方法都接受一个可选参数来指定日志级别。 如果未提供该参数,则使用默认的日志级别 Informational

记录到控制台窗口

Azure SDK for .NET 客户端库的核心原则是简化实时查看综合日志的功能。 利用 CreateConsoleLogger 方法,可以使用一行代码将日志发送到控制台窗口:

using AzureEventSourceListener listener = 
    AzureEventSourceListener.CreateConsoleLogger();

记录到诊断跟踪

如果实现跟踪侦听器,则可以使用 CreateTraceLogger 方法记录到标准 .NET 事件跟踪机制 (System.Diagnostics.Tracing)。 有关 .NET 中的事件跟踪的详细信息,请参阅跟踪侦听器

下面的示例指定一个详细的日志级别:

using AzureEventSourceListener listener = 
    AzureEventSourceListener.CreateTraceLogger(EventLevel.Verbose);

配置自定义日志记录

如上所述,需要注册事件侦听器才能从 Azure SDK for .NET 接收日志消息。 如果你不想使用上面的任何一种简化方法来实现全面的日志记录,可以构造 AzureEventSourceListener 类的一个实例。 向该实例传递一个你编写的回调方法。 此方法将接收可以处理并且必须处理的日志消息。 另外,在构造实例时,可以指定要包括的日志级别。

以下示例创建一个事件侦听器,该侦听器在控制台中记录一条自定义消息。 日志将筛选为从 Azure Core 客户端库发出的带有详细级别的事件。 Azure Core 库使用事件源名称 Azure-Core

using Azure.Core.Diagnostics;
using System.Diagnostics.Tracing;

// code omitted for brevity

using var listener = new AzureEventSourceListener((e, message) =>
    {
        // Only log messages from "Azure-Core" event source
        if (e.EventSource.Name == "Azure-Core")
        {
            Console.WriteLine($"{DateTime.Now} {message}");
        }
    },
    level: EventLevel.Verbose);

映射到 ASP.NET Core 日志记录

利用 AzureEventSourceLogForwarder 服务,你可以使用标准 ASP.NET Core 日志记录配置进行记录。 服务将日志消息从 Azure SDK 事件源转发到 ILoggerFactory

下表描述了用于 .NET 的 Azure SDK EventLevel 如何映射到 ASP.NET Core LogLevel

Azure SDK EventLevel ASP.NET Core LogLevel
Critical Critical
Error Error
Informational Information
Warning Warning
Verbose Debug
LogAlways Information

使用客户端注册进行日志记录

使用 Azure 服务总线库作为示例,完成以下步骤:

  1. 安装 Microsoft.Extensions.Azure NuGet 包:

    dotnet add package Microsoft.Extensions.Azure
    
  2. Program.cs中,通过调用 AddAzureClients 扩展方法注册 Azure SDK 库的客户端:

    using Azure.Identity;
    using Microsoft.Extensions.Azure;
    
    // code omitted for brevity
    
    builder.Services.AddAzureClients(azureBuilder =>
    {
        azureBuilder.AddServiceBusClient(
            builder.Configuration.GetConnectionString("ServiceBus"));
        azureBuilder.UseCredential(new DefaultAzureCredential());
    });
    

    在上述示例中,AddAzureClients 方法:

    • 将以下对象注册到依赖关系注入 (DI) 容器:
      • 日志转发器服务
      • Azure 服务总线客户端
    • 设置要用于所有已注册客户端的默认令牌凭据。
  3. appsettings.json 中,更改服务总线库的默认日志级别。 例如,通过设置 Logging:LogLevel:Azure.Messaging.ServiceBus 密钥将其切换为 Debug,如下所示:

    {
        "ConnectionStrings": {
            "ServiceBus": "<connection_string>"
        },
        "Logging": {
            "LogLevel": {
                "Default": "Information",
                "Microsoft.AspNetCore": "Warning",
                "Azure.Messaging.ServiceBus": "Debug"
            }
        },
        "AllowedHosts": "*"
    }
    

    由于 Logging:LogLevel:Azure.Messaging.ServiceBus 密钥设置为 Debug,将记录不超过 EventLevel.Verbose 的服务总线客户端事件。

不使用客户端注册进行日志记录

在某些情况下,将 Azure SDK 库的客户端注册到 DI 容器是不可能的或不必要的:

在这些情况下,请完成以下步骤:

  1. 安装 Microsoft.Extensions.Azure NuGet 包:

    dotnet add package Microsoft.Extensions.Azure
    
  2. Program.cs中,将日志转发器服务注册为 DI 容器中的单一实例:

    using Azure.Identity;
    using Microsoft.AspNetCore.DataProtection;
    using Microsoft.Extensions.Azure;
    using Microsoft.Extensions.DependencyInjection.Extensions;
    
    var builder = WebApplication.CreateBuilder(args);
    builder.Services.AddRazorPages();
    builder.Services.TryAddSingleton<AzureEventSourceLogForwarder>();
    
    builder.Services.AddDataProtection()
        .PersistKeysToAzureBlobStorage("<connection_string>", "<container_name>", "keys.xml")
        .ProtectKeysWithAzureKeyVault(new Uri("<uri>"), new DefaultAzureCredential());
    
  3. 从 DI 容器提取日志转发器服务并调用其 Start 方法。 例如,在 ASP.NET Core Razor Pages 页面模型类中使用构造函数注入:

    using Microsoft.AspNetCore.Mvc.RazorPages;
    using Microsoft.Extensions.Azure;
    
    public class IndexModel : PageModel
    {
        public IndexModel(AzureEventSourceLogForwarder logForwarder) =>
            logForwarder.Start();
    
  4. appsettings.json 中,更改 Azure Core 库的默认日志级别。 例如,通过设置 Logging:LogLevel:Azure.Core 密钥将其切换为 Debug,如下所示:

    {
      "Logging": {
        "LogLevel": {
          "Default": "Information",
          "Microsoft.AspNetCore": "Warning",
          "Azure.Core": "Debug"
        }
      },
      "AllowedHosts": "*"
    }
    

    由于 Logging:LogLevel:Azure.Core 键设置为 Debug,因此将记录级别不超过 EventLevel.Verbose 的 Azure Core 库事件。

有关详细信息,请参阅 .NET Core 和 ASP.NET Core 中的日志记录

使用 Azure.Monitor.OpenTelemetry.AspNetCore 记录日志

从版本 1.2.0 开始,Azure Monitor OpenTelemetry 发行版支持捕获来自 Azure 客户端库的日志。 可以使用在 .NET Core 和 ASP.NET Core 中记录日志中讨论的任何配置选项之一来控制日志记录。

使用 Azure 服务总线库作为示例,完成以下步骤:

  1. 安装 Azure.Monitor.OpenTelemetry.AspNetCore NuGet 包:

    dotnet add package Azure.Monitor.OpenTelemetry.AspNetCore
    
  2. 创建或注册库的客户端。 该发行版支持这两种情况。

    await using var client = new ServiceBusClient("<connection_string>");
    
  3. appsettings.json 中,更改服务总线库的默认日志级别。 例如,通过设置 Logging:LogLevel:Azure.Messaging.ServiceBus 密钥将其切换为 Debug,如下所示:

    {
        "ConnectionStrings": {
            "ServiceBus": "<connection_string>"
        },
        "Logging": {
            "LogLevel": {
                "Default": "Information",
                "Microsoft.AspNetCore": "Warning",
                "Azure.Messaging.ServiceBus": "Debug"
            }
        },
        "AllowedHosts": "*"
    }
    

    由于 Logging:LogLevel:Azure.Messaging.ServiceBus 密钥设置为 Debug,将记录不超过 EventLevel.Verbose 的服务总线客户端事件。

记录 HTTP 请求和响应正文

注意

此功能仅适用于使用 HTTP 与 Azure 服务通信的库。 基于备用协议(如 AMQP)的库不支持内容日志记录。 不受支持的示例包括事件中心、服务总线和 Web PubSub 等 Azure 服务的库。

使用客户端库排查意外行为时,检查以下项目会很有帮助:

  • 发送到基础 Azure 服务的 REST API 的 HTTP 请求正文。
  • 从 Azure 服务的 REST API 接收的 HTTP 响应正文。

默认情况下,会禁用上述内容的日志记录。 若要启用 HTTP 请求和响应正文的日志记录,请完成以下步骤:

  1. 将客户端 options 对象的 IsLoggingContentEnabled 属性设置为 true,并将 options 对象传递给客户端的构造函数。 例如,若要记录 Azure 密钥保管库的机密库的 HTTP 请求和响应:

    var clientOptions = new SecretClientOptions
    {
        Diagnostics = 
        {
            IsLoggingContentEnabled = true,
        }
    };
    var client = new SecretClient(
        new Uri("https://<keyvaultname>.vault.azure.net/"),
        new DefaultAzureCredential(),
        clientOptions);
    
  2. 将首选日志记录方法与详细/调试或更高的事件/日志级别配合使用。 有关具体说明,请参阅下表中的方法。

    方法 说明
    使用内置方法启用日志记录 EventLevel.VerboseEventLevel.LogAlways 传递到 AzureEventSourceListener.CreateConsoleLoggerAzureEventSourceListener.CreateTraceLogger
    配置自定义日志记录 AzureEventSourceListener 类的 level 构造函数参数设置为 EventLevel.VerboseEventLevel.LogAlways
    映射到 ASP.NET Core 日志记录 "Azure.Core": "Debug" 添加到 appsettings.json

后续步骤