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平台下,它还 ...
随机推荐
- Laravel5.1 Migration数据库迁移文件
Migration方便于团队开发,它就像数据库的版本控制一样,它的功能就是可以和别人共享你的数据库结构.这么说可能不太好理解,你跟着敲敲就明白了. 0 前提工作-配置数据库 找到你根目录的 .env ...
- python 推荐算法
每个人都会有这样的经历:当你在电商网站购物时,你会看到天猫给你弹出的“和你买了同样物品的人还买了XXX”的信息:当你在SNS社交网站闲逛时,也会看到弹出的“你可能认识XXX“的信息:你在微博添加关注人 ...
- Jmeter与LoadRunner 测试Java项目的坑
32位的JDK,Jmeter.bat 最大内存只能配置1G,测不了大并发,所以用Jmeter测试时一定要改成64位的Jmeter用LR测试java程序的时候必须用32位的JDK 环境变量 在path的 ...
- Android无线测试之—UiAutomator UiDevice API介绍四
拖拽与滑动 一.概念介绍: 1)拖拽:将组建从一个坐标移动到另一个坐标 2)移动:从一二坐标点移动到另一个坐标点 3)步长:从一点滑动到另一点使用的时间 二.拖拽与滑动的相关API: 返回值 方法名 ...
- python学习【第十一篇】网络编程
一.socket的简介 socket(简称:套接字)进程间通信的一种方式,它与其他进程间通信的一个主要不同是:能实现不同主机间的进程间通信,我们网络上各种各样的服务大多都是基于 Socket 来完成通 ...
- 《从零开始学Swift》学习笔记(Day 7)——Swift 2.0中的print函数几种重载形式
原创文章,欢迎转载.转载请注明:关东升的博客 Swift 2.0中的print函数有4种重载形式: l print(_:).输出变量或常量到控制台,并且换行. l print(_:_:).输出 ...
- JDBC 入门
1. JDBC 简介 JDBC (Java DataBase Connectivity) 就是 Java 数据库连接, 说白了就是用 Java 语言向 数据库发送 SQL 语句. JDBC 其实是访问 ...
- Python3.6全栈开发实例[013]
13.用户输入的信息,如果出现了列表中的敏感词汇,请用*替代. li = ["苍老师","东京热","武藤兰","波多野结衣&qu ...
- Js算两经纬度间球面距离
function GetDistance( lat1, lng1, lat2, lng2){ var radLat1 = lat1 * Math.PI / 180.0 var radLat2 = la ...
- Node.js的概念与应用
转:http://blog.jobbole.com/100058/?utm_source=blog.jobbole.com&utm_medium=relatedPosts Node.js 是什 ...