Estoy usando ConsoleLoggerProvider
de Microsoft.Extensions.Logging (MEL) para escribir registros en la aplicación de consola .NET 6.
Quiero que mis registros incluyan registros de "clase" y "método" para cada entrada de registro, para saber "desde dónde" en mi código se escribió el mensaje de registro.
La única forma actual de hacerlo sin usar soluciones de registro de terceros como Serilog es usar una función integrada de "ámbitos de registro" en MEL.
Así que termino escribiendo código como:
public class MyClass { ILogger _logger; .... //Contructor, etc. public void MyMethod() { using (_logger.BeginScope($"{nameof(MyClass)} => {nameof(MyMethod)}")) { ...//actual logic is here } } }
Observo un concepto de "ExternalScopeProviders" en la documentación de MS, pero está completamente sin documentar y sin ejemplos. ¿Existe una forma más "implícita" de establecer automáticamente los alcances de la estructura del código? ¿O estamos (como usuarios de .NET 6/C#) obligados al uso explícito de using (_logger.BeginScope)
en nuestro código para lograr esto?
El enfoque más moderno sería usar una función que genere automáticamente los nombres y la ubicación de los métodos. Puede crear un método de extensión para esto:
public void Log(this ILogger logger, LogLevel logLevel, string message, [CallerMemberName]string memberName = null, [CallerFilePath]string filePath = null, [CallerLineNumber]int line = 0) { logger.Log(logLevel, $"In function {memberName} ({filePath}:{line}): {message}"); }
(y de manera similar para otras funciones de la interfaz de ILogger
)
El compilador inserta automáticamente el nombre del miembro (sin clase/espacio de nombres) en memberName
, el archivo fuente en filePath
y el número de línea en line
si no los completa manualmente en el sitio de la llamada. Desafortunadamente, no hay una manera fácil de obtener el nombre de clase de la función de llamada de esta manera, pero normalmente es idéntico al nombre del archivo, por lo que no es un problema tan grande.