简体   繁体   English

Log4Net性能

[英]Log4Net performance

I have written a C# app that runs constantly in a loop and several threads write to a log4net file. 我编写了一个C#应用程序,它在循环中不断运行,并且有几个线程写入log4net文件。

The issue is that the longer the app is running, the more time it takes to complete a loop. 问题是应用程序运行的时间越长,完成循环所需的时间就越长。 I have run a ANTS Performance profiler, and noticed that most of this CPU time is spent logging with log4.net. 我已经运行了一个ANTS性能分析器,并注意到大部分CPU时间花在使用log4.net进行日志记录。

The more verbose the logs the more CPU it uses and after 30 minutes it's using 100% of the CPU. 日志越详细,它使用的CPU越多,30分钟后它使用100%的CPU。 If I disable logging the time taken for a loop remains constant over time. 如果我禁用日志记录,循环所需的时间将随着时间的推移保持不变。 I had a look at Windows Performance Monitor and the Physical Disk is most of the time IDLE. 我看了一下Windows性能监视器,物理磁盘大部分时间都是IDLE。

I have tried to keep my logging to a minimum, but even with relatively low amounts of logging im still experiencing the issue. 我试图将我的日志记录保持在最低限度,但即使记录的数量相对较少,我仍然遇到问题。

Here is a sample of my Log4net.xml configuration file: 以下是我的Log4net.xml配置文件的示例:

<log4net>
  <root>
    <!-- Levels: OFF, DEBUG, INFO, WARN, ERROR, FATAL-->
    <level value="INFO" />
    <appender-ref ref="RollingLogFileAppender" />
  </root>

  <!--Logs to a file-->
  <appender name="RollingLogFileAppender" type="log4net.Appender.RollingFileAppender">
    <file value="c:\\logs\\log-file.txt" />
    <appendToFile value="true" />
    <lockingModel type="log4net.Appender.FileAppender+ExclusiveLock" />
    <rollingStyle value="Composite" />
    <datePattern value="yyyyMMdd" />
    <maxSizeRollBackups value="20" />
    <maximumFileSize value="1MB" />
    <layout type="log4net.Layout.PatternLayout">
      <conversionPattern value="%date [%thread] %-5level %logger %L %M Schdl:[%property{scheduleContext}] Job:[%property{jobContext}] - %message%newline" />
    </layout>
  </appender>
</log4net>

I am using the same logger from every object that logs. 我正在使用记录的每个对象使用相同的记录器。

  log4net.ILog logger;
  log4net.Config.BasicConfigurator.Configure();
  logger = log4net.LogManager.GetLogger(typeof(myProject));

Why would it use more and more CPU the longer it runs? 为什么它运行得越久就会使用越来越多的CPU?

Any advise on how to improve this would be appreciated. 任何关于如何改善这一点的建议将不胜感激。

Are you configuring log4net in every object that logs? 您是否在每个记录对象中配置log4net? It looks like that from your code. 它看起来就像你的代码。 Configuration should be done once per process, eg at startup and then your objects should only have to acquire the logger. 每个进程应该进行一次配置,例如在启动时,然后您的对象应该只需要获取记录器。

For each class that needs to log I usually have the following pattern: 对于需要记录的每个类,我通常具有以下模式:

class SomeClass
{
    private static readonly ILog log = LogManager.GetLogger(typeof(SomeClass));
    ...
}

Using this pattern you will automatically get loggers that are hierarchical according to the namespace and name of the class. 使用此模式,您将根据类的名称空间和名称自动获取分层的记录器。

What are you doing with those Context Properties? 您在使用这些上下文属性做什么? Schdl:[%property{scheduleContext}] Job:[%property{jobContext}] If you assign something more than just a value here (or an object with a simple ToString() method), it can bog down performance. Schdl:[%property{scheduleContext}] Job:[%property{jobContext}]如果你在这里分配的不仅仅是一个值(或者一个带有简单ToString()方法的对象),它可能会降低性能。 See the log4net manual under Active Property Values for an idea of what I'm talking about. 请参阅Active Property Values下的log4net手册,了解我正在谈论的内容。

Peter Lillevold has a good suggestion about configuring log4net only once. Peter Lillevold对于仅配置一次log4net有一个很好的建议。 You can also put the following line in your AssemblyInfo.cs file: 您还可以在AssemblyInfo.cs文件中放入以下行:

[assembly: log4net.Config.XmlConfigurator()]

The following line is easy to cut and paste into any class that does logging: 以下行很容易剪切并粘贴到任何执行日志记录的类中:

private static readonly log4net.ILog _log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);

You also might try turning on log4net internal logging to see what's going on: 您也可以尝试打开log4net内部日志记录,看看发生了什么:

<appSettings>
  <add key="log4net.Internal.Debug" value="true"/>
</appSettings>

(I have never used log4net before so take what I recommend with caution) (我之前从未使用过log4net,所以请谨慎使用我的建议)

You could write an async proxy to log4Net component and log on a dedicated thread. 您可以为log4Net组件编写异步代理并登录专用线程。 You will no longer be blocking your main threads with attempts to write to the logfile. 尝试写入日志文件时,您将不再阻止主线程。

This is all useless if log4net already has an async proxy. 如果log4net已经有异步代理,这一切都没用。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM