Почему нельзя записывать журнал в файлы при публикации приложения WPF как одного файла - PullRequest
0 голосов
/ 18 июня 2020

Я использую Microsoft.Extensions.Hosting и NLog.Web.AspNetCore в WPF. Приложение работает правильно в режимах Debug и Release, но когда я публикую sh приложение как один файл, я обнаружил, что File target не работает, если fileName использует относительный путь.

Версия NLog : 4.6.8
Платформа :. NET Core 3
Конфигурация NLog

<nlog>
  <targets>
    <default-wrapper xsi:type="BufferingWrapper" bufferSize="100"/>
    <target xsi:type="File" name="file" fileName="logs/${level}-${shortdate}.log" encoding="utf-8"
            layout="${longdate}|${uppercase:${level}}|${logger}|${message} ${exception:format=tostring}" />
  </targets>
  <rules>
    <logger name="*" minlevel="Info" writeTo="file" final="true"/>
  </rules>
</nlog>

Я использую AddNLog для примените эту конфигурацию:

public App()
{
    _host = new HostBuilder()
        .ConfigureLogging(logBuilder =>
        {
            logBuilder.ClearProviders()
            .SetMinimumLevel(LogLevel.Debug)
            .AddNLog("NLog.config");
        })
        .ConfigureServices((hostContext, services) =>
        {
            //...
        }).Build();
}

Показывать MainWindow при запуске приложения:

private void Application_Startup(object sender, StartupEventArgs e)
{
    using var serviceScope = _host.Services.CreateScope();
    var serviceProvider = serviceScope.ServiceProvider;
    _logger = serviceProvider.GetRequiredService<ILogger<App>>();
    SetupExceptionHandling();
    MainWindow mainWindow = serviceProvider.GetRequiredService<MainWindow>();
    mainWindow.Show();
    _logger.LogInformation($"Application startup at {DateTime.Now} successfully");
}

Публикация в виде одного файла и его запуск, журнал успешного запуска в файл не записывается, Но когда я меняю fileName на абсолютный путь, например /logs/${level}-${shortdate}.log или ${level}-${shortdate}.log, журнал может быть записан.

Я пытаюсь настроить его в коде:

var config = new LoggingConfiguration();
var file = new FileTarget("file")
{
    FileName = "logs/${shortdate}-${level}.log",
    Layout = "${longdate}|${uppercase:${level}}|${logger}|${message} ${exception:format=tostring}"
};
config.AddRule(LogLevel.Info, LogLevel.Fatal, new BufferingTargetWrapper(file));
return config;

Но результат все тот же.

Я что-то не так пишу? спасибо за помощь.

1 Ответ

1 голос
/ 18 июня 2020

NLog автоматически добавит к относительному пути к имени файла префикс ${basedir} -layout. См. Также https://github.com/nlog/nlog/wiki/Basedir-Layout-Renderer

К сожалению, Microsoft решила не исправлять AppDomain.BaseDirectory при выполнении Single File Publi sh в NetCore 3.1

Обходной путь - явно указать ${basedir:fixTempDir=true}:

<nlog>
  <targets>
    <default-wrapper xsi:type="BufferingWrapper" bufferSize="100"/>
    <target xsi:type="File" name="file" fileName="${basedir:fixtempdir=true}/logs/${level}-${shortdate}.log" encoding="utf-8"
            layout="${longdate}|${uppercase:${level}}|${logger}|${message} ${exception:format=tostring}" />
  </targets>
  <rules>
    <logger name="*" minlevel="Info" writeTo="file" final="true"/>
  </rules>
</nlog>

Надеюсь, Microsoft исправит иллюзию с помощью NetCore5

...