LoggerMessage.Define
allows skipping various overheads in logging (parsing the template etc) and returns delegate that performs logging and includes a check if that logging category is enabled before performing the call to log. In some cases it's important that check be moved higher up the stack to avoid transformation of parameters before calling log, for e.g.
public class Connection { private string _connectionId; public string ConnectionId => _connectionId ??= GenerateConnectionId(); } public static class Log { private static readonly Action<ILogger, string, Exception> _connectionStart = LoggerMessage.Define<string>( LogLevel.Debug, new EventId(1, "ConnectionStarted"), "Connection {ConnectionId} started"); public static void ConnectionStarted(ILogger logger, Connection connection) { _connectionStart(logger, connection.ConnectionId, null); } }
The above logic ends up eagerly allocating the ConnectionId
even when the log level isn't enabled. The code could be changed to this:
public static void ConnectionStarted(ILogger logger, Connection connection) { + if (logger.IsEnabled(LogLevel.Debug)) + { _connectionStart(logger, connection.ConnectionId, null); + } }
It would end up checking if the category is enabled multiple times when the category is on.
Proposed APInamespace Microsoft.Extensions.Logging { public static class LoggerMessage { + public static Action<ILogger, T1...T6, Exception> Define<T1...T6>(LogLevel logLevel, EventId eventId, string formatString, bool skipEnabledCheck); }
The ... are overloads T1 to T6 (or more).
Usage Examplespublic class Connection { private string _connectionId; public string ConnectionId => _connectionId ??= GenerateConnectionId(); } public static class Log { private static readonly Action<ILogger, string, Exception> _connectionStart = LoggerMessage.Define<string>( LogLevel.Debug, new EventId(1, "ConnectionStarted"), "Connection {ConnectionId} started", skipEnabledCheck: true); public static void ConnectionStarted(ILogger logger, Connection connection) { if (logger.IsEnabled(LogLevel.Debug)) { _connectionStart(logger, connection.ConnectionId, null); } } }Risks
None.
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4