129

How do I turn off the logging done by ASP.NET for each request e.g.

INFO 09:38:41 User profile is available. Using 'C:\Users\xxxx xxxx\AppData\Local\ASP.NET\DataProtection-Keys' as key repository and Windows DPAPI to encrypt keys at rest.
DEBUG 09:38:41 Hosting starting
DEBUG 09:38:41 Hosting started
INFO 09:38:41 Request starting HTTP/1.1 GET http://localhost:23369/
INFO 09:38:41 Request starting HTTP/1.1 DEBUG http://localhost:23369/ text/html DEBUG 09:38:41 DEBUG requests are not supported
DEBUG 09:38:41 The request path / does not match a supported file type
DEBUG 09:38:41 Request successfully matched the route with name 'default' and template '{controller=Home}/{action=Index}/{id?}'. DEBUG 09:38:41 Request successfully matched the route with name 'default' and template '{controller=Home}/{action=Index}/{id?}'. DEBUG 09:38:41 Executing action Forums.Controllers.HomeController.Index
DEBUG 09:38:41 Executing action Forums.Controllers.HomeController.Index
INFO 09:38:41 Executing action method Forums.Controllers.HomeController.Index with arguments () - ModelState is Valid'
INFO 09:38:41 Executing action method Forums.Controllers.HomeController.Index
..

I couldn't find yet how I can turn this logging off...

This is my Configure method in the Startup class:

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

And this is my project.json file:

"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": { }
},

Update:
My log4net provider was taken from here

isapir
  • 21,295
  • 13
  • 115
  • 116
