c# - 如何在 ASP.NET Core MVC 的自定义记录器中正确实现 ILogger.IsEnabled()

标签 c# asp.net-core logging

我(作为新手)正在实现我自己的自定义记录器以用于 ASP.NET Core MVC 应用程序。我让这个记录器在各个方面都正常工作。但到目前为止我有点作弊,即我实现了 ILogger.IsEnabled 方法如下:

public bool IsEnabled(LogLevel logLevel)
{
    return true;
}

从功能上讲,这工作正常,因为框架确保仅当日志级别等于或高于指定级别时才调用 Log() 方法。因此,正在记录正确的“事物”,而未按预期记录较低级别的“事物”。

但是,我还想在我的代码中支持以下情况,其中 _logger 被键入为 ILogger 并正确地注入(inject)到我的 Controller 中:

if (_logger.IsEnabled(LogLevel.Debug))
{
    _logger.LogDebug("This is an expensive message to generate: " +
        JsonConvert.SerializeObject(request));
}

为了使其有效,我的 IsEnabled() 方法应该能够知道使用我的 LoggerProvider 创建的记录器实例的日志级别,但我不知道如何直接获取该信息,或者如何将其正确传递给我正在使用的记录器的注入(inject)实例。

我能够找到的复杂示例和教程似乎在每种情况下都是针对控制台应用程序类型而不是网络应用程序类型构建的,到目前为止,我一直没有成功地弄清楚如何通过模板化的来做到这一点ASP.NET MVC 中的 Startup 类。

什么是停止在我的自定义 IsEnabled() 方法中作弊的最简单和最有效的方法,以便在注入(inject)实例中没有注册记录器的情况下避免不必要的序列化(在我的示例中)正在处理 Debug 日志级别?或者您有最喜欢的 ASP.NET Core 设置示例或教程可以指给我看吗?

最佳答案

您可以查看内置记录器 source code看看他们是如何实现的。

简而言之,他们只检查 logLevel != LogLevel.None,但根据记录器逻辑,您可能还想检查一些其他配置。例如,DebugLogger 记录器还检查 Debugger.IsAttached 属性,EventLogLogger 检查 EventLogSettings.Filter(通过提供构造函数)。

更新

To make this effective, my IsEnabled() method should be able to know what the log level IS for the instance of the logger that was created with my LoggerProvider, but I don't know how to get that information directly, or how to pass it properly to the injected instance of the the logger I am working with.

您可以创建一个 ILoggerProvider 的实现,它又可以利用依赖注入(inject)来获得您想要的配置。如果你想使用选项模式来配置它,你必须按照以下行做一些事情:

public class MyLoggerProvider : ILoggerProvider
{
    private readonly IOptions<MyLoggerOptions> _options;

    public MyLoggerProvider(IOptions<MyLoggerOptions> options)
    {
        _options = options;
    }

    public ILogger CreateLogger(string name)
    {
        return new MyLogger(name, _options.Value);
    }
}

并可选择添加扩展方法以简化注册:

public static class MyLoggerExtensions
{
    public static ILoggingBuilder AddMyLogger(this ILoggingBuilder builder, Action<MyLoggerOptions> configure)
    {
        builder.Services.TryAddEnumerable(ServiceDescriptor.Singleton<ILoggerProvider, MyLoggerProvider>());
        LoggerProviderOptions.RegisterProviderOptions<MyLoggerOptions, MyLoggerProvider>(builder.Services);
        builder.Services.Configure(configure);
    }
}

关于c# - 如何在 ASP.NET Core MVC 的自定义记录器中正确实现 ILogger.IsEnabled(),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68809366/

相关文章:

asp.net-core - .NET Core 3.1 - Swagger 未加载

C# Math.Sin() 和 Math.Log() 不准确

apache - ECS 日志记录(awslogs 驱动程序)仅将 apache 服务器启动日志记录到 cloudwatch,没有 error.log 和没有 access.log

c# - 类中所有值类型的通用函数

c# - 带有标题和内容的 UserControl - 允许在内容面板中删除控件并防止在设计时在标题中删除控件

c# - .NET 是否可以在进程之间共享大型内存中的集合?

c# - 恢复 Nuget 包缓存?

c# - ASP.Net Core 3.0 Web 应用程序和 Vue 超时异常 Visual Studio 2019 v16.4

.net - 完整.NET Framework上的ASP.NET Core 2.1

python - 避免 `logger=logging.getLogger(__name__)`