Как установить fileName NLog на дату начала процесса? - PullRequest
6 голосов
/ 02 марта 2012

Я пытался

<target name="txtFile"
        xsi:type="File"
        fileName="${date:format=yyyy-MM-dd HH-mm-ss}.txt"
        layout="${longdate} ${level} ${message}"/>

но он создает новый файл каждую минуту. Я понимаю, что есть ${processinfo:property=StartTime}, но я не смог отформатировать его. Я попробовал:

${processinfo:property=StartTime:format=yyyy-MM-dd HH-mm-ss}

но это не работает

Ответы [ 2 ]

14 голосов
/ 11 июня 2012

Использование рендерера кэшированных макетов

Для решения, которое не требует кода, используйте Рендерер кэшированных макетов :

<target name="txtFile"
    xsi:type="File"
    fileName="${cached:cached=true:inner=${date:format=yyyy-MM-dd HH-mm-ss}}.txt"
    layout="${longdate} ${level} ${message}"/>

Использование собственного рендера макетов

Решение, приведенное выше, фактически не использует время запуска процесса.Вместо этого он использует время, когда первое сообщение журнала было перенаправлено на эту цель (например, первый журнал в файл).Это может быть проблемой, если, например, вы хотите, чтобы файлы журнала находились в каталоге, который назван в честь времени начала процесса.

В этом случае может использоваться пользовательский рендерер макетов.Добавьте следующий класс в ваш проект:

namespace NLog.LayoutRenderers
{
    using NLog.Config;

    [LayoutRenderer("processstarttime")]
    public class ProcessStartTimeLayoutRenderer : DateLayoutRenderer
    {
        private Process process;

        protected override void InitializeLayoutRenderer()
        {
            base.InitializeLayoutRenderer();
            this.process = Process.GetCurrentProcess();
        }

        protected override void CloseLayoutRenderer()
        {
            if (this.process != null)
            {
                this.process.Close();
                this.process = null;
            }

            base.CloseLayoutRenderer();
        }

        protected override void Append(System.Text.StringBuilder builder, LogEventInfo logEvent)
        {
            if (this.process != null)
            {
                builder.Append(this.process.StartTime.ToString(this.Format, this.Culture));
            }
        }
    }
}

И используйте его следующим образом:

<target name="txtFile"
    xsi:type="File"
    fileName="${processstarttime:format=yyyy-MM-dd HH-mm-ss}.txt"
    layout="${longdate} ${level} ${message}"/>

Это решение основано на Средстве отображения информации процесса .

1 голос
/ 02 марта 2012

Я решаю это путем усиления имени файла из кода.
Вот пример для вашего случая:

FileTarget fileTarget =
    LogManager.Configuration.AllTargets.
        Where( t => t.Name == "txtFile" ).First() as FileTarget;

DateTime Now = DateTime.Now;

fileTarget.FileName =
    string.Format( "{0}.txt", Now.ToString( "yyyy-MM-dd HH-mm-ss" ) );
  • Обратите внимание, что обработка ошибок не включена, вы должны заботиться о ней так, как считаете нужным.
...