NLog from appsettings with custom appsettings

Viewed 2523

I have a custom appsettings JSON file that I need to be added to the configuration. I'm doing this in the ConfigureAppConfiguration hook called from CreateHostBuilder called from Main in Program.cs. I'm also using NLog.

public static void Main(string[] args)
{
    //
    // currently using nlog.config but I want to use appsettings but they haven't been "built" yet
    var logger = NLog.Web.NLogBuilder.ConfigureNLog("nlog.config").GetCurrentClassLogger();
    try
    {
        logger.Debug("init main");
        CreateHostBuilder(args).Build().Run();
        // could move configurenlog call here, but already called "UseNLog()"
    }
    catch (Exception exception)
    {
        logger.Error(exception, "Stopped program because of exception");
        throw;
    }
    finally
    {
        NLog.LogManager.Shutdown();
    }
}
public static IHostBuilder CreateHostBuilder(string[] args) =>
    Host.CreateDefaultBuilder(args)
    .ConfigureAppConfiguration((hostingContext, config) => {
                  // add custom config file
                    config  
                        .AddJsonFile("customsettings.json", optional:true, reloadOnChange:true);
                })
      .ConfigureWebHostDefaults(webBuilder =>
      {
          webBuilder.UseStartup<Startup>();
      })
      .ConfigureLogging(logging =>
      {
          logging.ClearProviders();
          logging.SetMinimumLevel(Microsoft.Extensions.Logging.LogLevel.Trace);
      })
      .UseNLog();  // NLog: Setup NLog for Dependency injection

Now I want to use the (combined) appsettings to configure nlog as outlined here, but how do I do this AFTER I've loaded my custom config settings?

2 Answers

You can load appsettings before CreateHostBuilder by calling LoadConfigurationFromAppSettings():

using NLog;
using NLog.Web;

public static void Main(string[] args)
{
    var logger = LogManager.Setup()
                           .LoadConfigurationFromAppSettings()
                           .GetCurrentClassLogger();
    try
    {
        logger.Debug("init main");
        CreateHostBuilder(args).Build().Run();
    }
    catch (Exception exception)
    {
        logger.Error(exception, "Stopped program because of exception");
        throw;
    }
    finally
    {
        NLog.LogManager.Shutdown();
    }
}

See also: https://github.com/NLog/NLog.Web/blob/master/examples/ASP.NET%20Core%203/ASP.NET%20Core%203%20-%20VS2019/Program.cs

You can obtain the configuration (including your customsettings.json) during the host building process (in ConfigureServices()), and use it to configure NLog.

To simplify/avoid scoping issues for the variable used to store the configuration, I moved the CreateHostBuilder() method in Main() body:

public static void Main(string[] args)
{
    NLog.Logger theLogger = null;
    try
    {
        Microsoft.Extensions.Configuration.IConfiguration theConfig = null;

        var theHostBuilder = Host.CreateDefaultBuilder(args)
             .ConfigureAppConfiguration((hostingContext, config) =>
             {
                 // add custom config file
                 config.AddJsonFile("customsettings.json", optional: true, reloadOnChange: true);
             })
            .ConfigureServices((hostContext, services) =>
            {
                // store the configuration (includes your 'customsettings.json') in a variable
                theConfig = hostContext.Configuration;
            })
            .ConfigureLogging(l =>
            {
                l.ClearProviders();
                l.SetMinimumLevel(Microsoft.Extensions.Logging.LogLevel.Trace);
            })
            .UseNLog();

        // Build the host (actually executes the lambdas in .ConfigureAppConfiguration, .ConfigureServices, etc.)
        var theHost = theHostBuilder.Build();

        // configure NLog using the configuration obtained above
        NLog.LogManager.Configuration = new NLog.Extensions.Logging.NLogLoggingConfiguration(theConfig.GetSection("NLog"));
        
        // obtain the logger
        theLogger = NLog.LogManager.GetCurrentClassLogger();

        theHost.Run();
    }
    catch (Exception ex)
    {
        // if the logger could be obtained, log the exception
        theLogger?.Error(ex, "Exception!");
    }
    finally
    {
        NLog.LogManager.Shutdown();
    }
}

I got the idea from here

Related