ปัญหาไฟล์ที่ถูกล็อก 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

นอกจากนี้ควรระวังไฟล์ คำถามที่พบบ่อย 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" />

จากนั้นจะมีข้อผิดพลาดขณะเกิดการหมุน กระบวนการแรกจะสร้างไฟล์ใหม่และเปลี่ยนชื่อไฟล์ปัจจุบัน จากนั้นกระบวนการถัดไปจะทำเช่นเดียวกันและนำไฟล์ที่สร้างขึ้นใหม่และเขียนทับไฟล์ที่เปลี่ยนชื่อใหม่ ส่งผลให้ logfiel สำหรับวันสุดท้ายว่างเปล่า


1
สิ่งนี้จะเกิดขึ้นก็ต่อเมื่อหลายกระบวนการเข้าถึงไฟล์แบบม้วนเดียวกัน ปลอดภัยภายในกระบวนการเดียวกัน hectorcorrea.com/blog/log4net-thread-safe-but-not-process-safe
Mike Chamberlain

@MikeChamberlain ตาม OP (ดูความคิดเห็นของเขาเพื่อตอบ) จะมีคนงานหลายคนทำงานพร้อมกันโดยใช้ log4net เพื่อเข้าสู่ระบบ ดังนั้นประเด็นนี้จึงเป็นเรื่องที่เกี่ยวข้อง!
seebiscuit
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.