at the risk of sounding quick and dirty, I do normally initialize NLog twice. Once in at the beginning of Main() to capture startup errors (ie):
var nlogEnvironment = Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT");
LogManager.LoadConfiguration(nlogEnvironment == "" ? "nlog.config" : $"nlog.{nlogEnvironment}.config");
var logger = LogManager.GetCurrentClassLogger();
and then again using the cleanest method for either Generic Host (HostBuilder)(My preference since netcore seems to be shifting this way in general) or Web Host (WebHostBuilder) both methods are similar, but neither use a Startup or the traditional IAppBuilder, IHostingEnvironment,ConfigureServices pattern.
My warning here is that ASPNETCORE_ENVIRONMENT is unpredictable. For example, it's not even set on my machine. It can be set manually in the environment, set via command line arg, in an IIS config, or App/Site configs (among other places). Let me specify: It's unpredictable that early. You can specify programmatically which sources you read the setting from and in what order to respect them when you're configuring services, but not before you start to configure the host. See my example below:
Hence, I wrap it in #if(DEBUG). The idea is that you Do as little as possible in Main() and you should not have to rely on logging before your host is configured. If something goes wrong in your configured services, your logger is already started before even the host starts (remember that everything you do is just configuration, telling the host how it's going to start up. Nothing actually "happens" until you build and then run your host.) (admittedly this only really applies to netcore 2.x)
Disclaimer: I'm no expert and all of this could just sound like nonsense to you; If so, I apologize. I err on the side of wordy code for clarity rather than low line count. I code like I picture software components behaving in my head. It helps when I'm tasked with containerizing things that were never meant to be containerized.
Top comments (0)