patterncsharpdotnetTip
ILogger structured logging with semantic log properties
Viewed 0 times
.NET 6+
structured loggingILogger message templateLoggerMessage attributeSerilog propertieslog property capture
Problem
Using string interpolation in log messages ($"User {userId} logged in") produces flat strings that cannot be queried by log aggregation tools. Properties are lost after serialization.
Solution
Use message template syntax with named placeholders. The logger captures the values as structured properties:
// BAD — string concatenation loses structure
_logger.LogInformation($"Order {orderId} placed by {userId}");
// GOOD — structured properties captured separately
_logger.LogInformation(
"Order {OrderId} placed by {UserId}",
orderId, userId);
// With LoggerMessage.Define for high-performance zero-allocation logging
public static partial class Log
{
[LoggerMessage(EventId = 1001, Level = LogLevel.Information,
Message = "Order {OrderId} placed by {UserId}")]
public static partial void OrderPlaced(
ILogger logger, int orderId, string userId);
}
// Usage
Log.OrderPlaced(_logger, order.Id, user.Id);Why
Structured logging providers (Serilog, Application Insights, OpenTelemetry) extract named properties from the message template and store them as searchable fields. Interpolated strings produce a single opaque string field with no way to filter by orderId.
Gotchas
- Property names in templates are PascalCase by convention — {orderId} and {OrderId} are different properties
- LoggerMessage source generator (LoggerMessageAttribute) is available .NET 6+ and produces the best performance
- Avoid logging sensitive data (passwords, tokens) — use a destructure policy or log only IDs
Revisions (0)
No revisions yet.