【问题标题】:How to turn off the logging done by the ASP.NET core framework如何关闭由 ASP.NET 核心框架完成的日志记录
【发布时间】:2016-05-17 00:28:26
【问题描述】:

如何关闭 ASP.NET 为每个请求完成的日志记录,例如

INFO 09:38:41 用户配置文件可用。使用“C:\Users\xxxx xxxx\AppData\Local\ASP.NET\DataProtection-Keys”作为密钥存储库和 Windows DPAPI 来加密静态密钥。
调试 09:38:41 托管开始
调试 09:38:41 托管开始
INFO 09:38:41 请求开始 HTTP/1.1 GET http://localhost:23369/
INFO 09:38:41 请求开始 HTTP/1.1 DEBUG http://localhost:23369/ text/html 调试 09:38:41 不支持调试请求
调试 09:38:41 请求路径 / 与支持的文件类型不匹配
调试 09:38:41 请求成功匹配名称为“默认”和模板“{controller=Home}/{action=Index}/{id?}”的路由。 调试 09:38:41 请求成功匹配名称为“默认”和模板“{controller=Home}/{action=Index}/{id?}”的路由。 调试 09:38:41 执行操作 Forums.Controllers.HomeController.Index
调试 09:38:41 执行操作 Forums.Controllers.HomeController.Index
INFO 09:38:41 使用参数 () 执行操作方法 Forums.Controllers.HomeController.Index - ModelState 有效'
INFO 09:38:41 执行动作方法 Forums.Controllers.HomeController.Index
..

我还没有找到如何关闭此注销功能...

这是我在Startup 类中的Configure 方法:

public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
    loggerFactory.AddProvider(new Log4NetProvider());

    if (env.IsDevelopment())
    {
        app.UseBrowserLink();
        app.UseDeveloperExceptionPage();
        app.UseDatabaseErrorPage();
    }
    else
    {
        app.UseExceptionHandler("/Home/Error");

        // For more details on creating database during deployment see http://go.microsoft.com/fwlink/?LinkID=615859
        try
        {
            using (var serviceScope = app.ApplicationServices.GetRequiredService<IServiceScopeFactory>()
                .CreateScope())
            {
                serviceScope.ServiceProvider.GetService<ApplicationDbContext>()
                     .Database.Migrate();
            }
        }
        catch { }
    }

    app.UseIISPlatformHandler(options => options.AuthenticationDescriptions.Clear());

    app.UseStaticFiles();

    app.UseIdentity();

    // To configure external authentication please see http://go.microsoft.com/fwlink/?LinkID=532715

    app.UseMvc(routes =>
    {
        routes.MapRoute(
            name: "default",
            template: "{controller=Home}/{action=Index}/{id?}");
    });
}

这是我的 project.json 文件:

"dependencies": {
  "EntityFramework.Commands": "7.0.0-rc1-final",
  "EntityFramework.MicrosoftSqlServer": "7.0.0-rc1-final",
  "log4net": "2.0.5",
  "Microsoft.AspNet.Authentication.Cookies": "1.0.0-rc1-final",
  "Microsoft.AspNet.Diagnostics.Entity": "7.0.0-rc1-final",
  "Microsoft.AspNet.Identity.EntityFramework": "3.0.0-rc1-final",
  "Microsoft.AspNet.IISPlatformHandler": "1.0.0-rc1-final",
  "Microsoft.AspNet.Mvc": "6.0.0-rc1-final",
  "Microsoft.AspNet.Mvc.TagHelpers": "6.0.0-rc1-final",
  "Microsoft.AspNet.Server.Kestrel": "1.0.0-rc1-final",
  "Microsoft.AspNet.StaticFiles": "1.0.0-rc1-final",
  "Microsoft.AspNet.Tooling.Razor": "1.0.0-rc1-final",
  "Microsoft.Extensions.CodeGenerators.Mvc": "1.0.0-rc1-final",
  "Microsoft.Extensions.Configuration.FileProviderExtensions": "1.0.0-rc1-final",
  "Microsoft.Extensions.Configuration.Json": "1.0.0-rc1-final",
  "Microsoft.Extensions.Configuration.UserSecrets": "1.0.0-rc1-final",
  "Microsoft.Extensions.Logging": "1.0.0-rc1-final",
  "Microsoft.VisualStudio.Web.BrowserLink.Loader": "14.0.0-rc1-final"
},

