【问题标题】:Setting a BufferSize for Log4Net in NServiceBus Initialization在 NServiceBus 初始化中为 Log4Net 设置 BufferSize
【发布时间】:2012-03-03 00:33:06
【问题描述】:

在我的应用程序中配置 NServiceBus 时,我将 Log4Net 设置为使用 RollingFileAppender:

 .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() 扩展时这可能吗?

【问题讨论】:

    标签: log4net nservicebus


    【解决方案1】:

    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()
        {
        }
     }
    

    【讨论】:

    • 感谢您的创意回答。你最终把我指向了答案,所以我会给你信用。我还将使用我的工作解决方案为该问题创建另一个答案。
    • 谢谢 :-) 你也应该接受你自己的答案作为正确的答案。
    【解决方案2】:

    最后,缓冲不是问题,解决方案非常简单。看起来 RollingFileAppender 默认使用排他锁,因此日志文件在应用程序运行时被锁定。

    在这种情况下的修复是设置:LockingModel = new FileAppender.MinimalLock();

    更新后的 init 如下所示:

    .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
                                               });
    
                         })
    

    帕特里克。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-01-18
      • 2013-07-13
      • 2023-03-29
      • 2014-09-01
      • 1970-01-01
      • 2012-11-05
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多