-
Notifications
You must be signed in to change notification settings - Fork 5.3k
Closed
Labels
api-approvedAPI was approved in API review, it can be implementedAPI was approved in API review, it can be implementedarea-Extensions-Logging
Milestone
Description
Background and Motivation
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 API
namespace 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 Examples
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",
skipEnabledCheck: true);
public static void ConnectionStarted(ILogger logger, Connection connection)
{
if (logger.IsEnabled(LogLevel.Debug))
{
_connectionStart(logger, connection.ConnectionId, null);
}
}
}Risks
None.
Metadata
Metadata
Assignees
Labels
api-approvedAPI was approved in API review, it can be implementedAPI was approved in API review, it can be implementedarea-Extensions-Logging