log4j介绍的文档很多,在java领域使用的也比较广泛,而这个功能强大的库对国内的C++语言开发人员却使用的不多。这里从开发人员使用的角度介绍这个库,使开发人员用最少的代价尽快掌握这种技术。下面先简单介绍一下这个项目的优点(也是log4j的优点),然后分原理,手动使用步骤,配置文件驱动方式使用步骤,其他考虑等方面进行讨论。以下讨论基于log4cpp0.3.4b。
- 提供应用程序运行上下文,方便跟踪调试;
- 可扩展的、多种方式记录日志,包括命令行、文件、回卷文件、内存、syslog服务器、Win事件日志等;
- 可以动态控制日志记录级别,在效率和功能中进行调整;
- 所有配置可以通过配置文件进行动态调整;
- 多语言支持,包括Java(log4j),C++(log4cpp、log4cplus),C(log4c),python(log4p)等;
![]() ![]() |
![]() |
log4cpp有3个主要的组件:categories(类别)、appenders(附加目的地)、和 layouts(布局)。(为了方便大家理解,文中尽量使用英文原词)
layout类控制输出日志消息的显示样式(看起来像什么)。log4cpp当前提供以下layout格式:
|
appender类用来输出日志(被layout格式化后的)到一些设备上。比如文件、syslog服务、某个socket等。可以定义自己的appender类输出日志信息到别的设备上,比如应用自身的日子处理进程、数据库等。appender和layout的关系是layout附在appender上,appender类调用layout处理完日志消息后,记录到某个设备上。log4cpp当前提供以下appender:
|
category 类真正完成记录日志功能,两个主要组成部分是appenders和priority(优先级)。优先级控制哪类日志信息可以被这个category记录,当前优先级分为:NOTSET, DEBUG, INFO, NOTICE, WARN, ERROR, CRIT, ALERT 或 FATAL/EMERG 。每个日志信息有个优先级,每个category有个优先级,当消息的优先级大于等于category的优先级时,这个消息才会被category记录,否则被忽略。优先级的关系如下。category类和appender的关系是,多个appender附在category上,这样一个日志消息可以同时输出到多个设备上。
NOTSET < DEBUG < INFO < NOTICE < WARN < ERROR < CRIT < ALERT < FATAL = EMERG
category被组织成一个树,子category创建时优先级缺省NOTSET,category缺省会继承父category的appender。而如果不希望这种appender的继承关系,log4cpp允许使用additivity 标签,为false时新的appender取代category的appender列表。
为了更好的理解上面的概念下面以手动使用方式举例。
![]() ![]() |
![]() |
手动使用log4cpp的基本步骤如下:
- 实例化一个layout 对象;
- 初始化一个appender 对象;
- 把layout对象附着在appender对象上;
- 调用log4cpp::Category::getInstance("name"). 实例化一个category对象;
- 把appender对象附到category上(根据additivity的值取代其他appender或者附加在其他appender后)。
- 设置category的优先级;
|
![]() ![]() |
![]() |
另一个非常优秀的特征就是通过读取配置文件,确定category、appender、layout等对象。也是我们非常推荐的使用方式,可以灵活地通过配置文件定义所有地对象及其属性,不用重新编码,动态更改日志记录的策略。
Log4cpp主要提供了 log4cpp::PropertyConfigurator 和log4cpp::SimpleConfigurator两种机制(文件格式),但 log4cpp::SimpleConfigurator将来不再支持了,而且格式非常简单,这里就不多说明,自己看源码吧。
配置文件的格式和log4j的配置文件一样,是标准的java属性文件格式。下面是附带的例子配置文件:
|
配置文件语法如下,不是很规范,结合上面的例子,应该可以看懂。
|
基本使用步骤是:
- 读取解析配置文件;
- 实例化category对象;
- 正常使用这些category对象进行日志处理;
下面是个简单的使用代码,使用起来是非常方便的:
|
![]() ![]() |
![]() |
性能问题,可能是很多想使用log4cpp的程序员关心的问题。在参考资料2中有一段描述。结论就是log4j以及log4cpp是以性能为首要目标的;如果关闭日志记录的话,对性能影响可以忽略;打开日志记录,主要消耗是在记录动作,而不是库的管理过程;所以你尽可放心的使用。实在要深究性能的话。可以从下面方面提高:
输出的日志消息不要使用复杂的转换或者处理,比如: sub1.debug(string("Current num is") + i + GetCurStat()); 这种情况即使不进行日志处理,括号中的语句还是会执行。变通方法是:
|
安全性问题对于商业软件开发可能也是问题。可能不希望别人通过修改配置文件获取程序的调试等程序内部运行情况的日志信息。比较稳妥的方案或者是加密配置文件,运行中解密,输出到临时文件后读取;或者在发行版本里读取配置文件后,强行把低于某个优先级的category设到比较高的优先级。
多线程安全性问题。当前log4cpp还没有宣称自己是多线程安全的,不过其代码中大多数可能冲突的地方都增加了线程互斥控制,对多线程环境应该问题不大。但为了加入这个特性,linux下编译log4cpp时,configure请加入--with-pthreads 或者--with-omnithreads选项。Win版本已经加入对MS线程的支持。
来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/143526/viewspace-1043024/,如需转载,请注明出处,否则将追究法律责任。
转载于:http://blog.itpub.net/143526/viewspace-1043024/