https://blog.csdn.net/szx1999/article/details/50073857

7. 写日志会影响系统性能吗?

写日志必然是会消耗一定资源的,而RollingFileAppender也不是线程安全的。为了减小log4net影响系统性能的嫌疑,我们加入lockingModel参数,使用FileAppender.MinimalLock来减少并发时发生死锁的概率:

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

尽管如此,文件的I/O始终是耗性能的,有没有办法缓存一批日志,然后一次性写入文件呢?BufferingForwardingAppender正是为此而生,我们下章再介绍如何使用它。

https://stackoverflow.com/questions/11319319/log4net-bufferingforwardingappender-performance-issue

I found out the issue.

The BufferingForwardingAppender is inheriting from BufferingAppenderSkeleton (as are other appenders making use of logging events buffering such as AdoNetAppender, RemotingAppender, SmtpAppender ..).

The BufferingAppenderSkeleton is actually buffering logging events before actually delivering them to the target appender once a certain condition is met (buffer full for example).

According to documentation of the LoggingEvent class (representing a logging event, and containing all values (message, threadid ...) of the event) :

Some logging events properties are considered "volatile", that is the values are correct at the time the event is delivered to appenders, but will not be consistent at any time afterwards. If an event is to be stored and the processed at a later time, these volatile values must be fixed bycalling FixVolatileData. There is a performance penalty incurred by calling FixVolatileData but is is essential to maintain data consistency

These "volatile" properties are represented by the FixFlags enumeration containing flags such as Message, ThreadName, UserName, Identity ... so all volatile properties. It also contains the flag "None" (fix no properties), "All" (fix all properties) and "Partial" (fix only a certain predefine dset of properties).

Whem the BufferingAppenderSkeleton is instanciated, by DEFAULT it sets the fixing to "All" meaning that all "volatile" properties should be fixed.

In that context, for each LoggingEvent appended into the BufferingAppenderSkeleton, ALL "volatile" properties will be fixed before the event is inserted in the buffer. This includes the properties Identity (username) and LocationInformation (stack trace) even if these properties are not included in the layout (but I guess it makes some kind of sense if the layout is changed to include these properties at a later time while a buffer has been already been filled with LoggingEvents).

However in my case this really HURTS performance. I am not including the Identity and LocationInformation in my layout and don't plan to (mainly for performance issues)

Now for the solution ...

There are two properties in BufferingAppenderSkeleton which can be used to control the FixFlags flag value of the BufferingAppenderSkeleton (once again by default it is set to "ALL" which is not very nice !). These two properties are Fix (FixFlags type) and OnlyFixPartialEventData (bool type).

For a fine tune of the flag value or to disable all fix, the Fix property should be used. For a specific partial predefined combination of flags (not including Identity or LocationInfo), the OnlyFixPartialEventData can be used instead by setting it to "true".

If I reuse the configuration sample above (in my question), the only change made to the configuration to unleash performance is indicated below:

<appender name="BufferingForwardingAppender" type="log4net.Appender.BufferingForwardingAppender">
<bufferSize value="512" />
<appender-ref ref="RollingLogFileAppender" />
<Fix value="0"/> <!-- Set Fix flag to NONE -->
</appender>

Using this modified configuration, the benchmark code execution presented in my question above, is dropping from approx 14000ms to 230ms (60X faster) ! And if I use <OnlyFixPartialEventData value="true"/> instead of disabling all fix it is taking approx 350ms.

Sadly, this flag is not very well documented (except in the SDK documentation, a little bit) .. so I had to dig deep into log4net sources to find the issue.

