Sự cố tệp bị khóa log4net RollingFileAppender gián đoạn


113

Chúng tôi đang gặp sự cố không liên tục trên các máy phát triển và sản xuất, theo đó các tệp nhật ký của chúng tôi không được đăng nhập.

Khi chạy trong quá trình phát triển và gỡ lỗi bằng Visual Studio, chúng tôi nhận được thông báo lỗi log4net sau trong cửa sổ đầu ra VS:

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

Quá trình không thể truy cập tệp 'C: \ folder \ file.log' vì nó đang được sử dụng bởi một quá trình khác.

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.

Phần cấu hình sẽ giống như sau:

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

Giải pháp hiện tại của chúng tôi cho vấn đề này là đổi tên tệp nhật ký cuối cùng. Tất nhiên, chúng tôi sẽ mong đợi điều này không thành công (do khóa tệp nói trên), nhưng nó thường không. Một hoặc hai lần việc đổi tên không thành công do bị khóa từ quá trình aspnet_wp.exe .

Phần cấu hình log4net của chúng tôi được hiển thị bên dưới:

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

Như đã đề cập, chúng tôi thấy điều này không liên tục trên máy, nhưng khi sự cố xảy ra, nó vẫn tiếp diễn.

Câu trả lời:


172

Thử thêm

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

cho <appender />phần tử của bạn . Có một số tác động đến hiệu suất bởi vì điều này có nghĩa là log4net sẽ khóa tệp, ghi vào tệp và mở khóa tệp cho mỗi thao tác ghi (trái ngược với hành vi mặc định, thu nhận và giữ khóa trong một thời gian dài).

Một ngụ ý của hành vi mặc định là nếu bạn đang sử dụng nó trong một trang Web đang được thực thi theo nhiều quy trình công nhân đang chạy trên cùng một máy, mỗi quy trình sẽ cố gắng lấy và giữ khóa đó vô thời hạn, và hai trong số đó là chỉ sẽ thua. Thay đổi kiểu khóa thành khóa tối thiểu sẽ giải quyết được vấn đề này.

(Khi gỡ lỗi, các kết thúc không theo quy trình và quay vòng nhiều quy trình công nhân mới chính xác là loại điều có khả năng xảy ra.)

Chúc may mắn!


Tôi đã tiết kiệm cho tôi rất nhiều đau đầu về lý do tại sao máy ghi nhật ký của tôi hoạt động không liên tục. Tôi đã thêm các quy trình công nhân vào nhóm ứng dụng, duh!
RhinoDevX64

Tôi đang sử dụng điều này trong một dịch vụ và ngoài thay đổi này, người dùng dịch vụ cũng chạy khi cần quyền để viết. Cảm ơn!
LowTide

Cảm ơn rất nhiều, đã tiết kiệm rất nhiều thời gian.
Siva

2
Tôi chỉ muốn để đọc các tập tin, nhưng log4net khóa để đọc cũng ... nó có thể khóa chỉ để viết và đọc phần
JobaDiniz

37

Cũng cần lưu ý về Câu hỏi thường gặp về log4net :

Làm cách nào để nhận được nhiều quá trình để đăng nhập vào cùng một tệp?

Trước khi bạn bắt đầu thử bất kỳ giải pháp thay thế nào được cung cấp, hãy tự hỏi bản thân xem bạn có thực sự cần ghi nhật ký nhiều quy trình vào cùng một tệp hay không, sau đó đừng làm điều đó ;-).

FileAppender cung cấp các mô hình khóa có thể cắm được cho tiện ích này nhưng tất cả các triển khai hiện tại đều có vấn đề và nhược điểm.

Theo mặc định, FileAppender giữ một khóa ghi độc quyền trên tệp nhật ký khi nó đang ghi nhật ký. Điều này ngăn các quy trình khác ghi vào tệp. Mô hình này được biết là bị hỏng với (ít nhất là trên một số phiên bản của) Mono trên Linux và các tệp nhật ký có thể bị hỏng ngay khi một quy trình khác cố gắng truy cập tệp nhật ký.

MinimalLock chỉ có được khóa ghi khi nhật ký đang được ghi. Điều này cho phép nhiều quy trình xen kẽ ghi vào cùng một tệp, mặc dù có sự mất mát đáng kể về hiệu suất.

InterProcessLock hoàn toàn không khóa tệp nhưng đồng bộ hóa bằng Mutex trên toàn hệ thống. Điều này sẽ chỉ hoạt động nếu tất cả các quy trình hợp tác (và sử dụng cùng một mô hình khóa). Việc mua lại và phát hành Mutex cho mọi mục nhập nhật ký được ghi sẽ dẫn đến mất hiệu suất, nhưng Mutex thích hợp hơn khi sử dụng MinimalLock.

Nếu bạn sử dụng RollingFileAppender, mọi thứ thậm chí còn trở nên tồi tệ hơn vì một số quá trình có thể cố gắng bắt đầu cuộn tệp nhật ký đồng thời. RollingFileAppender hoàn toàn bỏ qua mô hình khóa khi cuộn tệp, tệp cuộn chỉ đơn giản là không tương thích với kịch bản này.

Một giải pháp thay thế tốt hơn là để các quy trình của bạn đăng nhập vào RemotingAppenders. Sử dụng RemoteLoggingServerPlugin (hoặc IRemoteLoggingSink) một quy trình có thể nhận tất cả các sự kiện và ghi chúng vào một tệp nhật ký duy nhất. Một trong những ví dụ cho thấy cách sử dụng RemoteLoggingServerPlugin.


6

Nếu bạn có

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

và thêm

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

sau đó sẽ có một lỗi trong khi lăn xảy ra. Quá trình đầu tiên sẽ tạo tệp mới và đổi tên tệp hiện tại. Sau đó, các proces tiếp theo sẽ thực hiện tương tự và lấy tệp mới tạo và ghi đè lên tệp mới được đổi tên. Dẫn đến logfiel của ngày cuối cùng bị trống.


1
Điều này chỉ đúng khi nhiều quy trình đang truy cập vào cùng một tệp cuộn. Nó an toàn trong cùng một quá trình. hectorcorrea.com/blog/log4net-thread-safe-but-not-process-safe
Mike Chamberlain

@MikeChamberlain Theo OP (Xem bình luận của anh ấy để trả lời) sẽ có nhiều công nhân làm việc đồng thời, sử dụng log4net để ghi nhật ký. Do đó vấn đề này là thích hợp!
seebiscuit
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.