Log4net иногда создает два журнала, один пустой

Используя приведенную ниже конфигурацию, примерно в половине случаев я получаю два журнала на один, один пустой. Они отличаются в имени файла на одну секунду (log.2015-03-09_11-50-25 против log.2015-03-09_11-50-26)

Я пытаюсь вести один журнал для каждого запуска консольного приложения.

<log4net>

  <appender name="Log" type="log4net.Appender.FileAppender">
    <file type="log4net.Util.PatternString" value="C:\env\QA\Logs\consoleapp\log.%date{yyyy-MM-dd_HH-mm-ss}.txt"/>
    <appendToFile value="true"/>
    <layout type="log4net.Layout.PatternLayout">
      <conversionPattern value="%date    %message%newline"/>
    </layout>
  </appender>

  <root>
    <level value="INFO"/>
    <appender-ref ref="Log"/>
  </root>
</log4net>

Последний журнал является единственным, который заполняется/записывается.

Почему это происходит? Как это исправить?

РЕДАКТИРОВАТЬ: Оказывается, я создавал второй регистратор в своем коде. Когда создание экземпляра происходило в другую секунду, создавался второй журнал. Приложение работало корректно.


person b15    schedule 09.03.2015    source источник
comment
удалите второй спецификатор в имени файла.   -  person user1666620    schedule 09.03.2015
comment
ваш подход может быть неоптимальным. Попробуйте использовать имя пользователя/pid/что-то еще, уникальное для периода времени, достаточно малого для ваших журналов, в качестве первичного ключа вашего имени файла журнала.   -  person swe    schedule 09.03.2015
comment
Временная метка @swe хороша для имен файлов журналов — позволяет легко читать имена файлов и помещает их в контекст.   -  person user1666620    schedule 09.03.2015
comment
Оказывается, я создавал второй регистратор в своем коде. Когда создание экземпляра происходило в другую секунду, создавался второй журнал. Приложение работало корректно.   -  person b15    schedule 09.03.2015


Ответы (2)


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

<file type="log4net.Util.PatternString" value="C:\env\QA\Logs\consoleapp\log.%date{yyyy-MM-dd_HH-mm-ss}.txt"/>

должно быть

<file type="log4net.Util.PatternString" value="C:\env\QA\Logs\consoleapp\log.%date{yyyy-MM-dd}.txt"/>

На моей последней работе кто-то установил второй спецификатор в имени файла журнала, и производственный сервер был близок к сбою, пытаясь отобразить 150 000 файлов, содержащихся в папке журнала.

Редактировать:

Если вы хотите писать один раз за запуск, вы можете добавить следующее в конфигурацию log4net:

<rollingStyle value="Once" />

и вам возможно нужно установить для атрибута appendToFile значение false.

один файл log4net за запуск

поэтому ваша конфигурация будет выглядеть так:

<appender name="Log" type="log4net.Appender.FileAppender">
    <file type="log4net.Util.PatternString" value="C:\env\QA\Logs\consoleapp\log.%date{yyyy-MM-dd_HH-mm-ss}.txt"/>
    <appendToFile value="false" />    
    <maxSizeRollBackups value="-1" /> <!--infinite-->
    <rollingStyle value="Once" />
    <layout type="log4net.Layout.PatternLayout">
      <conversionPattern value="%date    %message%newline"/>
    </layout>
  </appender>
person user1666620    schedule 09.03.2015
comment
Я не хочу перезаписывать или добавлять к предыдущему журналу. Я хочу отдельный файл для каждого запуска. Ваше предложение приводит к добавлению журнала, если он попадает в тот же день. - person b15; 09.03.2015
comment
Та же проблема, что и в моем исходном сообщении, но заметил, что когда второй файл находится в той же секунде, он все равно создает два, один с добавлением .1 к имени файла. - person b15; 09.03.2015

Я использовал решение user1666620, но все равно получил файл .log.1. Оказывается, в моем файле AssemblyInfo.cs была следующая строка:

[assembly: log4net.Config.XmlConfigurator(Watch = true)]

Удаление приведенной выше строки устранило мою проблему. Кстати, мой program.cs выглядит так:

public static class Program
{
    static Program()
    {
        // Initialize logging
        log4net.Config.XmlConfigurator.Configure();
    }

    private static readonly ILog log =
        LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);

    ...
}
person Nick    schedule 11.11.2015