简体   繁体   中英

Configuring NLOG with PublishSingleFile option set

I am in a corner now and I am not able to resolve this problem to my satisfaction.

The problems is caused by the use of NLOG in the Program.cs file of an ASP.NET Core 3.0 application when the application is published using the flag PublishSingleFile in the Visual Studio 2019's Publish options dialog with a SelfContained application.

See: Publishing a single file in NET Core 3.0

If I enable this option the publish procedure creates a single file that contains all the required files including the NLOG assembly.
I deploy this standalone executable along with configurations file like appsettings.json and nlog.config in the site's root as well the content folder wwwroot.

The problem arises when a request arrives to start the application. At this point I get an immediate crash at the first line of the main method. After enabling the stdout.log file I can see the reason.

Unhandled exception. System.IO.FileNotFoundException: Failed to load NLog LoggingConfiguration. Searched the following locations:

  • C:\Windows\TEMP.net\MyAPI\11jsrg2n.1ad\nlog.config

File name: 'nlog.config' at NLog.LogFactory.LoadConfiguration(String configFile, Boolean optional) at NLog.LogFactory.LoadConfiguration(String configFile) at NLog.LogManager.LoadConfiguration(String configFile) at NLog.Web.NLogBuilder.ConfigureNLog(String configFileName) at MyAPI.Program.Main(String[] args)

It seems like the whole exe is run from a different directory than the site's root folder.

Of course this happens because the first line in my main method tries to initialize the NLOG assembly.

To complete this question this is the code on my program.cs file

public class Program
{
    public static void Main(string[] args)
    {
        var logger = NLogBuilder.ConfigureNLog("nlog.config").GetCurrentClassLogger();
        try
        {
            logger.Info("----------------------------");
            logger.Info("MyAPI Application Start");
            CreateHostBuilder(args).Build().Run();
        }
        catch (Exception ex)
        {
            logger.Error(ex, "MyAPI stopped on Exception");
            throw;
        }
        finally
        {
            LogManager.Shutdown();
        }
    }

    public static IHostBuilder CreateHostBuilder(string[] args) =>
            Host.CreateDefaultBuilder(args)
            .ConfigureLogging(logging =>
            {
                logging.ClearProviders();
                logging.SetMinimumLevel(Microsoft.Extensions.Logging.LogLevel.Warning);
            })
            .UseNLog()
            .ConfigureWebHostDefaults(webBuilder =>
            {
                webBuilder.UseStartup<Startup>();
            });
}

So, thanks to everyone that followed my explanation and here is the question.

These is a way to configure NLOG in the main method (as well in the Startup code) when the application is published using the PublishSingleFile flag?

I forgot to add that if I publish without this settings everything works fine, thus this problem is not a showstopper, but nevertheless I would like to know if there is a workaround.

If you want NLog.config included/embedded in the single-exe-file, then try to specify this in csproj-file:

<Content Include="nlog.config">
  <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
  <ExcludeFromSingleFile>true</ExcludeFromSingleFile>
  <CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
</Content>

If you want to have NLog.config to be placed externally/outside the single-exe-file. Then try to explicit specify the process-directory:

var processPath = Path.GetDirectoryName(Process.GetCurrentProcess().MainModule.FileName);
var nlogConfigPath = Path.Combine(processPath, "nlog.config");
var logger = NLogBuilder.ConfigureNLog(nlogConfigPath).GetCurrentClassLogger();

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM