Home > database >  Use class name in compile-time logging source generation
Use class name in compile-time logging source generation

Time:04-27

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>();
  • Related