如何关闭 ASP.NET 核心框架完成的日志记录

本文关键字:日志 记录 框架 何关闭 ASP NET 核心 | 更新日期: 2023-09-27 18:33:42

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

信息 09:38:41 用户配置文件可用。使用"C:''Users''xxxx xxxx''AppData''Local''ASP.NET''DataProtection-Keys"作为密钥存储库,并使用Windows DPAPI加密静态密钥。
调试 09:38:41 托管开始
调试 09:38:41 托管开始
信息 09:38:41 请求启动 HTTP/1.1 获取 http://localhost:23369/
信息 09:38:41 请求启动 HTTP/1.1 调试 http://localhost:23369/文本/html 调试 09:38:41 不支持
调试请求 调试 09:38:41 请求路径/与支持的文件类型
不匹配 调试 09:38:41 请求已成功匹配名称为"默认"和模板"{控制器=主页}/{操作=索引}/{id?}"的路由。 调试 09:38:41 请求已成功匹配名称为"默认"和模板"{控制器=主页}/{操作=索引}/{id?}"的路由。 调试 09:38:41 执行操作论坛.控制器.主页控制器.索引
调试 09:38:41 执行操作论坛.控制器.主页控制器.索引
信息 09:38:41 执行操作方法 论坛.控制器.主页控制器.带参数的索引 (( - 模型状态有效'
信息 09:38:41 执行操作方法 论坛.控制器.主页控制器.索引
..

我还找不到如何关闭此日志记录...

这是我在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?}");
    });
}

这是我的项目.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 提供程序是从这里获取

如何关闭 ASP.NET 核心框架完成的日志记录

不确定我是否遗漏了什么,但你不是只想提高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不起作用,请道歉

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

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 文件现在没有显示 Microsoft 和其他人吐出的大量INFO日志记录。

更多信息在这里@Microsoft文档:日志筛选

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

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

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

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

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

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" 
  }
  ...
}

由于新的日志记录基础结构(通过设计(由 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."));
}

在 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 源:

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

当然,除了传递委托之外,您还可以直接设置 log4net 的日志级别。

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

ILoggerProvider只是实际日志记录框架的包装器。在简单的ConsoleLoggerProvider情况下,它背后没有框架,只是一个简单的Console.WriteLine调用。

对于 log4net,从示例中可以明显看出,可以按级别启用日志记录。这在上面喜欢的 .NET Core 记录器抽象中是不可能的,因为抽象不执行任何筛选。

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

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

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

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

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

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

在启动中设置这两个配置标志.cs

        services.ConfigureTelemetryModule<DependencyTrackingTelemetryModule>((module, options) =>
        {
            options.EnableDependencyTrackingTelemetryModule = false;
            options.EnableRequestTrackingTelemetryModule = false;
        });

然后,你将仅在日志中看到跟踪遥测类型