Closed
Description
Problem Description
In a large codebase, there are cases people want to log with existing types defined for business logic (and these types might come from a 3rd party library which is not controlled by the dev), rather than having to invent another type (and do the mapping) or write lots of boilerplate code.
public struct Food
{
public string Name { get; set; }
public double Price { get; set; }
}
logger.Eat(new Food { Name = "artichoke", Price = 3.99 });
In order for the above code to work, one has to write the boilerplate code as follows, and will start to hit performance issue if there are more than 6 fields (based on the current implementation).
using System;
using Microsoft.Extensions.Logging;
public static class LoggerExtensions
{
private static readonly Action<ILogger, Food, Exception> _eat = LoggerMessage.Define<Food>(
LogLevel.Information,
new EventId(1, nameof(Eat)),
"Eat (Food = {food})."); // message template, not interpolated string
public static void Eat(this ILogger logger, Food food)
{
_eat(logger, food, null);
}
}
The Ask
Provide a vendor agnostic way for the user to log strong typed objects without having to write boilerplate code, yet with good/reasonable performance.
public struct Food
{
public string Name { get; set; }
public double Price { get; set; }
}
public class Dog
{
public string Name { get; set; }
public int Age { get; set; }
}
logger.Eat(new Food { Name = "Artichoke", Price = 3.99 });
logger.Log(new Dog { Name = "Labrador Retriever", Age = 2 });
Additional Information
- It is not clear if this should part of .NET runtime, or it should be provided by 3rd party (e.g. OpenTelemetry). I guess one goal could be - any existing provider (e.g.
ConsoleLoggerProvider
) should just work. - This potentially could leverage compile-time logging source generation.
- Additional scenario 1
- Additional scenario 2