gdoron
  • 147,333
  • 58
  • 291
  • 367
  • 1
    1. Where exactly do you those logs you want to turn off. 2. How is your application hosted? – haim770 Feb 07 '16 at 07:58
  • @haim770, I didn't understand the first question. 2. IIS express. – gdoron Feb 07 '16 at 08:13
  • You're explicitly registering `log4net` as your logging provider. Is it the `log4net` logs you want to turn off? Is it something you see in the Console? Do you simply want to change the tracing level? – haim770 Feb 07 '16 at 08:14
  • @haim, I don't think it has anything to do with log4net, it's an adapter I wrote, it doesn't have access to the asp.net pipeline, which means asp.net internally calls the logger factory. – gdoron Feb 07 '16 at 08:39
  • 1
    You didn't specify where do you see/find those logs you want to disable so I had to assume it's `log4net` output. Again, *where* do you see the `DEBUG 09:38:41 Hosting starting` line? – haim770 Feb 07 '16 at 08:41
  • @haim I see it in my log.log file I configured log4net to log to. – gdoron Feb 07 '16 at 08:45
  • You'll have to show your `Log4NetProvider` – haim770 Feb 07 '16 at 08:58
  • @haim770 http://dotnetliberty.com/index.php/2015/11/09/asp-net-5-logging-with-log4net/ – gdoron Feb 07 '16 at 09:04
  • See https://github.com/aspnet/Logging/blob/dev/samples/SampleApp/logging.json – haim770 Feb 07 '16 at 09:34
  • @haim770, I deep dived into the source code, it seems ASP.NET team made it very hard to write a logger provider and use the logging. (Basically you need to be aware of all other components that want to use the log, and by default, they will use your log). I don't like it. Anyway, תודה אחי. – gdoron Feb 07 '16 at 19:26
  • I too think the team somehow "intertwined" the logging facility all over the place. On the other hand, it can be really handful sometimes. Anyway, I'm going to write an answer soon (based on their `ConsoleLogger` filters implementation). – haim770 Feb 07 '16 at 19:33
  • I added an issue on GitHub as well (https://github.com/aspnet/Logging/issues/359) – haim770 Feb 07 '16 at 19:46

9 Answers9

120

I'm not sure if I am missing something but don't you just want to raise the log level for the Microsoft logs?

Edit appsettings.json (assumes .AddJsonFile("appsettings.json", ...))

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

To

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

Or the same modification via environment variables (assumes .AddEnvironmentVariables())

Logging:LogLevel:Microsoft=None

You can also be more specific, the following reduces most entries but leaves Microsoft.AspNetCore.Hosting.Internal.WebHost at Information.

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

Appologies if this doesn't work for log4net

KCD
  • 9,873
  • 5
  • 66
  • 75
  • 9
    I couldn't get this to work with Serilog, but it did work for the console logging when running the app on the command line (i.e. dotnet run). – Alyce Oct 20 '16 at 06:36
  • 2
    This config file is only used to control console logging unfortunately. `loggerFactory.AddConsole(Configuration.GetSection("Logging"));` – scott Apr 12 '17 at 15:52
  • 9
    @Alyce Serilog has filtering available as well: `new LoggerConfiguration().Filter.ByExcluding(Matching.FromSource("Microsoft"))` - see this for more info: http://stackoverflow.com/questions/38760381/multiple-filters-for-one-logger-with-serilog – Mani Gandham May 13 '17 at 22:18
  • 7
    You can also override so that only events above a certain level are logged for a specific source by using `new LoggerConfiguration().MinimumLevel.Override("Microsoft", LogEventLevel.Warning)` – Mani Gandham May 13 '17 at 22:43
  • 2
    Ooooooooh, that's what those strange "LogLevels" for Microsoft and System were for... I didn't realise that. Excellent tip. – Mike Gledhill May 17 '18 at 08:08
  • 1
    If it isn't working, check your _appsettings.Development.json_. From the [docs](https://learn.microsoft.com/en-us/aspnet/core/fundamentals/logging/?view=aspnetcore-3.0#configuration): `If levels are specified in Logging.{providername}.LogLevel, they override anything set in Logging.LogLevel`. – jhhwilliams Oct 26 '19 at 04:37
  • Also, you can use `Logging__LogLevel__Microsoft=None` syntax instead of `Logging:LogLevel:Microsoft=None` in environment variable setup. Also, you can not write breviations, like, `Warn` or `Info`, you must write the full level names, like, `Information` or `Warning`. – korulis Jan 06 '20 at 15:10
  • Actually, in Linux `Logging:LogLevel:Microsoft=None` might not even work. I just have just experienced that myself. – korulis Jan 06 '20 at 15:44
  • I am working on Blazor Server app, I am using Log4net to send Logging emails out. I am getting confused I hope you could help. When an exception is thrown I am getting two emails instead of one. getting one written email In which it shows an Error I logged inside my LogError(ex. message), then I get another email with a detailed error. I "LogLevel": { "Default": "Error", "Microsoft": "None", "Microsoft.Hosting.Lifetime": "None", "Microsoft.AspNetCore.SignalR": "None" } even I put it on non still getting all of that Microsoft detailed in the second email – redar ismail Nov 03 '22 at 18:11
51

What have really worked for me was adding this in ASP.NET Core 2.0 project's Startup.cs file:

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

This way you'll only get Warning level logs for logging info starting with the filters passed to builder.AddFilter.

My log4net.log file now doesn't show that huge amount of INFO logging spit by Microsoft and others.

More info here @ Microsoft Docs: Log filtering

PJUK
  • 1,758
  • 1
  • 16
  • 21
Leniel Maccaferri
  • 100,159
  • 46
  • 371
  • 480
48

If you're using Serilog to do your .NET Core logging, you can update your appsettings.json file to set the log levels like so:

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

This allows you to only log errors from System/Microsoft while logging everything else as you'd like.

Pang
  • 9,564
  • 146
  • 81
  • 122
Tony Ranieri
  • 1,479
  • 1
  • 18
  • 32
  • 2
    This did the job for me. Thank You. – Sunny Okoro Awa Nov 19 '18 at 13:49
  • The error value for Microsoft didn't work for me in .NET 7. I needed to provide the full namespace of the logger I wanted to exclude. Here is my implementation "Using": ["Serilog.Expressions"], "MinimumLevel": { "Default": "Debug", "Override": { "Microsoft": "Information", "System": "Error", "Microsoft.AspNetCore.Hosting.Diagnostics": "Error" } } – Tom McDonough Jun 16 '23 at 07:23
17

In ASP.NET Core version 3, you can clear the existing log providers in the ConfigureServices function:

public void ConfigureServices(IServiceCollection services) {
    //Do everything else...
    services.AddLogging(c => c.ClearProviders());
}
Pang
  • 9,564
  • 146
  • 81
  • 122
Casey
  • 1,573
  • 14
  • 17
10

Setting Logging.LogLevel in appsettings.json for the key Microsoft was not enough. I had to specifically set the following keys specifically, e.g.:

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

But as an alternative using a key with a wildcard, e.g. Microsoft.*, worked. So I ended up with:

{
  "Logging": {
    "LogLevel": {
      "Default":     "Warning",
      "Microsoft.*": "Warning" 
  }
  ...
}
isapir
  • 21,295
  • 13
  • 115
  • 116
7

Since the new logging infrastructure is being used (by design) by asp.net itself (as well as other vendor code), it's up to the ILoggerProvider implementation to decide whether it wants to log that source or not.

Here's a revised implementation for log4net that adds a basic source filtering:

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)
        {
        }
    }
}

And the 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);
}

Possible usage (in Startup.cs):

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

    loggerFactory.AddLog4Net(x => !x.StartsWith("Microsoft."));
}
haim770
  • 48,394
  • 7
  • 105
  • 133
  • 1
    I can't find the correct answer anywhere here, the correct one should be: `loggerFactory.WithFilter(new FilterLoggerSettings { { "Microsoft", LogLevel.Warning }, { "System", LogLevel.Warning }, { "MyOwnProject", LogLevel.Debug } }) .AddConsole(Configuration.GetSection("Logging")) .AddDebug();` – timeshift Sep 07 '17 at 11:25
5

In and before ASP.NET 5 RC1 (now ASP.NET Core 1.0), you could do it via the logger factory, i.e.

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