"commands": {
  "web": "Microsoft.AspNet.Server.Kestrel",
  "ef": "EntityFramework.Commands"
},

"frameworks": {
  "dnx451": { }
},

更新:
我的 log4net 提供商被 from here

【问题讨论】:

  • 1.您要关闭的日志到底在哪里。 2. 您的应用程序是如何托管的?
  • @haim770,第一个问题我没看懂。 2. IIS 快递。
  • 您明确将log4net 注册为您的日志记录提供程序。是您要关闭的log4net 日志吗?这是您在控制台中看到的吗?您只是想更改跟踪级别吗?
  • @haim,我觉得跟log4net没什么关系,是我写的一个适配器,它无法访问asp.net管道,也就是说asp.net内部调用记录器工厂。
  • 您没有指定在哪里看到/找到要禁用的日志,所以我不得不假设它是log4net 输出。同样,在哪里您看到DEBUG 09:38:41 Hosting starting 行了吗?

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


【解决方案1】:

我不确定我是否遗漏了什么,但您不想提高 Microsoft 日志的日志级别吗?

编辑appsettings.json(假设.AddJsonFile("appsettings.json", ...)

{
  "Logging": {
    "IncludeScopes": false,
    "LogLevel": {
      "Default": "Trace",
      "System": "Information",
      "Microsoft": "Information"

{
  "Logging": {
    "IncludeScopes": false,
    "LogLevel": {
      "Default": "Trace",
      "System": "Information",
      "Microsoft": "None"

或者通过环境变量进行相同的修改(假设.AddEnvironmentVariables()

Logging:LogLevel:Microsoft=None

您还可以更具体一些,以下内容减少了大多数条目,但将 Microsoft.AspNetCore.Hosting.Internal.WebHost 保留为 Information

"Microsoft": "Information",  
"Microsoft.AspNetCore.Mvc.Internal": "Warning",
"Microsoft.AspNetCore.Authentication":  "Warning"

如果这不适用于log4net,请致歉

【讨论】:

  • 我无法让它与 Serilog 一起使用,但在命令行上运行应用程序(即 dotnet run)时,它确实适用于控制台日志记录。
  • 不幸的是,此配置文件仅用于控制控制台日志记录。 loggerFactory.AddConsole(Configuration.GetSection("Logging"));
  • @Alyce Serilog 也提供过滤功能:new LoggerConfiguration().Filter.ByExcluding(Matching.FromSource("Microsoft")) - 更多信息请参见:stackoverflow.com/questions/38760381/…
  • 您还可以覆盖,以便使用new LoggerConfiguration().MinimumLevel.Override("Microsoft", LogEventLevel.Warning)仅记录特定源的特定级别以上的事件
  • Ooooooooh,这就是 Microsoft 和 System 的那些奇怪的“LogLevels”的用途......我没有意识到这一点。很好的提示。
【解决方案2】:

真正对我有用的是在 ASP.NET Core 2.0 项目的 Startup.cs 文件中添加它:

using Microsoft.Extensions.Logging;
public void ConfigureServices(IServiceCollection services)
{
    .
    .
    .

    services.AddLogging(
    builder =>
    {
        builder.AddFilter("Microsoft", LogLevel.Warning)
               .AddFilter("System", LogLevel.Warning)
               .AddFilter("NToastNotify", LogLevel.Warning)
               .AddConsole();
    });
}

这样,您只会获得警告级别日志,用于记录从传递给builder.AddFilter 的过滤器开始的信息。

我的 log4net.log 文件现在没有显示微软和其他公司大量的 INFO 日志记录。

更多信息在这里@Microsoft Docs:Log filtering

【讨论】:

  • 像我这样的菜鸟,加using Microsoft.Extensions.Logging;
  • 谢谢。是的,如果你使用WebHost.CreateDefaultBuilder(args).UseStartup&lt;Startup&gt;(),那么你应该在Startup.cs中配置日志
【解决方案3】:

如果您使用 Serilog 进行 .NET Core 日志记录,您可以更新 appsettings.json 文件以设置日志级别,如下所示:

"Serilog": {
  "MinimumLevel": {
    "Default": "Verbose",
    "Override": {
      "Microsoft": "Error",
      "System": "Error"
    }
  },
  "Properties": {
    "Application": "your-app"
  }
}

这允许您只记录来自 System/Microsoft 的错误,同时根据需要记录其他所有内容。

【讨论】:

  • 这为我完成了工作。谢谢。
【解决方案4】:

由于 asp.net 本身(以及其他供应商代码)正在(按设计)使用新的日志记录基础架构,因此由 ILoggerProvider 实现决定是否要记录该源。

这里是 log4net 的修改实现,添加了基本的源过滤:

public class Log4NetProvider : ILoggerProvider
{
    private static readonly NoopLogger _noopLogger = new NoopLogger();
    private readonly Func<string, bool> _sourceFilterFunc;
    private readonly ConcurrentDictionary<string, Log4NetLogger> _loggers = new ConcurrentDictionary<string, Log4NetLogger>();

    public Log4NetProvider(Func<string, bool> sourceFilterFunc = null)
    {
        _sourceFilterFunc = sourceFilterFunc != null ? sourceFilterFunc : x => true;
    }

    public ILogger CreateLogger(string name)
    {
        if (!_sourceFilterFunc(name))
            return _noopLogger;

        return _loggers.GetOrAdd(name, x => new Log4NetLogger(name));
    }

    public void Dispose()
    {
        _loggers.Clear();
    }

    private class NoopLogger : ILogger
    {
        public IDisposable BeginScopeImpl(object state)
        {
            return null;
        }

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

        public void Log(LogLevel logLevel, int eventId, object state, Exception exception, Func<object, Exception, string> formatter)
        {
        }
    }
}

还有Log4NetAspExtensions

public static void ConfigureLog4Net(this IApplicationEnvironment appEnv, string configFileRelativePath)
{
    GlobalContext.Properties["appRoot"] = appEnv.ApplicationBasePath;
    XmlConfigurator.Configure(new FileInfo(Path.Combine(appEnv.ApplicationBasePath, configFileRelativePath)));
}

public static void AddLog4Net(this ILoggerFactory loggerFactory, Func<string, bool> sourceFilterFunc = null)
{
    loggerFactory.AddProvider(new Log4NetProvider(sourceFilterFunc));
}

public static void AddLog4Net(this ILoggerFactory loggerFactory)
{
    loggerFactory.AddLog4Net(null);
}

可能的用法(Startup.cs):

public Startup(IHostingEnvironment env, IApplicationEnvironment appEnv, ILoggerFactory loggerFactory)
{
    appEnv.ConfigureLog4Net("log4net.xml");

    loggerFactory.AddLog4Net(x => !x.StartsWith("Microsoft."));
}

【讨论】:

  • 我在这里找不到正确答案,正确的应该是:loggerFactory.WithFilter(new FilterLoggerSettings { { "Microsoft", LogLevel.Warning }, { "System", LogLevel.Warning }, { "MyOwnProject", LogLevel.Debug } }) .AddConsole(Configuration.GetSection("Logging")) .AddDebug();
【解决方案5】:

在 ASP.NET Core 版本 3 中,您可以在 ConfigureServices 函数中清除现有的日志提供程序:

public void ConfigureServices(IServiceCollection services) {
    //Do everything else...
    services.AddLogging(c => c.ClearProviders());
}

【讨论】:

  • 这对我不起作用。 ASP.NET 核心仍在记录 :'(
【解决方案6】:

appsettings.json 中为键 Microsoft 设置 Logging.LogLevel 是不够的。我必须专门设置以下键,例如:

"Microsoft.Hosting.Lifetime": "Warning",
"Microsoft.AspNetCore.Hosting.Diagnostics": "Warning",
"Microsoft.AspNetCore.StaticFiles.StaticFileMiddleware": "Warning"

但作为替代方案,使用带有通配符的键,例如Microsoft.*,工作。所以我最终得到了:

{
  "Logging": {
    "LogLevel": {
      "Default":     "Warning",
      "Microsoft.*": "Warning" 
  }
  ...
}

【讨论】:

    【解决方案7】:

    在 ASP.NET 5 RC1(现为 ASP.NET Core 1.0)之前及之前,您可以通过记录器工厂来实现,即

    public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
    {
        // completely disable logging or use one of the other levels, such as Error, Critical, Warning etc. 
        loggerFactory.MinimumLevel = LogLevel.None;
    }
    

    但是,对于当前分支(尚未发布,但可通过夜间构建获得),此功能已被删除。现在您需要为每个提供者传递LogLevel。通常这是通过扩展方法完成的。

    例如,对于内置控制台记录器,它将是 loggerFactory.AddConsole(minimumLevel: LogLevel.Warning);

    由于您的记录器提供程序是自定义的,因此您必须自己配置它。看看控制台记录器是如何做到的。它将委托传递给提供者,提供者进行过滤。

    来自GitHub Source

    public static ILoggerFactory AddConsole(
        this ILoggerFactory factory,
        LogLevel minLevel,
        bool includeScopes)
    {
        factory.AddConsole((category, logLevel) => logLevel >= minLevel, includeScopes);
        return factory;
    }
    

    当然你也可以直接设置log4net的日志级别,而不是传递委托。

    更新:扩展我在 cmets 中指出的内容

    ILoggerProvider 只是实际日志框架的包装。在ConsoleLoggerProvider 的简单案例中,它背后没有任何框架,只是一个简单的Console.WriteLine 调用。

    在 log4net 的情况下,从示例中可以明显看出日志记录可以在每个级别的基础上启用。这对于上面喜欢的 .NET Core 记录器抽象是不可能的,因为抽象不做任何过滤。

    在 log4net ILoggerProvider 中,只需将所有日志级别路由到 log4net 网络库并让它过滤它。

    根据创建的链接 GitHub 问题 @haim770,您有用于过滤的 SourceContext,如果 log4net 没有 SourceContext 的概念,您必须在提供程序中实现它。如果它有 SourceContext 的概念,那么提供者需要将其重新路由/翻译成 log4net 期望的结构。

    如您所见,记录器本身始终不了解 ASP.NET 的内部细节和实现细节。 Log4NetProvider 不能也不应该,因为它的任务是翻译/环绕该 api。提供者只是抽象,因此我们不必将实现细节泄漏到库中。

    【讨论】:

    • 这不是我想要的。我不想在我的应用程序中全局更改日志记录级别,我只想关闭通过我的提供程序隧道传输的 ASP.NET 日志记录。我深入研究了源代码,这不是一项简单的任务,我很不高兴:(
    • @gdoron:所有日志记录请求都将通过隧道传送到每个注册的ILoggingProvider。提供者/记录器的任务是进行日志级别过滤。这就是为什么 MinimumLevel 被删除并且现在只能在每个提供者级别上设置
    • 我了解所有记录器都应该获取所有记录请求。我只是不明白为什么没有办法将 ASP.NET 本身的日志记录设置为特定级别,为什么我需要我的日志记录提供程序了解所有组件,对我来说这似乎是糟糕的设计。
    • @gdoron:因为这是供应商的责任。一个应用程序可以有多个提供者,全局设置它可能没有意义。例如,您可能有一个用于开发的ConsoleLogger,您希望在其中拥有所有信息,包括“跟踪”和“调试”级别,另一方面,您可能希望拥有仅记录错误和关键的文件日志记录。 ASP.NET Core 非常灵活,因此可以轻松添加或删除某个功能。您只需将记录器设置为警告级别或更高级别,则不会记录调试、信息和跟踪级别
    • 此外,您的记录器提供者不需要了解任何组件,只需要了解调试级别即可,因为这是告诉记录器应该记录哪些类型的消息,哪些不应该记录。
    【解决方案8】:

    使用 Serilog,我发现在定义记录器配置时为 Microsoft 组件指定覆盖是一个简单的案例:

    Log.Logger = new LoggerConfiguration()
        ... // Other config
        .MinimumLevel.Information()
        .MinimumLevel.Override("Microsoft", LogEventLevel.Warning)
        ... // Other config
        .CreateLogger();
    

    这使我只能为 Microsoft 组件记录 Warning 或以上级别的条目,而为我自己的组件记录 Information 及以上级别。

    【讨论】:

      猜你喜欢
      • 2021-08-08
      • 1970-01-01
      • 1970-01-01
      • 2013-12-11
      • 1970-01-01
      • 1970-01-01
      • 2013-12-29
      • 2020-02-06
      • 1970-01-01
      相关资源
      最近更新 更多