Использование NLog в качестве регистратора файлов опрокидывания

Как - если возможно - могу ли я использовать NLog в качестве регистратора файлов опрокидывания? как будто:

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

Ответы

Ответ 1

Наконец, я установил архивирование файлов на основе размера. Я использую трюк, чтобы назвать файл после дня месяца, и мне понадобилось архивирование файлов на основе размера, потому что оно действительно помогает, когда вы вступаете в журнал, выходят за рамки нескольких сотен мегабайт. Это помогает сделать, например, 20 Мбайт кусков журнала, поэтому можно легко взглянуть на него с помощью легкого инструмента, такого как Notepad ++.

Он работает уже почти год. Вот упрощенная версия моего файла NLog.config:

<?xml version="1.0" encoding="utf-8" ?>
<nlog autoReload="true" throwExceptions="true"
      xmlns="http://www.nlog-project.org/schemas/NLog.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <variable name="LogDir" value="${specialfolder:folder=MyDocuments}/MyApp/Log"/>
  <variable name="LogDay" value="${date:format=dd}"/>
  <targets>
    <target name="LogTarget1" xsi:type="File" fileName="${LogDir}/${LogDay}.log" encoding="utf-8"
        maxArchiveFiles="10" archiveNumbering="Sequence" archiveAboveSize="1048576" archiveFileName="${LogDir}/{#######}.a" />
  </targets>
  <rules>
    <logger name="AppLog" writeTo="LogTarget1" />
  </rules>
</nlog>

Эта конфигурация делает файл журнала 1 МБ за каждый день месяца и хранит не более 10 архивных 1 МБ логов в папке My Documents\MyApp\Log; например 29.log, 30.log и 31.log.

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

<?xml version="1.0" encoding="utf-8" ?>
<nlog autoReload="true" throwExceptions="true" internalLogFile="nlog-internals.log"
      xmlns="http://www.nlog-project.org/schemas/NLog.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <variable name="LogHome" value="${basedir}/Log"/>
  <variable name="DailyDir" value="${LogHome}/${date:format=yyyy}/${date:format=MM}/${date:format=dd}"/>
  <variable name="HourlyArchive" value="${DailyDir}/${date:format=HH}-Archive/${level}-${logger}-{#######}-archived.a"/>
  <variable name="AppLogPath" value="${DailyDir}/${level}-${logger}.log"/>
  <variable name="DataLogPath" value="${DailyDir}/_data/inouts-${shortdate}.log"/>
  <variable name="EventSource" value="Application" />
  <targets>
    <target name="AppAsyncTarget" xsi:type="AsyncWrapper">
      <target xsi:type="RetryingWrapper" retryDelayMilliseconds="3000" retryCount="10">
        <target xsi:type="File" fileName="${AppLogPath}" encoding="utf-8"
            maxArchiveFiles="50" archiveNumbering="Sequence" archiveAboveSize="1048576" archiveFileName="${HourlyArchive}"
            layout="`${longdate}`${level}`${message}" />
      </target>
    </target>
    <target name="DataAsyncTarget" xsi:type="AsyncWrapper">
      <target xsi:type="RetryingWrapper" retryDelayMilliseconds="1500" retryCount="300">
        <target xsi:type="File" fileName="${DataLogPath}" encoding="utf-8"
            layout="`${longdate}`${message}" />
      </target>
    </target>
    <target name="EventLogAsyncTarget" xsi:type="AsyncWrapper">
      <target xsi:type="RetryingWrapper">
        <target xsi:type="EventLog" source="${EventSource}" machineName="." />
      </target>
    </target>
  </targets>
  <rules>
    <logger name="Data" writeTo="DataAsyncTarget" final="true" />
    <logger name="Event" writeTo="EventLogAsyncTarget" final="true" />
    <logger name="*" writeTo="AppAsyncTarget" />
  </rules>
</nlog>

И в каждом классе, который я хочу использовать для ведения журнала, я помещаю это:

static readonly Logger SlotClassLogger = LogManager.GetCurrentClassLogger();
static Logger ClassLogger { get { return SlotClassLogger; } }

Два дополнительных регистратора предназначены для ежедневного сбора данных и записи в журнал событий Windows; которые являются регистраторами приложений:

public static Logger DataLog { get; private set; }
public static Logger AppEventLog { get; private set; }

И они должны быть инициализированы при запуске приложения:

DataLog = LogManager.GetLogger("Data");
AppEventLog = LogManager.GetLogger("Event");

Примечание. Иногда при выходе из приложения вы получаете исключение, созданное NLog. Это потому, что что-то, что не инициализировано, не может быть утилизировано! Вы только что пишете пустую запись в свой регистратор при запуске приложения, скажем:

DataLog.Info(string.Empty);

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

Ответ 2

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

  • Подсказка к новому имени файла каждый день (помните часовой пояс, возможно, день UTC?)
  • Удаление старых файлов журнала

По моему опыту было бы целесообразно сохранить дату в имени файла журнала, например.

debug-2010-06-08.log

Эта часть должна быть простой с NLog, с учетом примеров в документах.

Теперь вторая часть может быть легко выполнена во втором потоке или, возможно, даже в совершенно другом процессе - просто нужно посмотреть, сколько файлов присутствует, и при необходимости удалить самые старые. Поиск "самого старого" должен быть легким, если дата указана в имени файла, даже если вы не хотите доверять информации о файловой системе.

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