2010-03-28 17 views

Trả lời

14

Tôi thực sự tìm thấy một cách để làm điều này trong luồng này:

http://www.l4ndash.com/Log4NetMailArchive/tabid/70/forumid/1/postid/18271/view/topic/Default.aspx

Tôi đã thử nghiệm phương pháp đầu tiên và nó hoạt động. Chỉ trong trường hợp liên kết đó không còn tốt nữa, tôi sẽ tái tạo mã ở đây. Về cơ bản tác giả nói rằng có hai cách để làm điều này.

cách đầu tiên:

Tạo một mô hình khóa mới mà chỉ có được một khóa (và tạo ra các tập tin) nếu ngưỡng thích hợp cho rằng công trình logger.

public class MyLock : log4net.Appender.FileAppender.MinimalLock 
{ 
     public override Stream AcquireLock() 
     { 
      if (CurrentAppender.Threshold == log4net.Core.Level.Off) 
        return null; 

      return base.AcquireLock(); 
     } 
} 

Bây giờ trong tập tin cấu hình, thiết lập các ngưỡng để bắt đầu ra như:

<threshold value="OFF" /> 

và chắc chắn rằng bạn thiết lập LockingModel mới này như bạn mô hình:

<lockingModel type="Namespace.MyLock" /> 

Tôi bằng cách sử dụng này với một appender file lăn.

Phương pháp thứ hai được liệt kê tại liên kết. Tôi đã không thử kỹ thuật này nhưng nó có vẻ là âm thanh kỹ thuật.

+1

Đối với bất cứ ai cố gắng để làm theo câu trả lời, tôi tin rằng câu trả lời của Jon Skeet thực sự là một lời nhận xét về câu trả lời này. –

+1

Bạn có thể mô tả phương pháp thứ 2 là do liên kết không hoạt động hay không. Nó là vô nghĩa để đề cập đến rằng một phương pháp là trên liên kết khi liên kết không còn hoạt động. –

+0

Tôi đã sử dụng kỹ thuật này để tạo NoLock. Tình hình của tôi là tôi đã sử dụng cấu hình tệp nhật ký trong ứng dụng web nhưng thực sự viết cho nó trong một dịch vụ cửa sổ có cấu hình tương tự. Ứng dụng web đã khóa tệp và các loại khóa khác nhau Tối thiểu, InterProcess không giúp được gì. Bây giờ ứng dụng web sử dụng cấu hình log4net để hiển thị tất cả tệp nhật ký cho quản trị viên nhưng không khóa tệp thực sự được sử dụng bởi dịch vụ windows. Rất biết ơn bạn vì câu trả lời này. Tôi lãng phí khoảng 5-6 giờ về điều này. –

3

Vấn đề với cách tiếp cận đó là sau đó nếu tệp tồn tại nhưng chỉ đọc hoặc nằm trong thư mục không tồn tại, bạn sẽ không tìm ra cho đến khi một lỗi khác đã gây ra sự cố. Bạn thực sự muốn tự tin rằng nhật ký đang hoạt động trước khi phần còn lại của ứng dụng bắt đầu.

có thể là cách để thực hiện việc này, nhưng nếu không tôi nghi ngờ rằng đây là lý do.

1

Một phương pháp đó là khá đơn giản được mô tả trong this message of the mailing list archive

Về cơ bản, với log4net, các file log được tạo ra khi các logger được cấu hình. Để cấu hình nó để làm khác là một chút hacky. Giải pháp là trì hoãn việc thực thi cấu hình. Thông điệp trên gợi ý cách làm như sau khi thiết lập các logger:

private static ILog _log = LogManager.GetLogger(typeof(Program)); 
public static ILog Log 
{ 
    get 
    { 
     if(!log4net.LogManager.GetRepository().Configured) 
      log4net.Config.XmlConfigurator.Configure(new FileInfo(AppDomain.CurrentDomain.SetupInformation.ConfigurationFile)); 
     return _log; 
    } 
} 

Tôi thường cấu hình log4net với lắp ráp thuộc tính, mà cấu hình logger tự động (do đó tạo ra các log file), và một getter đơn giản cho đăng nhập:

[assembly: log4net.Config.XmlConfigurator(Watch = true)] 
... 
public static log4net.ILog Log { get { return _log; } } 
private static readonly log4net.ILog _log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); 

Nhưng loại bỏ điều đó và thêm vào trình thu thập ở trên bằng logic bổ sung thay vì giải quyết vấn đề cho tôi.

Lưu ý: nói chung tôi đồng ý rằng trong hầu hết các trường hợp, cách tốt nhất là định cấu hình trình ghi nhật ký và tạo tệp (và thậm chí ghi vào tệp) khi khởi động ứng dụng.

7

Tôi biết đây là câu hỏi cũ nhưng tôi nghĩ điều này có thể hữu ích cho người khác.

Chúng tôi gặp phải tình huống tương tự khi ứng dụng yêu cầu không nên để lại tệp nhật ký trống nếu không xảy ra lỗi.

Chúng tôi giải quyết nó bằng cách tạo ra các lớp tùy chỉnh LockingModel sau:

public class MinimalLockDeleteEmpty : FileAppender.MinimalLock 
{ 
    public override void ReleaseLock() 
    { 
     base.ReleaseLock(); 

     var logFile = new FileInfo(CurrentAppender.File); 
     if (logFile.Exists && logFile.Length <= 0) 
     { 
      logFile.Delete(); 
     } 
    } 
} 

