Do you use LoggerMessage in .NET?

Updated by Baba Kamyljanov [SSW] 2 months ago. See history

123

Logging is a critical component in modern applications, but it can easily introduce performance overhead.

.NET 6 introduced the LoggerMessageAttribute, a feature in the Microsoft.Extensions.Logging namespace that enables source-generated, highly performant logging APIs. This approach eliminates runtime overheads like boxing and temporary allocations, making it faster than traditional logging methods.

Key performance benefits of LoggerMessageAttribute

  • Source Generation: Automatically generates the implementation of partial methods with compile-time diagnostics.
  • Improved Performance: Reduces runtime overhead by leveraging compile-time optimizations.
  • Flexible Usage: Supports static and instance-based methods with configurable log levels and message templates.

How to use LoggerMessageAttribute

Define logging methods as partial and static to trigger the code generator:

public static partial class Log
{
[LoggerMessage(
EventId = 0,
Level = LogLevel.Critical,
Message = "Could not open socket to `{HostName}`")]
public static partial void CouldNotOpenSocket(
ILogger logger, string hostName);
}

Logging methods can also be used in an instance context by accessing an ILogger field or primary constructor parameter:

public partial class InstanceLoggingExample(ILogger logger)
{
[LoggerMessage(
EventId = 0,
Level = LogLevel.Critical,
Message = "Could not open socket to `{HostName}`")]
public partial void CouldNotOpenSocket(string hostName);
}

Using LoggerMessageAttribute with JsonConsole formatter can produce structured logs. In our log messages we can specify custom event names as well as utelize string formatters:

[LoggerMessage(
EventId = 9,
Level = LogLevel.Trace,
EventName = "PropertyValueEvent")]
Message = "In {City} the average property value is {Value:E}")]
public static partial void PropertyValueInAustralia(ILogger logger, string city double value);

Constraints

When using LoggerMessageAttribute, ensure:

  • Logging methods must be partial and return void.
  • Logging method names must not start with an underscore.
  • Parameter names of logging methods must not start with an underscore.
  • Logging methods may not be defined in a nested type.
  • Logging methods cannot be generic.
  • If a logging method is static, the ILogger instance is required as a parameter.

More information

See this great article on Microsoft Learn which goes into more detail and usage examples: Compile-time logging source generation in .NET.

acknowledgements
related rules