记录复杂对象
在 .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();
}
}
了解更多
- Microsoft.Extensions.Logging.LogPropertiesAttribute
- Microsoft.Extensions.Telemetry.Abstractions
- .NET OpenTelemetry 中的日志关联
- OpenTelemetry 日志数据模型