Почему NLog работает в контроллерах, а не в Program.cs? - PullRequest
1 голос
/ 03 октября 2019

Я добавил NLog в свой проект MVC Core 2.2, и все работает отлично, кроме ведения журнала запуска приложений. Журналы хорошо записаны в контроллерах, но не в Program.cs. Вот мой основной метод, все материалы NLog были взяты из документации NLog:

public static void Main(string[] args)
{
    // NLog: setup the logger first to catch all errors
    var logger = NLogBuilder.ConfigureNLog("nlog.config").GetCurrentClassLogger();
    try
    {
        logger.Info("Starting app");
        CreateWebHostBuilder(args).Build().Run();
    }
    catch (Exception ex)
    {
        // NLog: catch setup errors
        logger.Error(ex, "App failed to start");
        throw;
    }
    finally
    {
        // Ensure to flush and stop internal timers/threads before application-exit (Avoid segmentation fault on Linux)
        NLog.LogManager.Shutdown();
    }
}

В собственных журналах NLog показано следующее:

Ошибка Произошла ошибка. Исключение: System.ArgumentException: путь не имеет юридической формы. в NLog.Targets.FileTarget.Write (LogEventInfo logEvent) в NLog.Targets.Target.Write (AsyncLogEventInfo logEvent)

, что странно, потому что журналы впоследствии записываются правильно в пути к файлу, который я определил.

Вот мой nlog.config:

<?xml version="1.0" encoding="utf-8" ?>
<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      autoReload="true"
      internalLogLevel="Info"
      internalLogFile="c:\temp\nlog.log"
      throwConfigExceptions="true">

  <!-- enable asp.net core layout renderers -->
  <extensions>
    <add assembly="NLog.Web.AspNetCore"/>
  </extensions>

  <variable name="logFilePath" value="${configsetting:name=Logging.LogFilePath}"/>

  <targets>
    <target xsi:type="File"
            name="PortailUsagersCore"
            fileName="${logFilePath}"
            layout="${longdate}|${event-properties:item=EventId_Id}|${uppercase:${level}}|${logger}|${message} ${exception:format=tostring}|url: ${aspnet-request-url}|controller: ${aspnet-mvc-controller}|action: ${aspnet-mvc-action}"
            maxArchiveFiles="4"
            archiveNumbering="Rolling"
            archiveAboveSize="2097152" />
  </targets>

  <rules>
    <logger name="*" writeTo="PortailUsagersCore" />
  </rules>
</nlog>

LogFilePath определен в appsettings.json и appsettings.development.json в разделе ведения журнала:

"Logging": {
    "LogFilePath": "C:\\Logs\\Portail\\PortailUsagersCore.log",
    "IncludeScopes": false,
    "LogLevel": {
      "Default": "Trace",
      "Microsoft": "Information"
    }
  }

1 Ответ

1 голос
/ 07 октября 2019

Мне удалось заставить его работать, благодаря предложениям RolfKristensen. Appsettings теперь читается перед инициализацией NLog, поэтому NLog теперь может читать путь к нему в нем. Я использовал ConfigSetting Layout Renderer для извлечения filePath в NLog.config.

string env = Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT");

// Load config file to read LogFilePath
var config = new ConfigurationBuilder()
    .AddJsonFile("appsettings.json", optional: false, reloadOnChange: true)
    .AddJsonFile($"appsettings.{env}.json", optional: true, reloadOnChange: true)
    .Build();

// LogFilePath is read in nlog.config
NLog.GlobalDiagnosticsContext.Set("LogFilePath", config["Logging:LogFilePath"]);

// NLog: setup the logger first to catch all errors
var logger = NLogBuilder.ConfigureNLog("nlog.config").GetCurrentClassLogger();

И в моем NLog.config я использую его следующим образом:

<variable name="logFilePath" value="${gdc:item=LogFilePath}"/>
<targets>
    <target xsi:type="File"
            name="PortailUsagersCore"
            fileName="${logFilePath}"

...