3

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?

Lukas
  • 1,699
  • 1
  • 16
  • 49
user210757
  • 6,996
  • 17
  • 66
  • 115

2 Answers2

0

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

Rolf Kristensen
  • 17,785
  • 1
  • 51
  • 70
  • Unfortunately this doesn't load my customsettings.json file. I am trying to put database connections in a custom appsettings file. I can just mimic "LoadConfigurationFromAppSettings" and add my customsettings.json file, but I'm already doing this in "ConfigureAppConfiguration" and was hoping to just grab the config at this point rather than doing the same thing twice. https://github.com/NLog/NLog.Web/blob/e523cdc6c5a7a479bb473be2c69a66578d7f1f8e/src/NLog.Web.AspNetCore/Config/SetupBuilderExtensions.cs#L25 – user210757 Dec 11 '20 at 15:48
  • seems like I should do this in Startup instead – user210757 Dec 11 '20 at 16:37
  • 1
    If you want logging up and running before having created the HostBuilder, then you need to load config twice. But if you can live without NLog until HostBuilder is running then just remove everything from your main-method except `CreateHostBuilder` and finally `NLog.LogManager.Shutdown()`. – Rolf Kristensen Dec 11 '20 at 23:33
0

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

Formalist
  • 349
  • 3
  • 12