This is particularly problematic especially in the "reference" configuration samples, this flag appears nowhere (http://logging.apache.org/log4net/release/config-examples.html). So the samples provided for BufferingForwardingAppender, and AdoNetAppender (and other appenders inheriting from BufferingAppenderSkeleton) will give TERRIBLE performance to users, even if the layout they are using is pretty minimal.

https://www.cnblogs.com/wigis/p/5023229.html

http://www.nimaara.com/2016/01/01/high-performance-logging-log4net/

https://github.com/NimaAra/Easy.Logger

Problems with BufferingForwardingAppender

The BufferingForwardingAppender only flushes its events once the bufferSize is full unless you specify lossy to be true so this means if you have an application producing a single log event every 1 second you would have to wait 512 seconds for the batch to be flushed out. This may not be a problem for you and if it is not then I highly recommend using this forwarder as it has great GC and CPU performance but if you need real-time monitoring of every log entry and a higher throughput then continue reading.

Another point we should be aware of is that this forwarder is not asynchronous it merely batches the events so the application thread(s) producing the log events will be blocked while the buffer is being flushed out.

The solution

Having considered the points above, I thought I could do better so say hello to my little friend AsyncBufferingForwardingAppender.

This buffering forwarder uses a worker thread which batches up and flushes the log events in the background, it also detects if it has been idle meaning if there has not been enough log events to cause the buffer to be flushed it will invoke a manual flush which addresses the problem I mentioned above and since it is developed as a forwarder you can add additional appenders to it for example it can forward the log events to the ConsoleDB or any other appender that you might have all at the same time.

BufferingForwardingAppender in log4net的更多相关文章

  1. log4net的各种Appender配置示例

    Apache log4net™ Config Examples Overview This document presents example configurations for the built ...

  2. Log4net 日志使用介绍

    概述 Log4net 有三个主要组件:loggers,appenders 和 layouts.这三个组件一起工作使得开发者能够根据信息类型和等级(Level)记录信息,以及在运行时控制信息的格式化和信 ...

  3. log4net学习笔记

    一直想找一个好用的日子类,今天偶然的机会看到了log4net这个类库,过来学习一下. log4net是.NET框架下的一个日子类库,官网是http://logging.apache.org/log4n ...

  4. log4net日志组件

    转载:http://www.cnblogs.com/knowledgesea/archive/2012/04/26/2471414.html 一.什么是log4net组件 Log4net是基于.net ...

  5. Apache log4net™ Config Examples

    Overview This document presents example configurations for the built-in appenders. These configurati ...

  6. Log4net 日志

    Log4net 日志使用介绍 概述 Log4net 有三个主要组件:loggers,appenders 和 layouts.这三个组件一起工作使得开发者能够根据信息类型和等级(Level)记录信息,以 ...

  7. log4net性能小探

    初步测试了Log4性能.Appender架构如下. 一般客户端,使用FileAppender,把Log记录在本地磁盘. <lockingModel type="log4net.Appe ...

  8. Log4net_配置

    Log4net 有三个主要组件:loggers,appenders 和 layouts.这三个组件一起工作使得开发者能够根据信息类型和等级(Level)记录信息,以及在运行时控制信息的格式化和信息的写 ...

  9. log4net使用手册

    1. log4net简介 log4net是.Net下一个非常优秀的开源日志记录组件.log4net记录日志的功能非常强大.它可以将日志分不同的等级,以不同的格式,输出到不同的媒介.Java平台下,它还 ...

随机推荐

  1. Laravel5.1 模型--查询作用域

    所谓的查询作用域就是允许你自定义一个查询语句 把它封装成一个方法. 1 定义一个查询作用域 定义查询作用域就是在模型中声明一个scope开头的方法: public function scopeHotA ...

  2. yii 国际化

    http://www.yiichina.com/doc/guide/2.0/tutorial-i18n config/main.php 外层加 'language' => 'en-US', 's ...

  3. [ACM] hdu 3923 Invoker (Poyla计数,高速幂运算,扩展欧几里得或费马小定理)

    Invoker Problem Description On of Vance's favourite hero is Invoker, Kael. As many people knows Kael ...

  4. cocos2d-x学习日志(18) --程序是怎样開始执行与结束?

    问题的由来 怎么样使用 Cocos2d-x 高速开发游戏.方法非常easy,你能够看看其自带的例程,或者从网上搜索教程,执行起第一个HelloWorld,然后在 HelloWorld 里面写相关逻辑代 ...

  5. EditTextView

    package com.egojit.android.sops.views.EditText; import android.content.Context; import android.graph ...

  6. log4j日志文件乱码问题的解决方法

    近日在AIX上用log4j打印日志,出现乱码,经过努力解决问题. 症状:在默认语言非中文(或者说默认语言不支持中文的)的Windows.Linux.Unix上,用log4j打印日志,出现乱码,常见的就 ...

  7. DataTable数据筛选

    DataView view = newDt.DefaultView;view.Sort = "Description asc,replyEnd desc";DataTable ta ...

  8. Hystrix参数说明

    参数配置 参数说明 值 备注 groupKey productStockOpLog group标识,一个group使用一个线程池 commandKey addProductStockOpLog com ...

  9. Unity使用native读取streamingasset里文件

    需求是,使用native方式,读取apk包里的lua代码,读进c#,做解密 一准备unity工程 public class GameMain : MonoBehaviour { public cons ...

  10. recorder.js

    (function (f) { if (typeof exports === "object" && typeof module !== "undefin ...