1.简介

(1)Apache log4cxx当前是由Apache软件基金会进行维护。它是java中著名开源项目Apache log4j在c++中对应的日志框架。它是借助于APR(Apache Portable Runtime)的可在多平台进行移植的开源项目。

经验表明,日志是开发流程中一个重要的模块,有很多优点。可以提供程序运行的精确信息。一旦我们将日志写入代码中,日志的产生就不用我们人工干预了。

此外,我们可以将日志信息记录在稳定的媒介中供我们之后去分析。除了这些用途之外,一个有效丰富的日志模块还可以看作是一个审计工具。

当然日志也有它的一些缺点。它会降低程序运行速度。如果日志冗余,会一直刷屏。为了减轻这些顾虑,log4cxx就被立志于设计成一个可靠、快速和可扩展的模块。

(2)log4cxx包括三个组件,loggers,appenders和layouts。loggers定义一个logger实体,appenders设置日志输出到哪里,layouts设置日志以什么格式进行输出。

(3)具体参考log4cxx官方网站:http://logging.apache.org/log4cxx/

2.windows下编译

由于log4cxx运行在APR下,所以需要apr和apr-util开源库,可以在apache官网上下载。编译过程中遇到了一些问题,可以参考网上的一些博客。

例如:http://blog.sina.com.cn/s/blog_a459dcf501013tbn.html

3.log4cxx的性能

(1)log4cxx对系统性能的影响程度主要体现在以下几方面:

a、日志输出的目的地,输出到控制台的速度比输出到文件系统的速度要慢。

b、日志输出格式不一样对性能也会有影响,如简单输出布局(SimpleLayout)比格式化输出布局(PatternLayout)输出速度要快。可以根据需要尽量采用简单输出布局格式输出日志信息。

c、日志级别越低输出的日志内容就越多,对系统系能影响很大。

d、日志输出方式的不同,对系统系能也是有一定影响的,采用异步输出方式比同步输出方式性能要高。

e、每次接收到日志输出事件就打印一条日志内容比当日志内容达到一定大小时打印系能要低。

(2)不同日志输出方式的性能分析

日志线程发现需要记日志时独占缓存(与此同时各线程等待,此时各线程是被阻塞住的),从缓存中取出日志信息,获得输出流进行输出,将缓存解锁(各线程收到提醒,可以接着写日志了)。

众所周知,磁盘IO操作、网络IO操作、数据库操作等都是非常耗时的,日志输出的主要性能瓶颈也就是在写文件、写网络、写数据库的时候。日志是肯定要记的,而要采用异步方式记,也就只有将这些耗时操作从主线程当中分离出去才真正的实现性能提升,也只有在线程间同步开销小于耗时操作时使用异步方式才真正有效 !

现在我们接着分别来看看这几种日志输出方式:

a、将日志记录到本地文件:log4cxx本身有一个buffer处理入库,采用异步方式并不一定能提高性能(主要是如何配置好缓存大小);而线程间的同步开销则是非常大的!因此在使用本地文件记录日志时不建议使用异步方式。

b、将日志记录到JMS:JMS本身是支持异步消息的,如果不考虑JMS消息创建的开销,也不建议使用异步方式。(java中的log4j)

c、将日子记录到SOCKET:将日志通过Socket发送,纯网络IO操作不需要反馈,因此也不会耗时

d、将日志记录到数据库:众所周知数据库是几种方式中最耗时的,网络、磁盘、数据库事务,都使数据库操作异常的耗时,在这里采用异步方式入库倒是一个不错的选择。

e、将日志记录到SMTP:同数据库

(3)日志输出到文件的性能分析

log4cxx.logger.monitorLogger=INFO,monitorAppender
log4cxx.additivity.monitorLogger=false

log4cxx.appender.monitorAppender=org.apache.log4cxx.DailyRollingFileAppender
log4cxx.appender.monitorAppender.File=mtlogs/mt_log.txt
log4cxx.appender.monitorAppender.layout=org.apache.log4cxx.PatternLayout
log4cxx.appender.monitorAppender.layout.ConversionPattern=%m%n
log4cxx.appender.monitorAppender.DatePattern='.'yyyy-MM-dd-HH
log4cxx.appender.monitorAppender.BufferedIO=true

