Search code examples
datedependency-injectionconfignlog.net-4.8

Subtract from date in NLog configuration


I've configured NLog to archive the log files every day. It works, but the name of the created subdirectory for the archived log files contain the actual date, instead of the archived log's date.

If the current date is 2023.10.26 then NLog should create a subdirectory with name archived-2023.10.25 the first time the software is started on current day.

An important detail is that I don't want to add any date to the log file's name.

My appsettings.json:

{
  "ConnectionStrings": {
    ...
  },
  "Logging": {
    "LogLevel": {
      "Default": "Debug"
    },
    "NLog": {
      "IncludeScopes": true,
      "RemoveLoggerFactoryFilter": true
    }
  },
  "NLog": {
    "autoShutdown": true,
    "autoReload": true,
    "throwConfigExceptions": true,
    "internalLogLevel": "Info",
    "internalLogFile": "c:\\temp\\internal-nlog.txt",
    "extensions": [
      { "assembly": "NLog.Extensions.Logging" }
    ],
    "variables": {
      "logPath": "D:\\Logs"
    },
    "targets": {
      "Info": {
        "type": "File",
        "createDirs": true,
        "layout": "${longdate}|${level:uppercase=true}|${message}",
        "archiveEvery": "Day",
        "archiveFileName": "${logPath}\\Archive\\archived-${date:format=yyyy.MM.dd}\\Info.log",
        "fileName": "${logPath}\\Info.log"
      }
    },
    "rules": [
      {
        "logger": "Info",
        "minLevel": "Trace",
        "writeTo": "Info"
      }
    ]
  }
}

Registering NLog in App.xaml.cs

Microsoft.Extensions.Hosting.Host
    .CreateDefaultBuilder()
    .ConfigureLogging((hostingContext, loggingBuilder) =>
    {
        loggingBuilder.AddNLog(
            new NLogProviderOptions() { ReplaceLoggerFactory = true },
            s => LogManager.Setup().LoadConfigurationFromSection(hostingContext.Configuration).LogFactory);
    })
    .ConfigureServices((hostContext, services) =>
    {
        // adding services
    })
    .Build();

Using a custom layout renderer I could make it work, but I'd rather keep everything in the NLog configuration if possible.


Solution

  • Using version 5.2.5 NLog's dynamic archive mode does not suppport dynamic directory names yet (only file names).

    The only viable way I found was to use a custom layout renderer.

    [LayoutRenderer("archive-directory")]
    public class ArchiveDirectoryLayoutRenderer : LayoutRenderer
    {
        protected override void Append(StringBuilder builder, LogEventInfo logEvent)
        {
            builder.Append(DateTime.Now.AddDays(-1).ToString("yyyy.MM.dd"));
        }
    }