39

In ASP.NET Core 2.0 we have this

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

That CreateDefaultBuilder(args) has many helpful defaults. However it contains this:

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

So the console and debug logging providers are always registered.

I used to register them like this

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

How do I remove/unregister them when running in production mode? I don't mean changing the logging level, I mean I don't want them registered at all in production mode.

2
  • The CreateDefaultBuilder was created to ease setup (aggregate lots of common stuff) a new project. Before final 2.0 there was no DefaultBuilder. I would suggest you to copy the code from the source code you´ve just linked and change it by your own, as I said, CreateDefaultBuilder is just to ease this step. Take a look how it was done before: learn.microsoft.com/en-us/aspnet/core/migration/1x-to-2x/… . Regards. Commented Aug 31, 2017 at 18:26
  • 1
    @dime2lo I'm hoping I don't have to do that. I'm happy with the defaults, except for the logging during production mode. There surely is a way to undo those particular registrations. Commented Aug 31, 2017 at 19:11

3 Answers 3

59

I would say the designed way to do this would be by changing the logging configuration not to log anything to those providers. But I understand that you want to remove any calls for production; and you can still do this properly in code.

You can simply access the hosting environment from the HostBuilderContext that gets passed to the ConfigureLogging lambda:

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

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

Obviously, this alone does not help to undo what the CreateDefaultBuilder call already set up. First, you would need to unregister those providers. For that, you can use the new ILoggingBuilder.ClearProviders method:

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

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

This was introduced in response to this logging issue on GitHub.

Sign up to request clarification or add additional context in comments.

4 Comments

If ClearProviders not found add using namespace Microsoft.Extensions.Logging
It is a bummer that there isn't a way to remove providers - only the ability to create a whole new configuration especially now that ASP.NET Core's default builder creates a default configuraton that includes both the Debug and Console loggers. The place to look is in the source of CreateDefaultBuilder() and duplicate only what you need from there.
I love ClearProviders()! I wanted to disable logging during debugging - since I was testing server round trip (100 times in a for loop) and didn't want the time to write and scroll the console screwing up my result. Looks like it was taking about 10ms for each database call just for logging!
Also very important to note (as you did) that ClearProviders was an officially approved solution for this issue - and not just a hack :-)
14

I found that it is better to remove a specific logging provider from the services as follows:

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

Comments

4

I think you cant use the CreateDefaultBuilder then or set the LogLevels to None maybe. According to the docs you can use this.

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

How to Add providers Section https://learn.microsoft.com/en-us/aspnet/core/fundamentals/logging?tabs=aspnetcore2x

Found another option, just add a Logging Filter for Console in your appsettings.json

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

4 Comments

Yeah that's how we did it in 1.1. I'd like to keep the defaults, but undo those registrations, there must be a way.
the only way I know of doing that, would be to override that class with your own code. I had to do that for Identity PasswordHasher.
Can I add a logging provider through configuration alone? I couldn't quite figure that out. (I want to ClearProviders() and add Console by means of appsettings.json)
@JensMander I don't believe that would be possible. If it is possible, it would depend on the provider you are using.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.