上面的日志输出配置,在当日志打印很频繁的时候,由于写文件时读写磁盘的速度小于日志打印速度,这样下来就会影响软件性能(在windows平台下会导致内存增长,猜测可能会将日志先缓存起来,再进行写文件操作)。

如果添加如下配置:

log4cxx.appender.monitorAppender.BufferedIO=true
log4cxx.appender.monitorAppender.BufferSize=8192

这个选项用于告诉log4cxx输出日志的时候采用缓冲的方式,而不是即时flush方式(log4cxx输出缓冲日志是以8K为单位的,因为磁盘的一个block为8K,这样可以减少碎片,也就是说假设你设置缓存为18K,log4cxx在16K(8K*2)的时候就会输出),而不是18K)。实现了缓存模式,即合并日志输出的模式,它先把所有的日志都放到一个buffer数组里,如果buffer满了,就把buffer里内容全部写入磁盘,这样可以大大减少调用磁盘的次数。那么问题来了:既然开启缓存模式能提高系统,那么log4cxx为什么没有默认开启缓存模式呢?个人猜测是因为缓存模式需要缓存填充满了才会写入磁盘,但是假如系统突然崩溃了,缓存中残留的数据没有写入磁盘,从而导致日志丢失。而系统崩溃时的日志往往是排查和定位问题的关键,所以大部分情况下日志的完整性更为重要。但是享受缓慢模式的高性能与日志的完整性真的是鱼与熊掌不可兼得吗?是不是可以通过捕获异常,在异常中将缓存日志写入文件中?

(4)日志输出采用异步方式性能分析

异步输出日志工作原理

AsyncAppender采用的是生产者消费者的模型进行异步地将Logging Event送到对应的Appender中。

a、 生产者:外部应用了log4cxx的系统的实时线程,实时将Logging Event传送进AsyncAppender里

b、 中转:Buffer和DiscardSummary

c、 消费者:Dispatcher线程和appenders

工作原理:

1) Logging Event进入AsyncAppender,AsyncAppender会调用append方法,在append方法中会去把logging Event填入Buffer中,当消费能力不如生产能力时,AsyncAppender会把超出Buffer容量的Logging Event放到DiscardSummary中,作为消费速度一旦跟不上生成速度,中转buffer的溢出处理的一种方案。

2)AsyncAppender有个线程类Dispatcher,它是一个简单的线程类,实现了Runnable接口。它是AsyncAppender的后台线程。

Dispatcher所要做的工作是:

1)锁定Buffer,让其他要对Buffer进行操作的线程阻塞。

2)看Buffer的容量是否满了,如果满了就将Buffer中的Logging Event全部取出,并清空Buffer和DiscardSummary;如果没满则等待Buffer填满Logging Event,然后notify Disaptcher线程。

3) 将取出的所有Logging Event交给对应appender进行后面的日志信息推送。

以上是AsyncAppender类的两个关键点:append方法和Dispatcher类,通过这两个关键点实现了异步推送日志信息的功能,这样如果大量的Logging Event进入AsyncAppender,就可以游刃有余地处理这些日志信息了。

