日志库Log
2014年7月1日
2014年9月12日添加QT原生日志函数
1 概述
在系统集成中,大多数以库或可执行文件的形式集成(在windows中,dll形式的库在集成时有很多问题,最著名的就是dll地狱,还有C++导出类等其它问题),集成中的调试信息很难通过程序的中调试程序输出(如TRACE(),OutputDebugString()等。为了能够在运行中获取调试信息,一般将程序的信息输出到文件,以日志的形式进行保存。
常用的日志库有log4c(可移植性好,文档少),log4cpp(使用方便,文档资源全,最接近log4j,推荐),log4cplus(功能全,复杂),log4qt(可以直接操作QT类)。Qt中可以使用通过的库,原生的日志使用qDebug()等的处理函数,将其记录到文件中作为日志。
2 log4c
2.1 库
官网:http://log4c.sourceforge.net/。
下载源码编译,或直接使用预编译的版本。
2.2 操作
log4c移植于log4j(java),用于日志输出的纯C库,操作方法与log4j相同。
log4c通过log4crc文件指定相关的参数。
在程序中使用log4c_init():初始化。log4c_finit():去初始化。来初始化和释放资源。
log4c_categary_get(name):从rc文件中获取指定的category。
log4c_categary_log(pCat,type,str):依据rc文件的配置输出log信息。
2.3 配置
categary:类别,不同的log对象的种类。
在RC文件中指定名称、优先级和appender。
appender:输出位置。
在RC文件中指定名称、类别和layout、rollingpolicy。
layout:输出格式。
在RC文件中指定名称和类型。、
rollingpolicy:输出文件策略。
在RC文件中指定文件的名称、类型、最大、最小。
2.4 示例
参考:
入门:http://www.cnblogs.com/jyli/archive/2010/02/11/1660606.html
详细:http://xueqi.iteye.com/blog/1570013
3 log4cpp
3.1 库
官网:http://log4cpp.sourceforge.net/。
下载源码编译,无预编译的版本。
3.2 编译
下载后有各种库的(如:msvc10等)工程文件,使用相关的程序(如:vs2012)打开(debug版对应不同的VC版本需要编译成不同的文件,但是release版本可以通用),编译,编译lig4cpp(动态库)和libcpplib(静态库)。
编译完成后在工程文件目录下有debug和release两个目录,将相关的lib、dll拷贝出来,源文件下有include目录,就可以用了。
注意:在使用时需要与客户程序相同的vc版本。
编译完成后可以使用doxygen生成帮助文件。
参考:http://blog.youkuaiyun.com/kingskyleader/article/details/7320826
http://sogo6.iteye.com/blog/1154315
http://www.ibm.com/developerworks/cn/linux/l-log4cpp/
3.3 原理
log4cpp将所不同的日志类型视为不同的类别(Category)。每个日志可以指定不同的输出(Appender),输出的格式使用布局(Layout)设定。
类别是进行日志操作的实体类,可以使用派生的子类直接继承父类。所有类别的父类是rootCategory。类别需要指定输出的优先级别(Priority),小于此级别的日志将不输出。
日志具有不同的优先级,可以设置日志输出的优先级范围。
在使用配置文件时,将所有的类属性以键值对的方式进行配置。
3.4 方法
3.4.1类别Category:用于标识不同的日志对象。
1) Category需要指定日志优先级(Priority,只有大于指定Priority的日志才会记录)和输出目标(Appender,可以有多个输出Appender)。
2) Category组织为树,子Category继承父Category的Appender,使用additivity=false,可以重新生成Appender列表。
3) 由于在源程序的不同文件中可能需要使用同一个日志输出,所以使用静态单例的方法,根据不同的名称,生成不同的类别。
3.4.2输出Appender:输出日志到指定的目标。
1) Appender也是树形组织的类别,可以继承。预定义有多种类型(参见源码),常用的有:consoleAppender(输出到std::cout),Win32DebugAppender(VC IDE中的输出窗口==OutputDebugString),FileAppender(文件输出),RollingFileAppender(循环文件输出)。
2) Appender需要指定类型及其参数,并设置输出布局(Layout)。
3.4.3布局Layout:设置日志格式。
Layout需要指定类型及其参数。
3.4.4优先级Priority:设置需要输出的级别范围。
NOTSET < DEBUG < INFO < NOTICE < WARN< ERROR < CRIT < ALERT < FATAL = EMER
示例:
usingnamespacelog4cpp;
Appender*myAppender=newFileAppender("myapp","myapp.log");
myAppender->setLayout(newBasicLayout);
Category&myCat=Category::getInstance("mycat");
myCat.setPriority(Priority::DEBUG);
myCat.addAppender(myAppender)
myCat.debug("mycat.myapp.basiclayout.");
3.4.5配置文件
可以直接读取配置文件,使用配置文件中的参数,生成指定的类,使用时直接获取类进行输出,操作方便,配置灵活。
配置参数参见:配置
3.5 操作
3.5.1程序生成
可以利用程序生成各种参数完成日志记录。
修改时不方便,仅用于原理演示。
示例:
#include<log4cpp/Category.hh>
#include<log4cpp/FileAppender.hh>
#include<log4cpp/BasicLayout.hh>
#pragmacomment(lib,"log4cpp.lib")
intmain(intargc,char*argv[])
{
usingnamespacelog4cpp;
log4cpp::Layout*pLayout=newlog4cpp::BasicLayout;
Appender*pAppender=newFileAppender("FileAppender","../test.log");
pAppender->setLayout(pLayout);
Category&warn_log= Category::getInstance("mywarn");
warn_log.setPriority(Priority::DEBUG);
warn_log.addAppender(pAppender);
warn_log.debug("%s,%d","hello,log4cpp!",12