使用适用于 .NET 的 Azure SDK 进行日志记录

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

重要

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

记录信息

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

HTTP 请求日志条目:

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

HTTP 响应日志条目:

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

HTTP 请求和响应内容:

  • 内容流作为文本或字节,具体取决于 Content-Type 标头。

    注释

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

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

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

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

Azure SDK for .NET 的客户端库通过 System.Diagnostics.Tracing.EventSource 类将事件记录到 Windows 事件跟踪(ETW),这是 .NET 的典型用法。 事件源允许在应用中使用结构化日志记录,同时降低性能开销。 若要获取对事件日志的访问权限,需要注册事件侦听器。

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

登录到控制台窗口

适用于 .NET 客户端库的 Azure SDK 的核心原则是简化实时查看综合日志的功能。 此方法 CreateConsoleLogger 允许使用单行代码将日志发送到控制台窗口:

using AzureEventSourceListener listener = 
    AzureEventSourceListener.CreateConsoleLogger();

记录日志到诊断跟踪信息

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

此示例指定冗长日志级别:

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

配置自定义日志记录

如上所述,需要注册事件侦听器才能从用于 .NET 的 Azure SDK 接收日志消息。 如果不想使用上述简化方法之一实现全面的日志记录,可以构造类的 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 (string.Equals(e.EventSource.Name, "Azure-Core", StringComparison.Ordinal))
        {
            Console.WriteLine($"{DateTime.Now} {message}");
        }
    },
    level: EventLevel.Verbose);

映射到 ASP.NET 核心日志记录

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

下表描述了 Azure SDK for .NET 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中,更改服务总线库的默认日志级别。 例如,按如下所示将Debug键设置为Logging:LogLevel:Azure.Messaging.ServiceBus以实现切换:

    {
        "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 库的默认日志级别。 例如,按如下所示将Debug键设置为Logging:LogLevel:Azure.Core以实现切换:

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

    由于将Logging:LogLevel:Azure.Core密钥设置为Debug,Azure Core 库的事件将被记录到EventLevel.Verbose

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

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

从版本开始,1.2.0支持捕获来自 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中,更改服务总线库的默认日志级别。 例如,按如下所示将Debug键设置为Logging:LogLevel:Azure.Messaging.ServiceBus以实现切换:

    {
        "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)的库不支持内容日志记录。 不支持的示例包括 Azure 服务的库,例如事件中心、服务总线和 Web PubSub。

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

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

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

  1. 将客户端选项对象的 IsLoggingContentEnabled 属性设置为 true,并将 options 对象传递给客户端的构造函数。 例如,若要记录 Azure Key Vault 机密库的 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.LogAlwaysAzureEventSourceListener.CreateConsoleLoggerAzureEventSourceListener.CreateTraceLogger
    配置自定义日志记录 AzureEventSourceListener 类的 level 构造函数参数设置为 EventLevel.VerboseEventLevel.LogAlways
    映射到 ASP.NET Core 日志系统 "Azure.Core": "Debug"添加到appsettings.json

后续步骤