log4cxx的更多相关文章

  1. how to build apache log4cxx 0.10 by Visual Studio 201*

    Chapter 1 Official Steps  We are going to follow the steps here, http://logging.apache.org/log4cxx/b ...

  2. windows 下编译log4cxx(x64)

    参考链接 http://blog.csdn.net/hnu_zxc/article/details/7786060 http://blog.chinaunix.net/uid-20384806-id- ...

  3. 在RHEL5.2 64bit下编译安装log4cxx错误

    apache-log4cxx.0.10.0 依赖于apache-apr和apache-apr-utils两个包 先安装他们俩,然后编译log4cxx,发现make失败,错误如下 ronized.o . ...

  4. log4cxx安装和使用

    log4cxx是Java社区著名的log4j的c++移植版,用于为C++程序提供日志功能,以便开发者对目标程序进行调试和审计,log4cxx是apache软件基金会的开源项目,基于APR实现跨平台支持 ...

  5. Apache log4cxx用法

    一个好的系统通常需要日志输出帮助定位问题 .Apache基金会的log4cxx提供的完善的Log分级和输出功能.所以准备把该Log模块加入的系统中. 使用log4cxx需要满足一下功能: 1.提供日志 ...

  6. log4cxx在vs2013的静态编译

    网络上找了一圈,结果都是通过修改代码来编译,做为强迫症患者接受不了这种修改代码却无法预知代码带来影响的方式,而且没有静态编译的方法,为了方便其他人后续不在走弯路,提供自己的编译方法. 虽然最终的目的是 ...

  7. 使用log4cxx在GUI 程序中将信息输出到Console

    之前看到有个方法是在项目属性设置里实现的 以VS2010为例: 右键Project选择Properties->Configuration Properties->Build Events- ...

  8. log4cxx 使用代码进行配置

    (1)官网的一个例子 #include <log4cxx/logger.h> #include <log4cxx/helpers/pool.h> #include <lo ...

  9. log4cxx入门第一篇--一个小例子

    先看官网:http://logging.apache.org/log4cxx/index.html 转载自:http://wenku.baidu.com/view/d88ab5a9d1f34693da ...

随机推荐

  1. ffmbc——广播电视以及专业用途量身定制的FFmpeg

    做项目遇到针对于mpegts多节目流转码的问题,看遍了ffmpeg的参数都得不到解决办法,最后在雷神的博客中看到了ffmbc: 结果,还是没解决问题,但是看起来改改ffmbc的代码还是相对简单一些,抽 ...

  2. 关于把.net 2.0的项目升级到.net4.0遇到的一些问题

    进入公司实习的的第一个项目又是是一个升级项目.这次升级的是一个c/s架构的项目. 大致介绍一下这个项目的结构客户端采用winform+devexpress商业控件开发的,数据库是用的oracle数据库 ...

  3. Spark在Ubuntu中搭建开发环境

    一.在Windows7中安装Ubuntu双系统 工具/原料   windows7 64位 ubuntu 16.04 32位 UltraISO最新版(用来将镜像文件烤到U盘中) 空U盘(若有文件,请先备 ...

  4. 回文自动机(BZOJ2565)

    #include <cstdio> #include <cstring> #include <iostream> using namespace std; ][], ...

  5. 10 行 Python 代码写的模糊查询

    导语: 模糊匹配可以算是现代编辑器(在选择要打开的文件时)的一个必备特性了,它所做的就是根据用户输入的部分内容,猜测用户想要的文件名,并提供一个推荐列表供用户选择. 样例如下: Vim (Ctrl-P ...

  6. python学习之day5,装饰器,生成器,迭代器,json,pickle

    1.装饰器 import os import time def auth(type): def timeer(func): def inner(*args,**kwargs): start = tim ...

  7. Block产生的内存泄露,以及解决方法

    前言: 在ARC(自动引用技术)前,Objective-c都是手动来分配释放 释放 计数内存,其过程非常复杂. ARC技术推出后,貌似世界和平了很多,但是其实ARC并不等同于Java或者C#中的垃圾回 ...

  8. 解决:Win 10 + Mint 18双系统时间不同步,更换系统启动项顺序

    1.win10 & mint 18双系统时间同步: 先打开终端下更新一下时间,确保时间无误: sudo apt-get install ntpdate sudo ntpdate time.wi ...

  9. iis虚拟目录名称“ReportServer”的巧合

      今天测试一个Crystal Report网站的报表服务,建立一个虚拟目录,名为ReportServer,结果无论怎样访问浏览器都返回 localhost/ReportServer - / Micr ...

  10. 理解javascript this指向

    匿名函数中的this指向window对象 这句话很经典: 每个函数在调用时,其活动对象都会自动获取两个特殊的变量:this和arguments.内部函数在搜索这两个变量时,只会搜到其活动对象为止,因此 ...