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. MySQL左连接查询

    1.语法: select 字段列表 from table1 别名1 left join table2 别名2 on 连接条件 [where 子句]

  2. lumen-Permission 权限管理使用心得

    安装 composer require spatie/laravel-permission github上有详细介绍:https://github.com/spatie/laravel-permiss ...

  3. 【discuz】G变量注解之 $_G['member'] 全局当前登录者信息

    print? <?php G变量的使用方法: 直接复制下面的变量放到discuzx模板需要的位置即可! 例如:$_G['style'][boardlogo] 刷新后就会 显示一张logo 全局当 ...

  4. 一个fork的面试题——fork + 缓存区

    update : 20140512 题目:请问下面的程序一共输出多少个“-”? #include <stdio.h> #include <sys/types.h> #inclu ...

  5. 【BZOJ2325】[ZJOI2011]道馆之战 线段树+树链剖分

    [BZOJ2325][ZJOI2011]道馆之战 Description 口袋妖怪(又名神奇宝贝或宠物小精灵)红/蓝/绿宝石中的水系道馆需要经过三个冰地才能到达馆主的面前,冰地中的每一个冰块都只能经过 ...

  6. tomcat8热部署配置--maven自动发布项目到tomcat8(如何支持远程访问部署)

    1.tomcat8实现热部署的配置  我们实现热部署后,自然就可以通过maven操作tomcat了,所以就需要maven取得操作tomcat的权限,现在这一步就是配置tomcat的可操作权限. #进入 ...

  7. 第五课 nodejs 路由实现并处理请求作出响应

    1创建一个http Server 文件server.js var http = require('http');var url = require('url');function start(rout ...

  8. <block/> 并不是一个组件,它仅仅是一个包装元素,不会在页面中做任何渲染,只接受控制属性

    <block/> 并不是一个组件,它仅仅是一个包装元素,不会在页面中做任何渲染,只接受控制属性

  9. 使用mybatis向oracle数据库插入数据异常

    遇到了使用mybatis向oracle数据库插入数据异常的问题, 具体的报错如下:org.springframework.jdbc.UncategorizedSQLException: ### Err ...

  10. php中定时计划任务的实现原理

    根据php手册简单介绍一些相关的知识: 1.连接处理: 在 PHP 内部,系统维护着连接状态,其状态有三种可能的情况: 0 - NORMAL(正常) 1 - ABORTED(异常退出) 2 - TIM ...