ILogger 的隐式范围

Implicit scopes for ILogger

我正在使用 Microsoft.Extensions.Logging (MEL) 中的 ConsoleLoggerProvider 在 .NET 6 控制台应用程序中写入日志。

我希望我的日志包含每个日志条目的“class”和“方法”记录,以了解日志消息在我的代码中“从何处”写入。

当前唯一不使用 Serilog 等第三方日志记录解决方案的方法是使用 MEL 中“日志范围”的内置功能。

所以我最终写了这样的代码:

public class MyClass {

    ILogger _logger;

    .... //Contructor, etc.

    public void MyMethod() 
    {
        using (_logger.BeginScope($"{nameof(MyClass)} => {nameof(MyMethod)}"))
            {
                ...//actual logic is here
            }
     }
}
    

我在 MS 文档中观察到“ExternalScopeProviders”的概念,但它完全没有记录且没有示例。是否有更多“隐式”方式自动设置代码结构范围?还是我们(作为 .NET 6/C# 用户)必须在我们的代码中显式使用 using (_logger.BeginScope) 来实现这一点?

更现代的方法是使用 auto-generates 方法名称和位置的函数。您可以为此创建一个扩展方法:

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}");
}

ILogger 接口的其他函数也类似)

编译器自动在memberName中插入成员名(不带class/namespace),在filePath中插入源文件,在line中插入行号,如果你这样做not 在调用站点手动填写它们。不幸的是,没有简单的方法可以通过这种方式获取调用函数的 class 名称,但它通常与文件名相同,所以这不是什么大问题。