2014-12-03 2 views
11

Я использую 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: Это то, что я пытаюсь для того чтобы достигнуть:

На старте приложения

  1. Создает файл журнала с именем файла в формате "yyyy-MM-dd hh.mm.ss".txt, используя текущий штамп времени (Пример -> «2014-04-29 11: 11: 11.txt»)
  2. Приложение регистрируется в этом файле в течение некоторого времени, пока не будет
    • Становится слишком большим (в течение определенного предела) или
    • архив время истекает (в моем случае, это один день)
  3. Регистратор затем прекращает запись в файл, созданный в 1. ("2014-04 -29 11.11.11.txt ") и не переименовывает его или иным образом не добавляет к нему последовательные/скользящие числа или форматирование даты.
  4. Повторите шаги 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

Я не знаю, если вы можете сделать это с родными раскладками, но это относительно легко реализовать свой собственный 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» добавляет идентификатор процесса в конце имени, может быть полезно отслеживать разные экземпляры с включенными журналами.

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

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

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

<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" /> 

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

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

+0

Меня временно перевели в другой проект. Когда я вернусь к этому проекту через несколько дней, я попробую это и награду щедростью по мере необходимости. – Brandon

+0

Я не могу заставить NLog распознать рендер.Я создаю свою конфигурацию ведения журнала в коде (без файла конфигурации), и когда я применяю строку Layout к 'FileName' моего' FileTarget', я получаю ArgumentException с 'LayoutRenderer не может быть найден: 'CreationDate'' (я переименовал renderer, очевидно) – Brandon

+0

Я понял, как получить NLog для распознавания моего LayoutRenderer ('ConfigurationItemFactory.Default.LayoutRenderers.RegisterDefinition()'), и теперь он работает, однако этот LayoutRenderer делает то же самое, что просто кеширование имени файла. Имя файла никогда не изменяется при его архивировании. – Brandon

0

Проблема заключается в том, что вы используете маску, которая включает в себя HOURS, MINUTES и SECONDS в имени файла. У меня такая же проблема в проходе. Возможно, вам нужно подумать о том, какая реальная польза от наличия ЧАСОВ, МИНУТ и СЕКУНД в имени файла журнала, если у вас есть ежедневный ролловер. Для правильной настройки используйте формат, соответствующий вашим критериям архива. EX: ArchiveEvery = День YYYYMMDD.LOG

ArchiveEvery = Час YYyyMmDd hh.log

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

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

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

Надежда эта помощь

+1

Требование от клиента о том, чтобы их журналы были в формате «yyyy-MM-dd hh.mm.ss»; Они не изменят свое мнение об этом. Нам нужны 2 поведения из-за регистрации данных. – Brandon

+0

OK, нет другого пути :-( – Miguel

3

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

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

С NLog 4.3.9 вы можете настроить «кеш-ключ», чтобы вы могли контролировать, когда кеш должен быть недействительным.

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

filename="${cached:cached=true:Inner=${date:format=yyyy-MM-dd hh.mm.ss}:CacheKey=${shortdate}}.log" 
Смежные вопросы