Переривчаста проблема із заблокованою системою log4net RollingFileAppender


113

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

Під час запуску в розробці та налагодження за допомогою 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>

Як уже згадувалося, ми спостерігаємо це з періодичністю на машинах, але як тільки проблема виникає, вона зберігається.

Відповіді:


172

Спробуйте додати

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

до своєї <appender />стихії. Існує деякий вплив на продуктивність, оскільки це означає, що log4net блокує файл, записує до нього та розблоковує його для кожної операції запису (на відміну від поведінки за замовчуванням, яка набуває та утримує замок протягом тривалого часу).

Одним із наслідків поведінки за замовчуванням є те, що якщо ви використовуєте її під веб-сайтом, який виконується за допомогою декількох робочих процесів, що працюють на одній машині, кожен з них намагатиметься отримати та утримувати цей замок нескінченно, і два з них просто збираюся програти. Зміна моделі блокування на мінімальний замок вирішує цю проблему.

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

Удачі!


Врятувало мені чимало подряпин по голові, чому мій лісоруб працює з перервами. Я додав робочі процеси до пулу програм, так!
RhinoDevX64

Я використовую це в сервісі, і на додаток до цієї зміни, користувач сервісу запускав необхідний дозвіл на написання. Дякую!
LowTide

Велике спасибі, заощадили багато часу.
Сіва

2
Я просто хотів би прочитати файл, але log4net блокується і для читання ... він може блокуватись лише для написання та спільного читання
JobaDiniz

37

Також пам’ятайте про FAQ log4net :

Як отримати декілька процесів для входу в один файл?

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

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

За замовчуванням FileAppender утримує ексклюзивне блокування запису у файлі журналу під час реєстрації. Це запобігає запису інших файлів у файл. Ця модель, як відомо, виходить з ладу (принаймні, в деяких версіях) Mono в Linux і файли журналів можуть бути пошкоджені, як тільки інший процес намагається отримати доступ до файлу журналу.

MinimalLock отримує блокування запису лише під час написання журналу. Це дозволяє безперервно переплутати записи в один і той же файл, хоча і зі значною втратою продуктивності.

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

Якщо ви використовуєте RollingFileAppender, речі стають ще гіршими, оскільки декілька процесів можуть спробувати почати згортання файлу журналу одночасно. RollingFileAppender повністю ігнорує модель блокування під час прокатки файлів, прокатні файли просто не сумісні з цим сценарієм.

Кращою альтернативою є те, щоб ваші процеси увійшли до RemotingAppenders. Використовуючи RemoteLoggingServerPlugin (або IRemoteLoggingSink), процес може отримувати всі події та записувати їх до одного файлу журналу. Один із прикладів показує, як використовувати модуль RemoteLoggingServerPlugin.


6

Якщо у вас є

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

і додати

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

тоді станеться помилка під час прокатки. Перший процес створить новий файл і перейменує поточний файл. Тоді наступний процес зробить те саме і візьме новостворений файл і замінить нещодавно перейменований файл. В результаті чого журнальний журнал за останній день був порожнім.


1
Це справедливо лише тоді, коли декілька процесів мають доступ до одного і того ж прокатувального файлу. Це безпечно в межах одного процесу. hectorcorrea.com/blog/log4net-thread-safe-but-not-process-safe
Майк Чемберлен

@MikeChamberlain Відповідно до ОП (див. Його коментар, щоб відповісти), одночасно працюватимуть кілька працівників, використовуючи log4net для входу. Тому це питання актуальне!
seebiscuit
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.