However, with the current branch (not released yet, but available via nightly builds), this has been removed. Now you need to pass the LogLevel per provider. Typically this is done via extension method.

For the built in console logger, it would be loggerFactory.AddConsole(minimumLevel: LogLevel.Warning); for example.

Since your logger provider is a custom one, you will have to configure it yourself. Take a look on how the console logger does it. It passes a delegate to the provider, that does the filtering.

From GitHub Source:

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

Of course instead of passing a delegate you can also directly set the log level of log4net.

Update: To extend on what I've pointed out in the comments

The ILoggerProvider is only a wrapper around the actual logging framework. In the simple case of ConsoleLoggerProvider, there is no framework as all behind it, just a simple Console.WriteLine call.

In case of log4net, it's obvious from the example that logging can be enabled on a per level basis. This isn't possible with the .NET Core logger abstraction liked above, as the abstraction doesn't do any filtering.

In a log4net ILoggerProvider one would simply route all log levels to the log4net net library and have it filter it.

Based on the linked GitHub issue @haim770 created, you have the SourceContext for filtering and if log4net doesn't have a concept of SourceContext, you'll have to implement this in the provider. If it has a concept of SourceContext, then the provider needs to reroute/translate it into the structure log4net expects it.

As you can see, the logger itself always stays unaware about internal specifics and implementation details of ASP.NET. The Log4NetProvider can't and shouldn't, because it's task is to translate/wrap around that api. Providers are just abstractions, so we don't have to leak implementation details into a library for example.

Tseng
  • 61,549
  • 15
  • 193
  • 205
  • This is not what I'm after. I do not want to change the logging level globally in my application, I just wish to turn off the ASP.NET logging which is tunneled through my provider. I deep dived into the source code, it's not a trivial task, I'm unhappy :( – gdoron Feb 07 '16 at 19:31
  • @gdoron: All logging requests will be tunneled to every registered `ILoggingProvider`. It's the task of the provider/logger to do the log level filtering. That's why `MinimumLevel` was removed and the now can only be set on per provider level – Tseng Feb 07 '16 at 19:37
  • I understand that all the loggers should get all logging requests. I just don't understand why there's no way to set ASP.NET itself logging to a specific level, why do I need my logging provider to be aware of all of the components, to me it seems like bad design. – gdoron Feb 07 '16 at 19:48
  • @gdoron: Because it's the providers responsibility. An application can have more than one provider, setting it globally may make no sense. For example you may have a `ConsoleLogger` for development, where you want to have all information, including "Trace" and "Debug" Level, on the other side you may want to have file logging which only logs Errors and Criticals. ASP.NET Core is made to be very flexible and be easy to add or remove a certain feature and for that reason. All you need to do is set your logger to Warning Level or higher, then Debug, Information and Trace level won't be logged – Tseng Feb 07 '16 at 19:52
  • Also your logger provider doesn't need to be aware of any components, just about the debug level, as this is what tells the logger what kind of messages it should log and which not. – Tseng Feb 07 '16 at 19:53
  • This is not true, see [this example](https://github.com/aspnet/Logging/blob/dev/samples/SampleApp/logging.json) from Microsoft samples, the logger is aware of all of the components. If I set my logger to "information" level, it will ignore `debug` level of ASP.NET as well as of my application level, a thing I do not want. I can understand the reason for this design, it just makes things much more complicated for most users. – gdoron Feb 07 '16 at 20:21
  • @gdoron: I think you are a confusing two things here: `ILoggerProvider` and the logger itself. In most cases, the `ILoggerProvider` wraps the actual logger around this interface and handles/translates ASP.NET Core related types (like LogLevel) to your logging library types, also also does the rough filtering. In the example, the ConsoleLogger is so simple, that it does both in one class. All the provider has to do is receive the log messages from the application, apply log level and source filter, and if it passes it, call the log method of your log library – Tseng Feb 08 '16 at 07:06
  • The actual logger, that is called from `ILoggerProvider` can do the actual logging (i.e. broadcast it via message bus, write it to the database, to a file, or event log like in windows etc). The actual logger never knows about how the log system works or details about it. The provider however, may need to know this to do the filtering and the `ILoggerProvider` is tied to the Logger abstractions of ASP.NET Core (since it depends on that interface to be plugged in in the logging pipeline) – Tseng Feb 08 '16 at 07:08
2

With Serilog, I found it was a simple case of specifying an override for Microsoft components when defining the logger configuration:

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

This allowed me to only log Warning level or above entries for Microsoft components, but Information and above for my own components.

Martin
  • 16,093
  • 1
  • 29
  • 48
  • If you add `.MinimumLevel.Override("System", LogEventLevel.Warning)` it also helps (this got rid of redundant logs from my HttpClients) – duck Apr 06 '23 at 15:13
0

Set these two configuration flags in the startup.cs

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

then you will only see the trace telemetry type in the logs

Adam Weitzman
  • 1,552
  • 6
  • 23
  • 45