BufferingForwardingAppender in log4net
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 Console, DB or any other appender that you might have all at the same time.
BufferingForwardingAppender in log4net的更多相关文章
- log4net的各种Appender配置示例
Apache log4net™ Config Examples Overview This document presents example configurations for the built ...
- Log4net 日志使用介绍
概述 Log4net 有三个主要组件:loggers,appenders 和 layouts.这三个组件一起工作使得开发者能够根据信息类型和等级(Level)记录信息,以及在运行时控制信息的格式化和信 ...
- log4net学习笔记
一直想找一个好用的日子类,今天偶然的机会看到了log4net这个类库,过来学习一下. log4net是.NET框架下的一个日子类库,官网是http://logging.apache.org/log4n ...
- log4net日志组件
转载:http://www.cnblogs.com/knowledgesea/archive/2012/04/26/2471414.html 一.什么是log4net组件 Log4net是基于.net ...
- Apache log4net™ Config Examples
Overview This document presents example configurations for the built-in appenders. These configurati ...
- Log4net 日志
Log4net 日志使用介绍 概述 Log4net 有三个主要组件:loggers,appenders 和 layouts.这三个组件一起工作使得开发者能够根据信息类型和等级(Level)记录信息,以 ...
- log4net性能小探
初步测试了Log4性能.Appender架构如下. 一般客户端,使用FileAppender,把Log记录在本地磁盘. <lockingModel type="log4net.Appe ...
- Log4net_配置
Log4net 有三个主要组件:loggers,appenders 和 layouts.这三个组件一起工作使得开发者能够根据信息类型和等级(Level)记录信息,以及在运行时控制信息的格式化和信息的写 ...
- log4net使用手册
1. log4net简介 log4net是.Net下一个非常优秀的开源日志记录组件.log4net记录日志的功能非常强大.它可以将日志分不同的等级,以不同的格式,输出到不同的媒介.Java平台下,它还 ...
随机推荐
- C字符串复制
void mystrcpy(char *from, char *to) { for(; *from != '\0'; from++, to++) { *to = *from; } *to = '\0' ...
- cocos2d-x:Layer::setPosition
如果Node的实际类型是Layer或者其派生类, setPosition是不是有猫腻? std::string menuImage = "menu.png"; auto menuI ...
- 41、Android中当数据库需要更新时我们该怎么办?
转载 http://blog.csdn.net/jiangwei0910410003/article/details/39670813
- 标准模板库--STL
标准模板库STL 1.泛型程序设计 C++ 语言的核心优势之一就是便于软件的重用 C++中有两个方面体现重用: 1.面向对象的思想:继承和多态,标准类库 2.泛型程序设计(generic progra ...
- 关于微信小程序的尺寸关系
在微信小程序开发中,大家尽量使用rpx为单位, px实际上就是系统级的rem(把页面按比例分割750份,1rpx=window.innerWidth/750),或者scale伸缩布局的width=75 ...
- 巨蟒python全栈开发django2:初识django
今日内容大纲: 1.起飞版web框架 2.自定制框架的流程 3.jinja2模板渲染初识 4.MVC&&MTV 5.django版本介绍及django安装 6.django初识(一些操 ...
- code first 数据库无损迁移
环境:vs2013+nuget Enable-Migrations -EnableAutomaticMigrations Update-Database
- <2013 07 06> Future and Near Future
试图了解 量子力学 近现代基础物理学理论 量子计算机 脑科学 近现代生物学 遗传变异与进化 复杂工程学 系统工程 管理科学 人工智能 智能算法 机器学习 深度学习 大数据 云计算 ...
- CentOS6.9添加环境变量
方法一:直接运行命令export PATH=$PATH:~/.composer/vendor/bin 使用这种方法,只会对当前会话有效,也就是说每当登出或注销系统以后,PATH 设置就会失效,只是临时 ...
- Clustered and Secondary Indexes
Clustered and Secondary Indexes secondary index A type of InnoDB index that represents a subset of t ...