We're using compile-time logging source generation with the LoggerMessageAttribute
, e. g.:
public static partial class LoggerExtensions
{
[LoggerMessage(
EventId = 1953,
EventName = "ExecutingQuery",
Level = LogLevel.Information,
Message = "Executing query {MyQuery}")]
public static partial void ExecutingQuery(this ILogger logger, string myQuery);
}
So that we can log like this:
internal class MyBeautifulQueryHandler
{
private readonly ILogger<MyBeautifulQueryHandler> _logger;
public MyBeautifulQueryHandler(ILogger<MyBeautifulQueryHandler> logger) => _logger = logger;
public async Task ExecuteAsync(MyBeautifulQuery query)
{
_logger.ExecutingQuery(nameof(MyBeautifulQuery));
// do something asynchronously
}
}
This patterns using the nameof
operator occurs again and again in our codebase.
I'm wondering whether compile-time logging source generation supports something like this:
_logger.ExecutingQuery<MyBeautifulQuery>();
or even better
_logger.ExecutingQuery();
with both resulting in the same log message Executing query MyBeautifulQuery
. So I'm looking for something similar to CallerMemberNameAttribute
.
Is that possible?
Thanks!
CodePudding user response:
You can use a layer of indirection:
public static partial class LoggerExtensions
{
[LoggerMessage(
EventId = 1953,
EventName = "ExecutingQuery",
Level = LogLevel.Information,
Message = "Executing query {MyQuery}")]
static partial void LogExecutingQuery(ILogger logger, string myQuery);
public static void ExecutingQuery<T>(this ILogger logger)
{
LogExecutingQuery(logger, typeof(T).Name);
}
}
Would have your desired usage:
_logger.ExecutingQuery<MyBeautifulQuery>();