Периодическая проблема с заблокированным файлом log4net RollingFileAppender

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

При запуске разработки и отладки с помощью Visual Studio мы получаем следующие сообщения об ошибках log4net в окне вывода VS:

log4net:ERROR [RollingFileAppender] Unable to acquire lock on file C:\folder\file.log.

Процесс не может получить доступ к файлу «C: \ folder \ file.log», поскольку он используется другим процессом.

log4net:ERROR XmlConfigurator: Failed to find configuration section 'log4net' in the application's .config file.
Check your .config file for the <log4net> and <configSections> elements.

Раздел конфигурации должен выглядеть так:

<section
  name="log4net"
  type="log4net.Config.Log4NetConfigurationSectionHandler,log4net" />

Наше текущее решение проблемы - переименовать последний файл журнала. Мы, конечно, ожидаем, что это не удастся (из-за вышеупомянутой блокировки файла), но обычно этого не происходит. Один или два раза переименование не удавалось из-за блокировки процесса aspnet_wp.exe.

Наш раздел конфигурации log4net показан ниже:

<log4net>
  <appender name="RollingLogFileAppender" type="log4net.Appender.RollingFileAppender">
    <file value="C:\folder\file.log"/>
    <appendToFile value="true" />
    <datePattern value="yyyyMMdd" />
    <rollingStyle value="Date" />
    <maximumFileSize value="10MB" />
    <maxSizeRollBackups value="100" />
    <layout type="log4net.Layout.PatternLayout">
      <header value="[Header]&#xA;"/>
      <footer value="[Footer]&#xA;"/>
      <conversionPattern value="%date %-5level %logger ${COMPUTERNAME} %property{UserHostAddress} [%property{SessionID}] - %message%newline"/>
    </layout>
  </appender>
  <root>
    <level value="INFO"/>
    <appender-ref ref="RollingLogFileAppender"/>
  </root>
</log4net>

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


person Richard Ev    schedule 04.01.2010    source источник


Ответы (3)


Попробуйте добавить

<lockingModel type="log4net.Appender.FileAppender+MinimalLock" />

к вашему <appender /> элементу. Это оказывает некоторое влияние на производительность, потому что это означает, что log4net будет блокировать файл, записывать в него и разблокировать его для каждой операции записи (в отличие от поведения по умолчанию, которое устанавливает и удерживает блокировку в течение длительного времени).

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

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

Удачи!

person Nicholas Piasecki    schedule 04.01.2010
comment
Избавило меня от головной боли по поводу того, почему мой регистратор работал с перебоями. Я добавил рабочие процессы в пул приложений, да! - person RhinoDevX64; 20.03.2012
comment
Я использую это в службе, и в дополнение к этому изменению пользователь, выполняющий службу, также имел необходимое разрешение на запись. Спасибо! - person LowTide; 04.06.2012
comment
Я просто хотел бы прочитать файл, но log4net также блокирует чтение ... он может блокироваться только для записи и совместного чтения - person JobaDiniz; 12.04.2019

Также обратите внимание на часто задаваемые вопросы по log4net:

Как заставить несколько процессов регистрироваться в одном файле?

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

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

По умолчанию FileAppender удерживает исключительную блокировку записи в файл журнала во время его ведения. Это предотвращает запись в файл другими процессами. Эта модель, как известно, не работает (по крайней мере, в некоторых версиях) Mono в Linux, и файлы журнала могут быть повреждены, как только другой процесс попытается получить доступ к файлу журнала.

MinimalLock получает блокировку записи только во время записи журнала. Это позволяет нескольким процессам чередовать записи в один и тот же файл, хотя и со значительной потерей производительности.

InterProcessLock вообще не блокирует файл, а синхронизирует его с помощью общесистемного Mutex. Это будет работать только в том случае, если все процессы взаимодействуют (и используют одну и ту же модель блокировки). Получение и освобождение Mutex для каждой записи журнала, которая должна быть записана, приведет к потере производительности, но Mutex предпочтительнее использования MinimalLock.

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

Лучшая альтернатива - вести журнал процессов в RemotingAppenders. Используя RemoteLoggingServerPlugin (или IRemoteLoggingSink), процесс может получать все события и записывать их в один файл журнала. Один из примеров показывает, как использовать RemoteLoggingServerPlugin.

person Ciprian Teiosanu    schedule 06.06.2013

Если у вас есть

<staticLogFileName value="true" />
<rollingStyle value="Date" />
<datePattern value="yyyyMMdd" />

и добавить

<lockingModel type="log4net.Appender.FileAppender+MinimalLock" />

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

person Jonte    schedule 20.12.2010
comment
Это верно только в том случае, если несколько процессов обращаются к одному и тому же скользящему файлу. Это безопасно в рамках того же процесса. hectorcorrea.com/blog/log4net-thread-safe-but- небезопасно - person Mike Chamberlain; 17.04.2013
comment
@MikeChamberlain Согласно OP (см. Его комментарий для ответа) одновременно будет работать несколько рабочих, использующих log4net для ведения журнала. Поэтому этот вопрос актуален! - person seebiscuit; 27.02.2014