【问题标题】:Remove console and debug loggers in ASP.NET Core 2.0 when in production mode在生产模式下删除 ASP.NET Core 2.0 中的控制台和调试记录器
【发布时间】:2018-02-09 17:00:45
【问题描述】:

在 ASP.NET Core 2.0 中我们有这个

public static IWebHost BuildWebHost(string[] args) =>
    WebHost.CreateDefaultBuilder(args)
        .UseStartup<Startup>()
        .Build();

CreateDefaultBuilder(args) 有许多有用的默认值。然而它contains this:

.ConfigureLogging((context, logging) => {
    logging.AddConfiguration(context.Configuration.GetSection("Logging"));
    logging.AddConsole();   // HERE IS THE PROBLEM
    logging.AddDebug();     // HERE IS THE PROBLEM
})

所以控制台和调试日志提供程序总是被注册。

我以前是这样注册的

if (env.IsDevelopment())
{ 
    // register them here
}

在生产模式下运行时如何删除/取消注册它们? 我的意思不是改变日志记录级别,我的意思是我根本不希望它们在生产模式下注册。

【问题讨论】:

  • CreateDefaultBuilder 的创建是为了简化新项目的设置(聚合许多常见的东西)。在最终 2.0 之前,没有 DefaultBuilder。我建议您从刚刚链接的源代码中复制代码并自行更改,正如我所说,CreateDefaultBuilder 只是为了简化这一步。看看之前是怎么做的:docs.microsoft.com/en-us/aspnet/core/migration/1x-to-2x/…。问候。
  • @dime2lo 我希望我不必这样做。我对默认设置很满意,除了生产模式下的日志记录。肯定有一种方法可以撤消这些特定的注册。

标签: c# asp.net-core asp.net-core-2.0


【解决方案1】:

我会说设计的方法是通过更改日志配置而不向这些提供者记录任何内容。但我了解您想取消任何生产要求;而且您仍然可以在代码中正确执行此操作。

您可以简单地从传递给ConfigureLogging lambda 的HostBuilderContext 访问托管环境:

.ConfigureLogging((context, logging) =>
{
    logging.AddConfiguration(context.Configuration.GetSection("Logging"));

    if (context.HostingEnvironment.IsDevelopment())
    {
        logging.AddConsole();
        logging.AddDebug();
    }
});

显然,仅此一项并不能帮助撤消 CreateDefaultBuilder 调用已经设置的内容。首先,您需要注销这些提供程序。为此,您可以使用新的ILoggingBuilder.ClearProviders 方法:

.ConfigureLogging((context, logging) =>
{
    // clear all previously registered providers
    logging.ClearProviders();

    // now register everything you *really* want
    // …
});

这是为了回应this logging issue on GitHub而引入的。

【讨论】:

  • 如果没有找到 ClearProviders 添加using namespace Microsoft.Extensions.Logging
  • 遗憾的是,没有办法删除提供程序 - 只有创建全新配置的能力,尤其是现在 ASP.NET Core 的默认构建器创建了一个默认配置,其中包括调试和控制台记录器。要查看的位置在CreateDefaultBuilder() 的源代码中,并仅从那里复制您需要的内容。
  • 我爱ClearProviders()!我想在调试期间禁用日志记录 - 因为我正在测试服务器往返(在 for 循环中 100 次)并且不希望有时间编写和滚动控制台来搞砸我的结果。看起来每个数据库调用仅用于日志记录大约需要 10 毫秒!
  • 同样重要的是要注意(就像您所做的那样)ClearProviders 是官方批准的解决此问题的解决方案 - 而不仅仅是 hack :-)
【解决方案2】:

我发现最好从服务中删除特定的日志记录提供程序,如下所示:

.ConfigureLogging((context, logging) => {
    foreach (ServiceDescriptor serviceDescriptor in logging.Services)
    {
        if (serviceDescriptor.ImplementationType == typeof(Microsoft.Extensions.Logging.Console.ConsoleLoggerProvider))
        {
            // remove ConsoleLoggerProvider service only
            logging.Services.Remove(serviceDescriptor);
            break;
        }
    }

    // now you can register any new logging provider service; e.g.,
    logging.AddLog4Net();
    logging.AddEventSourceLogger();
})

【讨论】:

    【解决方案3】:

    我认为您可能无法使用 CreateDefaultBuilder 或将 LogLevels 设置为 None。根据文档,您可以使用它。

    public static void Main(string[] args)
    {
    var webHost = new WebHostBuilder()
        .UseKestrel()
        .UseContentRoot(Directory.GetCurrentDirectory())
        .ConfigureAppConfiguration((hostingContext, config) =>
        {
            var env = hostingContext.HostingEnvironment;
            config.AddJsonFile("appsettings.json", optional: true, 
    reloadOnChange: true)
                  .AddJsonFile($"appsettings.{env.EnvironmentName}.json", 
    optional: true, reloadOnChange: true);
            config.AddEnvironmentVariables();
        })
        .ConfigureLogging((hostingContext, logging) =>
        {
    
    
    logging.AddConfiguration(hostingContext.Configuration.GetSection("Logging"));
            logging.AddConsole();
            logging.AddDebug();
        })
        .UseStartup<Startup>()
        .Build();
    
    webHost.Run();
    }
    

    如何添加提供者 Section https://docs.microsoft.com/en-us/aspnet/core/fundamentals/logging?tabs=aspnetcore2x

    找到另一个选项,只需在 appsettings.json 中为控制台添加一个日志过滤器

      "Logging": {
    "IncludeScopes": false,
    "LogLevel": {
      "Default": "Debug",
      "System": "Information",
      "Microsoft": "Information"
    },
    "Console": {
      "LogLevel": {
        "Default": "None"
      }
    }
    

    },

    【讨论】:

    • 是的,我们在 1.1 中就是这样做的。我想保留默认值,但撤消这些注册,一定有办法。
    • 我知道的唯一方法是用您自己的代码覆盖该类。我必须为 Identity PasswordHasher 这样做。
    • 我可以单独通过配置添加日志提供程序吗?我无法完全弄清楚。 (我想 ClearProviders() 并通过 appsettings.json 添加控制台)
    • @JensMander 我不相信这是可能的。如果可能,这将取决于您使用的提供商。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-10-21
    • 2018-09-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-08-08
    • 2015-06-28
    相关资源
    最近更新 更多