2012-03-01 63 views
3

當我的應用程序配置NServiceBus,我設立log4net的使用RollingFileAppender在NServiceBus初始化設置一個緩衝區大小爲log4net的

.Log4Net<RollingFileAppender>(x=> 
     { 
       x.AppendToFile = true; 
       x.Threshold = Level.Debug; 
       x.MaxSizeRollBackups = 10; 
       x.RollingStyle = RollingFileAppender.RollingMode.Size; 
       x.File = "c:\\Logs\\log.txt"; 
      }) 

我想刪除緩存測試(通過設置BufferSize = 1

當使用.Log4Net()的擴展時,這可能嗎?

回答

1

最終,緩存是不是問題和解決方案是非常簡單的。它看起來像RollingFileAppender默認情況下使用排他鎖,因此日誌文件在應用程序運行時被鎖定。

在這種情況下此修復程序是設置:LockingModel = new FileAppender.MinimalLock();

更新後的初始化看起來是這樣的:

.Log4Net<RollingFileAppender>(x=> 
     { 
       x.LockingModel = new FileAppender.MinimalLock(); 
       x.Threshold = Level.Debug; 
       x.MaxSizeRollBackups = 10; 
       x.RollingStyle = RollingFileAppender.RollingMode.Size; 
       x.File = "c:\\Logs\\log.txt"; 
      }) 

當我在搜索log4net的文檔進行緩衝解決方案,我於BufferingForwardingAppender絆倒了。這appender包裝提供緩衝服務的非緩衝appender。

這裏是配置會是什麼樣子,如果我想緩存添加到RollingFileAppender進行:

.Log4Net<BufferingForwardingAppender> 
       (x => 
        { 
         x.BufferSize = 50; // number of events to buffer        
         x.AddAppender(new RollingFileAppender() 
              { 
               LockingModel = new FileAppender.MinimalLock(), 
               Layout = new SimpleLayout(), 
               Threshold = Level.Debug, 
               MaxSizeRollBackups = 10, 
               RollingStyle = RollingFileAppender.RollingMode.Size, 
               File = "c:\\Logs\\log.txt", 
               SecurityContext = NullSecurityContext.Instance 
              }); 

        }) 

帕特里克。

2

log4net FileAppender類不提供BufferSize屬性,因此無法直接在配置中或使用該擴展方法對其進行設置。 (該屬性僅由BufferingAppenderSkeleton基類暴露,但不屬於FileAppender類的基類)。

實際上,在log4net代碼庫中進行探測,看起來好像您可以控制FileAppender所使用的緩衝區大小的唯一方法是編寫您自己的LockingModelBase實現。附帶log4net的那些實現,即ExclusiveLockMinimalLock,內部使用一個FileStream構造,使用的爲0x1000默認的緩衝區大小,即4096

有了這樣說,你也許能夠做這樣的事情:

.Log4Net<RollingFileAppender>(x=> 
    { 
      x.AppendToFile = true; 
      x.Threshold = Level.Debug; 
      x.MaxSizeRollBackups = 10; 
      x.RollingStyle = RollingFileAppender.RollingMode.Size; 
      x.File = "c:\\Logs\\log.txt"; 
      x.LockingModel = new MyUnbufferedLockingModel(); 
     }) 

隨着MyUnbufferedLockingModel是這樣的:

public class MyUnbufferedLockingModel : log4net.FileAppender.LockingModelBase 
{ 
    // This is essentially a rip-off of the default 'ExclusiveLock' class, 
    // but when creating the "m_stream", using an explicit buffer size of 1. 
    // Depending on your needs you may want to use the 'MinimalLock' class 
    // instead. 

    private Stream m_stream = null; 

    public override Stream AcquireLock() 
    { 
     return m_stream; 
    } 

    public override void CloseFile() 
    { 
     using (CurrentAppender.SecurityContext.Impersonate(this)) 
     { 
      m_stream.Close(); 
     } 
    } 

    public override void OpenFile(string filename, bool append, Encoding encoding) 
    { 
     try 
     { 
      using (CurrentAppender.SecurityContext.Impersonate(this)) 
      { 
       string directoryName = Path.GetDirectoryName(filename); 
       if (!Directory.Exists(directoryName)) 
       { 
        Directory.CreateDirectory(directoryName); 
       } 
       FileMode mode = append ? FileMode.Append : FileMode.Create; 
       m_stream = new FileStream(filename, mode, FileAccess.Write,  
        FileShare.Read, 
        1 /*BufferSize*/); 
      } 
     } 
     catch (Exception exception) 
     { 
      CurrentAppender.ErrorHandler.Error("Unable to acquire lock on file " + filename + ". " + exception.Message); 
     } 
    } 

    public override void ReleaseLock() 
    { 
    } 
} 
+0

謝謝你的創意答案。你最終指出我的答案,所以我會給你信貸。我還會用我的工作解決方案爲問題創建另一個答案。 – Patrick 2012-03-02 16:23:44

+0

謝謝:-)你應該也接受你自己的答案作爲正確的答案。 – 2012-03-05 05:17:52