Создайте файл NLog с текущей датой и временем без его кеширования, сохраняя имя файла архива одинаковым

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

Я создаю конфигурации ведения журнала в коде (я пишу обертку, чтобы выставить некоторые конкретные функции), и у меня есть объект FileTarget, созданный с помощью этих параметров:

this._fileTarget.FileName = "${date:format=yyyy-MM-dd hh.mm.ss}.log";
this._fileTarget.ArchiveAboveSize = Math.Pow(1024, 2) * 5; //5MB
this._fileTarget.ArchiveNumbering = ArchiveNumberingMode.Date;
this._fileTarget.ArchiveEvery = FileArchivePeriod.Day;
this._fileTarget.ArchiveDateFormat = "yyyy-MM-dd hh.mm.ss";

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

Я добавил кэшированную целевую оболочку к имени файла как таковой:

this._fileTarget.FileName = "${cached:cached=true:inner=${date:format=yyyy-MM-dd hh.mm.ss}.log}";

Но все, что покупает меня, - это имя файла, которое теперь никогда не изменяется и выглядит так, когда оно архивировано

2014-12-03 12.00.00.2014-12-03 12.00.00.log
2014-12-03 12.00.00.2014-12-03 12.10.00.log
etc...

Можно ли указать NLog только архивировать файлы на основе размера и даты файла и игнорировать нумерацию архивов и форматирование даты? Я пытаюсь создать файлы журналов, имя которых является меткой времени, когда оно было создано, где новые файлы создаются только определенного размера или каждый день.

Edit: Это то, что я пытаюсь добиться:

При запуске приложения

  • Создает файл журнала с именем файла в формате "yyyy-MM-dd hh.mm.ss".txt с использованием текущей метки времени (Пример → "2014-04-29 11:11:11.txt" )
  • Приложение регистрируется в этом файле некоторое время, пока оно не будет
    • Становится слишком большим (над определенным лимитом) или
    • Время архива истекает (в моем случае это один день)
  • Затем регистратор прекращает запись в файл, созданный в 1. ( "2014-04-29 11.11.11.txt" ) и не переименовывает его или иным образом не добавляет к нему последовательные/скользящие номера или форматирование даты.
  • Повторяйте шаги 1-3 до конца времени.

Оставив меня с папкой журнала, которая выглядит так:

Logs
|
|> 2014-12-10 12:50:50.txt    (1024 kb)
|> 2014-12-10 12:50:55.txt    (1020 kb)
|> 2014-12-10 12:51:01.txt    (1024 kb)
|> 2014-12-10 12:51:10.txt    (1003 kb)  
|> 2014-12-10 12:51:20.txt    (400 kb)  <-The currently active log file.

Ответ 1

Это старый вопрос, но в этом случае есть некоторые улучшения.

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

Так как NLog 4.3.9 вы можете настроить "cachekey", чтобы вы могли контролировать, когда кеш должен быть заблокирован.

В этом случае следующая конфигурация дает вам дату и в имени файла, но только 1 файл каждый день. Время в имени файла будет временем первого события журнала за этот день.

filename="${cached:cached=true:Inner=${date:format=yyyy-MM-dd hh.mm.ss}:CacheKey=${shortdate}}.log"

Ответ 2

Я не знаю, можете ли вы сделать это с помощью собственных макетов, но относительно легко реализовать собственный LayoutRenderer для достижения этого.

Я сделал кое-что довольно близко к тому, что вы хотите несколько раз назад:

    [LayoutRenderer("UniqueName")]
    public class UniqueNameLayoutRenderer : LayoutRenderer
    {
        #region Fields (1)

        private string _constantName;

        #endregion Fields

        #region Enums (1)

        public enum PatternType
        {
            /// <summary>
            /// Long date + current process ID
            /// </summary>
            LongDateAndPID,
            /// <summary>
            /// Long date (including ms)
            /// </summary>
            LongDate,
        }

        #endregion Enums

        #region Properties (2)

        public string ConstantName
        {
            get
            {
                if (_constantName == null)
                {
                    if (Format == PatternType.LongDateAndPID)
                    {
                        string pid;
                        try
                        {
                            pid = Process.GetCurrentProcess().Id.ToString(CultureInfo.InvariantCulture);
                        }
                        catch
                        {
                            pid = "000"; 
                        }

                        _constantName = DateTime.Now.ToString("yyyy-MM-dd_HHmmss-ffff") + "_pid" + pid;
                    }
                    else if (Format == PatternType.LongDate)
                    {
                        _constantName = DateTime.Now.ToString("yyyy-MM-dd_HHmmss-ffff");
                    }
                }

                return _constantName;
            }
        }

        [DefaultParameter]
        public PatternType Format { get; set; }

        #endregion Properties

        #region Methods (2)

        // Protected Methods (1) 

        protected override void Append(StringBuilder builder, LogEventInfo logEvent)
        {
            builder.Append(ConstantName);
        }
        // Private Methods (1) 

        #endregion Methods
    }
}

Он сгенерирует имя файла при первом вызове с длительным временем и сохранит его до конца выполнения. Я в основном использовал его с NLog 2, но похоже, что он хорошо работает с NLog 3.2.

Он предназначен для использования с

"{UniqueName:format=LongDate}" 

в файле конфигурации NLog, например. "LongDateAndPID" добавляет идентификатор процесса в конце имени, может быть полезно отслеживать разные экземпляры с включенными календарными журналами.

Прежде чем использовать его, вы должны зарегистрировать приложение с помощью:

<extensions><add assembly="MyAssemblyWhichContainsRenderer"/></extensions>

Чтобы использовать его с включенной кативкой, просто используйте что-то вроде этого:

<target xsi:type="File"
        name="logfile"
        fileName="${logDirectory}\logs-${UniqueName:format=LongDateAndPID}.txt"
        layout="${longdate} | ${level:uppercase=true} (${threadid}) | ${callsite} : ${message} ${exception:format=ToString}"
        archiveFileName="${logDirectory}\logs-${UniqueName:format=LongDateAndPID}_{##}.txt"
        archiveAboveSize="25165824"
        concurrentWrites="false"
        archiveNumbering="Sequence"
        maxArchiveFiles="99999" />

(конечно, это только пример)

Не стесняйтесь адаптировать средство визуализации макета к вашим собственным потребностям.

Ответ 3

Проблема заключается в том, что вы используете маску, которая включает HOURS, MINUTES и SECONDS в имени файла. У меня такая же проблема в проходе. Вероятно, вам нужно подумать о том, какова реальная выгода за то, что у HOURS, MINUTES и SECONDS есть имя файла журнала, если у вас есть ежедневный ролловер. Для правильной настройки используйте формат, соответствующий критериям вашего архива. EX: ArchiveEvery = День YYYYMMDD.LOG

ArchiveEvery = Hour yyyyMMdd hh.log

ArchiveEvery = минуту yyyyMMdd hh.mm.log

С другой стороны: действительно ли вам нужно сочетание двух типов поведения для архивации?

Если ответ "ДА", продолжайте и реализуйте свое собственное приложение, как говорится в другом сообщении. Else попробуйте скопировать файлы каждый час, это будет держать ваши файлы вялеными.

Надеемся на эту помощь