Masalah file terkunci log4net RollingFileAppender terputus-putus

113

Kami melihat masalah terputus-putus pada mesin pengembangan dan produksi yang tidak dapat diakses oleh file log kami.

Saat menjalankan pengembangan dan debugging menggunakan Visual Studio kami mendapatkan pesan galat log4net berikut di jendela keluaran VS:

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

Proses tidak dapat mengakses file 'C: \ folder \ file.log' karena sedang digunakan oleh proses lain.

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.

Bagian konfigurasi akan terlihat seperti ini:

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

Solusi kami saat ini untuk masalah ini adalah dengan mengganti nama file log terakhir. Kami tentu saja berharap ini gagal (karena kunci file yang disebutkan di atas), tetapi biasanya tidak. Sekali atau dua kali penggantian nama gagal karena kunci dari proses aspnet_wp.exe .

Bagian konfigurasi log4net kami ditunjukkan di bawah ini:

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

Seperti yang disebutkan, kami melihat ini sesekali di komputer, tetapi begitu masalah terjadi, masalah tetap ada.

Richard Ev
sumber

Jawaban:

172

Coba tambahkan

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

ke <appender />elemen Anda . Ada beberapa dampak kinerja karena ini berarti bahwa log4net akan mengunci file, menulis padanya, dan membukanya untuk setiap operasi tulis (berlawanan dengan perilaku default, yang memperoleh dan menahan kunci untuk waktu yang lama).

Salah satu implikasi dari perilaku default adalah jika Anda menggunakannya di bawah situs Web yang sedang dijalankan di bawah beberapa proses pengerjaan yang berjalan di mesin yang sama, masing-masing akan mencoba untuk mendapatkan dan memegang kunci itu tanpa batas, dan dua di antaranya adalah hanya akan kalah. Mengubah model penguncian ke kunci minimal dapat mengatasi masalah ini.

(Saat men-debug, penghentian tidak terlacak, dan menjalankan banyak proses pekerja baru adalah jenis hal yang mungkin terjadi.)

Semoga berhasil!

Nicholas Piasecki
sumber
Menyelamatkan saya dari banyak garukan kepala tentang mengapa logger saya bekerja sesekali. Saya menambahkan proses pekerja ke kumpulan aplikasi, ya!
RhinoDevX64
Saya menggunakan ini dalam layanan dan sebagai tambahan untuk perubahan ini, pengguna layanan menjalankan izin yang diperlukan untuk menulis juga. Terima kasih!
LowTide
Terima kasih banyak, Menghemat banyak waktu.
Siva
2
Saya hanya ingin membaca file, tetapi log4net mengunci untuk membaca juga ... itu bisa mengunci hanya untuk menulis dan berbagi bacaan
JobaDiniz
37

Perhatikan juga FAQ log4net :

Bagaimana cara mendapatkan beberapa proses untuk masuk ke file yang sama?

Bahkan sebelum Anda mulai mencoba salah satu alternatif yang disediakan, tanyakan pada diri Anda apakah Anda benar-benar perlu memiliki banyak proses untuk masuk ke file yang sama, lalu jangan lakukan itu ;-).

FileAppender menawarkan model penguncian yang dapat dicolokkan untuk usecase ini tetapi semua implementasi yang ada memiliki masalah dan kekurangan.

Secara default, FileAppender memegang kunci tulis eksklusif pada file log saat sedang melakukan logging. Ini mencegah proses lain untuk menulis ke file. Model ini diketahui rusak dengan (setidaknya pada beberapa versi) Mono di Linux dan file log mungkin rusak segera setelah proses lain mencoba mengakses file log.

MinimalLock hanya memperoleh kunci tulis saat log sedang ditulis. Hal ini memungkinkan beberapa proses untuk menyisipkan penulisan ke file yang sama, meskipun dengan penurunan performa yang cukup besar.

InterProcessLock tidak mengunci file sama sekali tetapi menyinkronkan menggunakan Mutex di seluruh sistem. Ini hanya akan berfungsi jika semua proses bekerja sama (dan menggunakan model penguncian yang sama). Akuisisi dan merilis Mutex untuk setiap entri log yang akan ditulis akan mengakibatkan hilangnya kinerja, tetapi Mutex lebih disukai daripada penggunaan MinimalLock.

Jika Anda menggunakan RollingFileAppender, keadaan menjadi lebih buruk karena beberapa proses mungkin mencoba untuk mulai memutar file log secara bersamaan. RollingFileAppender sepenuhnya mengabaikan model penguncian saat file bergulir, file bergulir sama sekali tidak kompatibel dengan skenario ini.

Alternatif yang lebih baik adalah meminta proses Anda masuk ke RemotingAppenders. Menggunakan RemoteLoggingServerPlugin (atau IRemoteLoggingSink) sebuah proses dapat menerima semua kejadian dan mencatatnya ke satu file log. Salah satu contoh menunjukkan cara menggunakan RemoteLoggingServerPlugin.

Ciprian Teiosanu
sumber
6

Jika Anda memiliki

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

dan tambahkan

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

maka akan terjadi error saat rolling terjadi. Proses pertama akan membuat file baru dan mengganti nama file saat ini. Kemudian proses selanjutnya akan melakukan hal yang sama dan mengambil file yang baru dibuat dan menimpa file yang baru diganti namanya. Menghasilkan logfiel untuk hari terakhir menjadi kosong.

Jonte
sumber
1
Ini benar hanya ketika beberapa proses mengakses file bergulir yang sama. Aman dalam proses yang sama. hectorcorrea.com/blog/log4net-thread-safe-but-not-process-safe
Mike Chamberlain
@MikeChamberlain Menurut OP (Lihat komentarnya untuk menjawab) akan ada beberapa pekerja yang bekerja secara bersamaan, menggunakan log4net untuk log. Oleh karena itu, masalah ini penting!
seebiscuit