记录复杂对象

了解如何使用 OpenTelemetry .NET 记录复杂对象

.NET OpenTelemetry 日志入门 - 控制台 指南中,我们学习了如何记录基本数据类型。本指南将向您展示如何记录复杂对象。

复杂对象记录在 .NET 中

.NET 8.0 通过 LogPropertiesAttribute 引入了复杂对象记录。此属性和相应的代码生成逻辑由一个名为 Microsoft.Extensions.Telemetry.Abstractions 的扩展包提供。

先决条件

实施步骤

1. 安装必需的包

安装 Microsoft.Extensions.Telemetry.Abstractions

dotnet add package Microsoft.Extensions.Telemetry.Abstractions

2. 定义一个复杂数据类型

创建一个结构来表示您的复杂对象

public struct FoodRecallNotice
{
    public string? BrandName { get; set; }
    public string? ProductDescription { get; set; }
    public string? ProductType { get; set; }
    public string? RecallReasonDescription { get; set; }
    public string? CompanyName { get; set; }
}

3. 创建一个带有 LogPropertiesAttribute 的日志记录扩展方法

为您的日志记录器定义一个使用 Define an extension method to ILogger 的扩展方法,该方法使用

using Microsoft.Extensions.Logging;

internal static partial class LoggerExtensions
{
    [LoggerMessage(LogLevel.Critical)]
    public static partial void FoodRecallNotice(
        this ILogger logger,
        [LogProperties(OmitReferenceName = true)] in FoodRecallNotice foodRecallNotice);
}

[LogProperties(OmitReferenceName = true)] 属性指示源生成器

  • FoodRecallNotice 的所有属性包含为单独的日志属性
  • 从属性键中省略引用名称(参数名称)

4. 记录复杂对象

创建复杂对象的实例并记录它

// Create a complex object
var foodRecallNotice = new FoodRecallNotice
{
    BrandName = "Contoso",
    ProductDescription = "Salads",
    ProductType = "Food & Beverages",
    RecallReasonDescription = "due to a possible health risk from Listeria monocytogenes",
    CompanyName = "Contoso Fresh Vegetables, Inc.",
};

// Log the complex object
logger.FoodRecallNotice(foodRecallNotice);

5. 运行应用程序

运行应用程序,例如使用 dotnet run,您应该会在控制台上看到日志输出

LogRecord.Timestamp:               2024-01-12T19:01:16.0604084Z
LogRecord.CategoryName:            Program
LogRecord.Severity:                Fatal
LogRecord.SeverityText:            Critical
LogRecord.FormattedMessage:
LogRecord.Body:
LogRecord.Attributes (Key:Value):
    CompanyName: Contoso Fresh Vegetables, Inc.
    RecallReasonDescription: due to a possible health risk from Listeria monocytogenes
    ProductType: Food & Beverages
    ProductDescription: Salads
    BrandName: Contoso
LogRecord.EventId:                 252550133
LogRecord.EventName:               FoodRecallNotice

请注意,FoodRecallNotice 对象的每个属性都显示为日志记录中的一个单独的属性。

LogPropertiesAttribute 选项

LogPropertiesAttribute 提供了几个选项来控制属性如何包含在日志中

  • OmitReferenceName: 设置为 true 时,参数名称将从属性键中省略。在上例中,属性键只是属性名(例如,“BrandName”),而不是“foodRecallNotice.BrandName”。

  • IncludeProperties: 用于指定要包含哪些属性。如果未指定,则包含所有属性。

  • ExcludeProperties: 用于指定要从日志记录中排除哪些属性。

  • IncludeSensitive: 设置为 true 时,标记有 [Sensitive] 属性的属性将包含在日志中。默认值为 false

完整示例

以下是一个将所有内容整合在一起的完整示例

using System;
using Microsoft.Extensions.Logging;
using OpenTelemetry;
using OpenTelemetry.Logs;

// Complex object definition
public struct FoodRecallNotice
{
    public string? BrandName { get; set; }
    public string? ProductDescription { get; set; }
    public string? ProductType { get; set; }
    public string? RecallReasonDescription { get; set; }
    public string? CompanyName { get; set; }
}

// Logger extension method
internal static partial class LoggerExtensions
{
    [LoggerMessage(LogLevel.Critical)]
    public static partial void FoodRecallNotice(
        this ILogger logger,
        [LogProperties(OmitReferenceName = true)] in FoodRecallNotice foodRecallNotice);
}

// Main program
class Program
{
    static void Main(string[] args)
    {
        // Create a logger factory with OpenTelemetry
        using var loggerFactory = LoggerFactory.Create(builder =>
        {
            builder.AddOpenTelemetry(options =>
            {
                options.AddConsoleExporter();
            });
        });

        // Get a logger instance
        var logger = loggerFactory.CreateLogger<Program>();

        // Create a complex object
        var foodRecallNotice = new FoodRecallNotice
        {
            BrandName = "Contoso",
            ProductDescription = "Salads",
            ProductType = "Food & Beverages",
            RecallReasonDescription = "due to a possible health risk from Listeria monocytogenes",
            CompanyName = "Contoso Fresh Vegetables, Inc.",
        };

        // Log the complex object
        logger.FoodRecallNotice(foodRecallNotice);

        Console.WriteLine("Press any key to exit");
        Console.ReadKey();
    }
}

了解更多