Logging complex objects
Estás viendo la versión en inglés de está página porque aún no ha sido traducida. ¿Te interesa ayudar? Mira en Contribuir.
In the Getting Started with OpenTelemetry .NET Logs - Console guide, we learned how to log primitive data types. This guide will show you how to log complex objects.
Complex object logging in .NET
Complex object logging was introduced in .NET 8.0 through the LogPropertiesAttribute. This attribute and the corresponding code generation logic are provided by an extension package called Microsoft.Extensions.Telemetry.Abstractions.
Prerequisites
- Complete the Getting Started with Console tutorial.
Implementation steps
1. Install the required package
Install the Microsoft.Extensions.Telemetry.Abstractions package:
dotnet add package Microsoft.Extensions.Telemetry.Abstractions 2. Define a complex data type
Create a struct to represent your complex object:
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. Create a logger extension method with LogPropertiesAttribute
Define an extension method for your logger that uses the Define an extension method to ILogger that uses the
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); } The [LogProperties(OmitReferenceName = true)] attribute instructs the source generator to:
- Include all properties of the
FoodRecallNoticeas individual log attributes - Omit the reference name (the parameter name) from the attribute keys
4. Log the complex object
Create an instance of your complex object and log it:
// 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. Run the application
Run the application, for example using dotnet run, and you should see the log output on the console:
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 Notice that each property of the FoodRecallNotice object appears as a separate attribute in the log record.
LogPropertiesAttribute options
The LogPropertiesAttribute provides several options to control how properties are included in logs:
OmitReferenceName: When set to
true, the parameter name is omitted from attribute keys. In the example above, attribute keys are just the property names (for example, “BrandName”) rather than “foodRecallNotice.BrandName”.IncludeProperties: Used to specify which properties should be included. If not specified, all properties are included.
ExcludeProperties: Used to specify which properties should be excluded from logging.
IncludeSensitive: When set to
true, properties marked with[Sensitive]attribute are included in logs. The default isfalse.
Complete example
Here’s a complete example that puts everything together:
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(); } } Learn more
- Microsoft.Extensions.Logging.LogPropertiesAttribute
- Microsoft.Extensions.Telemetry.Abstractions
- Log Correlation in OpenTelemetry .NET
- OpenTelemetry Logs Data Model
Comentarios
¿Fue útil esta página?
Thank you. Your feedback is appreciated!
Please let us know how we can improve this page. Your feedback is appreciated!