Nó có nguồn gốc từ lớp FileAppender.MinimalLock rằng sẽ phát hành các khóa trên các log file sau khi viết mỗi tin nhắn đăng nhập.

Chúng tôi đã thêm chức năng bổ sung sẽ xóa tệp nhật ký nếu nó vẫn trống sau khi khóa được giải phóng. Nó ngăn không cho ứng dụng rời khỏi tệp nhật ký lỗi trống nếu các ứng dụng chạy và thoát mà không có bất kỳ lỗi nào.

Ưu

  • Nó vẫn sẽ tạo ra một file log trống trong giai đoạn cấu hình của Log4Net, đảm bảo khai thác gỗ được làm việc trước phần còn lại của ứng dụng khởi động. Tuy nhiên, tệp nhật ký sẽ bị xóa ngay lập tức.
  • Nó không yêu cầu bạn tắt đăng nhập tệp cấu hình của bạn bằng cách đặt giá trị ngưỡng thành "TẮT" và hơn, sau này, bật ghi nhật ký theo chương trình trước khi viết sự kiện nhật ký đầu tiên của bạn.

Nhược điểm

  • này rất có thể là một phương pháp chậm trong việc quản lý các file bản ghi của bạn bởi vì phương pháp ReleaseLock, và việc kiểm tra về độ dài tập tin, sẽ được gọi sau khi mỗi sự kiện nhật ký được viết vào tệp nhật ký. Chỉ sử dụng nó khi bạn mong đợi có rất ít lỗi và đó là yêu cầu nghiệp vụ mà tệp nhật ký không nên tồn tại khi không có lỗi.
  • Tệp nhật ký được tạo và xóa khi trống. Điều này có thể là một vấn đề nếu bạn có các công cụ khác theo dõi thư mục nhật ký để thay đổi hệ thống tệp. Tuy nhiên, đây không phải là vấn đề trong hoàn cảnh của chúng tôi.
+0

Tôi thích phương pháp này nhiều nhất và con đầu tiên có thể bị suy yếu bằng cách đặt cờ khi tệp chứa dữ liệu để các cuộc gọi tiếp theo tới 'ReleaseLock' sẽ không còn kiểm tra thông tin tệp nữa. – ZoolWay

-2
private static ILog _log = LogManager.GetLogger(typeof(Program)); 
public static ILog Log 
{ 
    get 
    { 
     if(!log4net.LogManager.GetRepository().Configured) 
     log4net.Config.XmlConfigurator.Configure(new FileInfo(AppDomain.CurrentDomain.SetupInformation.ConfigurationFile)); 
     return _log; 
    } 
} 
+0

và? ..... mẫu mã của bạn làm gì liên quan đến câu hỏi? –

0

AcquireLock và ReleaseLock phương pháp làm việc cho tôi, nhưng nó làm phiền tôi rằng các tập tin được tạo/xóa nhiều lần. Đây là một tùy chọn tương tự khác để tắt logger và xóa logfile trống khi chương trình hoàn thành. Chỉ cần gọi RemoveEmptyLogFile khi bạn đang thực hiện đăng nhập.

/// <summary> 
/// Sets the logging level for log4net. 
/// </summary> 
private static void RemoveEmptyLogFile() 
{ 
    //Get the logfilename before we shut it down 
    log4net.Appender.FileAppender rootAppender = (log4net.Appender.FileAppender)((log4net.Repository.Hierarchy.Hierarchy)log4net.LogManager.GetRepository()).Root.Appenders[0]; 
    string filename = rootAppender.File; 

    //Shut down all of the repositories to release lock on logfile 
    log4net.Repository.ILoggerRepository[] repositories = log4net.LogManager.GetAllRepositories(); 
    foreach (log4net.Repository.ILoggerRepository repository in repositories) 
    { 
    repository.Shutdown(); 
    } 

    //Delete log file if it's empty 
    var f = new FileInfo(filename); 
    if (f.Exists && f.Length <= 0) 
    { 
    f.Delete(); 
    } 
} // RemoveEmptyLogFile 
3

Sau đây gọi cho OpenFile() xảy ra khi nhật ký được định cấu hình. Các cuộc gọi tiếp theo là khi thông điệp nhật ký thực được tạo.

class CustomFileAppender : RollingFileAppender 
{ 
    private bool isFirstTime = true; 
    protected override void OpenFile(string fileName, bool append) 
    { 
     if (isFirstTime) 
     { 
      isFirstTime = false; 
      return; 
     } 

     base.OpenFile(fileName, append); 
    } 

}

Và trong tập tin cấu hình, thay đổi appender

<log4net> 
<appender name="RollingFile" type="<your namespace>.CustomFileAppender"> 
... 
</log4net> 

Trình tự từ nguồn log4net là như sau:


  • Cuộc gọi đầu tiên OpenFile() là vì ActivateOptions() được gọi từ FileAp pender của nhà xây dựng.
  • Khi thông điệp tường trình được tạo, AppAppSkeleton's DoAppend() gọi PreAppendCheck()
  • PreAppendCheck() bị ghi đè trong TextWriterAppender, cơ sở của FileAppender.
  • PreAppendCheck() gọi là ảo PrepareWriter nếu tệp chưa được mở.
  • PrepareWriter() của FileAppender gọi SafeOpenFile() mà inturn gọi OpenFile()
Các vấn đề liên quan