-
Notifications
You must be signed in to change notification settings - Fork 4.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add LoggerMessage.Define overload to disable IsEnabled check #45290
Comments
Tagging subscribers to this area: @maryamariyan Issue DetailsBackground and Motivation
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 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);
}
}
} RisksNone.
|
Looks good as proposed. namespace Microsoft.Extensions.Logging
{
public static class LoggerMessage
{
public static Action<ILogger, T1, Exception> Define<T1>(LogLevel logLevel, EventId eventId, string formatString);
public static Action<ILogger, T1, T2, Exception> Define<T1, T2>(LogLevel logLevel, EventId eventId, string formatString);
public static Action<ILogger, T1, T2, T3, Exception> Define<T1, T2, T3>(LogLevel logLevel, EventId eventId, string formatString);
public static Action<ILogger, T1, T2, T3, T4, Exception> Define<T1, T2, T3, T4>(LogLevel logLevel, EventId eventId, string formatString);
public static Action<ILogger, T1, T2, T3, T4, T5, Exception> Define<T1, T2, T3, T4, T5>(LogLevel logLevel, EventId eventId, string formatString);
public static Action<ILogger, T1, T2, T3, T4, T5, T6, Exception> Define<T1, T2, T3, T4, T5, T6>(LogLevel logLevel, EventId eventId, string formatString);
}
} |
@bartonjs did you copy the wrong overloads? These are already here: runtime/src/libraries/Microsoft.Extensions.Logging.Abstractions/src/LoggerMessage.cs Line 151 in 5078dd6
skipEnabledCheck .
What about the overload that doesn't take any runtime/src/libraries/Microsoft.Extensions.Logging.Abstractions/src/LoggerMessage.cs Line 130 in 5078dd6
PS: I have a PR ready, just need to submit it when the new overloads are confirmed. |
Renaming "master" to "main" in #48357 broke the link. https://github.com/dotnet/runtime/compare/main...gfoidl:loggermessage-skipEnabledCheck?expand=1 works instead. You added if (skipEnabledCheck)
{
return (logger, exception) => { /* just call logger.Log and not logger.IsEnabled */ };
}
else
{
return (logger, exception) => { /* call logger.IsEnabled and logger.Log */ };
} That would be more work for the JIT compiler, though. |
I would prefer if it returned a different lambda without the check. @KalleOlaviNiemitalo are you going to submite a PR? |
No, I do not intend to make a PR. |
But I can take the suggestion from @KalleOlaviNiemitalo and incorporate them into my changes. |
Filed dotnet/aspnetcore#31332 so that these new API can be used for ASP.NET Core too. |
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.The above logic ends up eagerly allocating the
ConnectionId
even when the log level isn't enabled. The code could be changed to this: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
Risks
None.
The text was updated successfully, but these errors were encountered: