ILoggerFactory vs serviceCollection.AddLogging vs WebHostBuilder.ConfigureLogging
Asked Answered
T

2

61

I have typical logging requirement for my asp.net core 2.x app:

  • use application insight in production,
  • console and debug logger in development env
  • setup some filters based on category and log level

Now I see at least three different API's to configure the logging:

  1. WebHostBuilder.ConfigureLogging()in Program.cs

    public static void Main(string[] args)
    {
        var webHost = new WebHostBuilder()               
            .ConfigureLogging((hostingContext, logging) =>
            {
                logging.AddConfiguration(hostingContext.Configuration.GetSection("Logging"));
                logging.AddConsole();
                logging.AddDebug();
                logging.AddAzureWebAppDiagnostics();
            })
            .UseStartup<Startup>()
            .Build();
    
        webHost.Run();
    }
    
  2. Inject ILoggerFactory to Startup.Configure method:

    public void Configure(IApplicationBuilder app, ILoggerFactory loggerFactory, IServiceProvider serviceProvider)
    {
        loggerFactory.AddConsole();
        loggerFactory.AddAzureWebAppDiagnostics();
        loggerFactory.AddApplicationInsights(app.ApplicationServices, 
            (category, level) => level >= (category == "Microsoft" ? LogLevel.Error : LogLevel.Information));
        }
    
  3. in Startup.ConfigureServices:

    public void ConfigureServices(IServiceCollection services)
    {
        services.AddLogging(logging => 
        {
            logging.AddConfiguration(hostingContext.Configuration.GetSection("Logging"));
            logging.AddConsole();
            logging.AddDebug();
            logging.AddAzureWebAppDiagnostics();
        }
    }
    

What is the difference between those? When to use which?

Toadflax answered 7/6, 2018 at 14:38 Comment(3)
1 was added in ASP.NET Core 2.0 to replace 2, given that it sets up logging earlier. Where have you seen 3?Clardy
I've edited the 3rd code snippet. not sure where I saw it, but I intelli sense suggests itToadflax
More or less: 1 is preferred when you already have the ConfigureLogging method. Take into account that CreateDefaultBuilder has this method, but it already have configured the logs for you. 2 can be used to get a fast reference to a logger from ILoggerFactory. If you dont have this factory, you cannot do that. 3 is used to have a log instance by dependency injection in your constructors.Mg
M
33

The third one uses ConfigureServices which is a public method in the WebHostBuilder. The first one uses ConfigureLogging which is one of IHostBuilder's extension methods in HostingHostBuilderExtensions.

They both call the IServiceCollection's extension method AddLogging in LoggingServiceCollectionExtensions under the Microsoft.Extensions.Logging package. The AddLogging method first tries to add two singletons ILoggerFactory and ILogger<> and an enumerable of LoggerFilterOptions, then it does the action for logging(ILoggingBuilder) which finally calls the AddProvider method to add the log providers implemented by these providers(Console, Azure) and calls SetMinimumLevel to add LoggerFilterOptions.

The second method directly adds the log providers to LoggerFactory. And these providers are called in LoggerFactory when logging methods are called.

As for orders, the second and third methods are called by WebHostBuilder's UseStartup<TStartup> method.

Mispronounce answered 8/6, 2018 at 3:27 Comment(3)
This answers the first part of the question (What is the difference between those?) but not the second part (When to use which?) Kirk Larkin answers the seccond part in his comment: #1 was added in ASP.NET Core 2.0 to replace #2, given that it sets up logging earlier.Inhabiter
All links given above are no longer available.Proteolysis
Thanks @TheInventorofGod, they're available now.Mispronounce
D
13

In ASP.NET Core 3.x, the first example is now the endorsed option. As explained by the documentation

public static IHostBuilder CreateHostBuilder(string[] args) =>
    Host.CreateDefaultBuilder(args)
        .ConfigureLogging(logging =>
        {
            logging.ClearProviders();
            logging.AddConsole();
        })
        .ConfigureWebHostDefaults(webBuilder =>
        {
            webBuilder.UseStartup<Startup>();
        });

Another change is that writing logs before completion of the DI container setup in the Startup.ConfigureServices method is no longer supported:

  • Logger injection into the Startup constructor is not supported.
  • Logger injection into the Startup.ConfigureServices method signature is not supported

Logging during the host construction is also not supported (since the DI container is not yet set up), the documentation advises to create a separate logger for that case.

Dominance answered 10/2, 2020 at 13:22 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.