log4cpp日志库使用
????????Log4cpp是一个开源的C++类库,它提供了C++程序中使用日志和跟踪调试的功能,它提供了应用程序运行上下文,方便跟踪调试;可扩展的、多种方式记录日志,包括命令行、文件、回卷文件、内存、syslog服务器、Win事件日志等;可以动态控制日志记录级别,在效率和功能中进行调整;所有配置可以通过配置文件进行动态调整;多语言支持,包括Java(log4j),C++(log4cpp、log4cplus),C(log4c),python(log4p)等;
1.源码下载
Log4cpp的主页为:Log library for C++ download | SourceForge.net
2.Windows下源码编译
(1)打开mscv10文件夹,双击打开msvc10.sln文件
(2)配置管理器,选择Release x64
(3)log4cpp处右键属性,在预处理器定义处增加HAVE_SNPRINTF
(4)找到log4cpp下的NTEventLogCategories.mc右键属性,在命令行点击编辑
改为以下命令:
if not exist $(OutDir) md $(OutDir)
mc.exe -h $(OutDir) -r $(OutDir) $(ProjectDir)..\%(Filename).mc
RC.exe -r -fo $(OutDir)%(Filename).res $(OutDir)%(Filename).rc
link.exe /MACHINE:IX86 -dll -noentry -out:$(OutDir)NTEventLogAppender.dll $(OutDir)%(Filename).res
(5)倘若需编译log4cppLIB则需对log4cppLIB也执行以上2-5步操作,如需编译整个工程还需对testDailyRollingFileAppender下的testDailyRollingFileAppender.cpp的第43行增加一个空格,即由下图的1改为2
(6)在log4cpp处右键生成
(7)对log4cpp项目编译后生成的lib和dll文件在log4cpp\msvc10\x64\Release文件夹下
(8)Qt项目中加载log4cpp
- 将log4cpp的头文件(include文件夹)拷贝到工程目录下
- 将生成的log4cpp.lib库文件拷贝到工程目录下
- 在Qt工程.pro文件中添加以下配置
LIBS += -L$$PWD/log4cpp/lib/ -llog4cpp
INCLUDEPATH += $$PWD/log4cpp/include
DEPENDPATH += $$PWD/log4cpp/include
- 将生成的log4cpp.dll文件拷贝到工程生成目录下
PS:log4cpp在编译过程如果snprintf.c报错,可将snprintf.c移除后重新编译
3.linux下源码编译
1、编译
本地编译
./configure
交叉编译
./configure CC=aarch64-linux-gnu-gcc CXX=aarch64-linux-gnu-g++ --host=aarch64-linux-gnu --prefix=/home/xmr/log4cpp/build --with-pthreads
安装完成后,log4cpp.so库默认在/usr/local/lib下,头文件在/usr/local/include目录下。可通过该配置项修改为所描述的位置。
2、make
3、make check
4、make install
在程序运行时,依赖的动态库需要在执行时加入环境变量:
export LD_LIBRARY_PATH= $LD_LIBRARY_PATH:/usr/local/lib
4.log4cpp使用
log4cpp库中主要分三大类:Category(种类)、Appender(附加目的地)、Layout(布局)
- category类是日志记录的主要执行类,相当于log4j中的Logger,它负责写日志,就是执行debug(Object msg)、info(Object msg)、warn(Object msg)、error(Object msg)等方法。
- appender类用来指明目的地,即日志要写到什么地方去。log4cpp已经实现了多种不同目标的输出方式,可以向文件输出日志、向控制台输出日志、向Socket输出日志等。
- layout类指明日志输出的格式
此外还有Priority(优先级)和NDC(嵌套的诊断上下文)等。
- Priority被用来指定Category的优先级和日志的优先级
- NDC则是一种用来区分不同场景中交替出现的日志的手段。
log4cpp记录日志的原理如下:
- 每一个Category都有一个优先级,该优先级可以由setPriority方法设置,或者从其父Category中继承而来
- 每条日志也有一个优先级,当Category记录该条日志时,如果日志优先级高于Category的优先级时,该日志被记录,否则被忽略
Category、Appender和Layout三者的关系如下:
- 系统中可以有多个Category,它们都是继承自同一个根,每个Category负责记录自己的日志
- 每个Category可以添加多个Appender,每个Appender指定了一个日志的目的地,比如文件、网络、终端
- 当Category记录一条日志时,该复制被写入到所有附加到此Category的Appender
- 每个Appender都包含一个Layout,该Layout定义了这个Appender上日志的格式
应用时的大概流程:
- 定义一个layout类对象,确定输出日志信息的格式
- 定义一个appender类对象,确定日志输出到什么地方,然后把layout对象用setlayout方法绑定一下
- 定义一个category对象,与appender类对象绑定
- 调用category对象进行写日志
简单使用:
#include "log4cpp/Category.hh"
#include "log4cpp/Appender.hh"
#include "log4cpp/OstreamAppender.hh"
#include "log4cpp/DailyRollingFileAppender.hh"
#include "log4cpp/FileAppender.hh"
#include "log4cpp/RollingFileAppender.hh"
#include "log4cpp/PropertyConfigurator.hh"
#include "log4cpp/PatternLayout.hh"
//定义一个layout类对象,确定输出日志信息的格式
log4cpp::Layout *lay = new log4cpp::SimpleLayout();
//定义一个appender类对象,确定日志输出到什么地方,然后把layout对象用setlayout方法绑定一下
log4cpp::Appender *appender = new log4cpp::FileAppender("FileAppender", "./log_name.log");
appender->setLayout(lay);
//定义一个category对象,与appender类对象绑定
log4cpp::Category &category = log4cpp::Category::getRoot();
category.setAppender(appender);
//调用category对象进行写日志
category.setPriority(log4cpp::Priority::INFO);
category.info("Program info which cannot be wirten");
category.debug("This debug message will fail to write");
category.alert("Alert info");
category.log(log4cpp::Priority::WARN, "This will be a logged warning");
log4cpp::Category::shutdown();
(1)layout布局—日志输出格式
layout对象规定了日志输出的内容格式,创建后需要和append对象绑定生效。注意,一个布局仅能绑定一个appender对象。比较常用的布局有两种:log4cpp::BasicLayout和log4cpp::PatternLayout
- log4cpp::BasicLayout是最简单的布局,输出时间戳,消息优先级和消息内容
- log4cpp::PatternLayout布局支持通过类似print函数的格式控制符的方式自定义输出的信息和内容。通过如下函数进行设置:
log4cpp::PatternLayout::setConversionPattern (conststd::string& conversionPattern) ;
该函数接收的参数为格式控制字符串,其中符号含义如下:
%c: 记录日志的category对象名称;
%d: 日期;日期可以进一步的设置格式,用花括号包围,例如%d{%H:%M:%S,%l} 或者 %d{%d %m %Y%H:%M:%S,%l}。如果不设置具体日期格式,则如下默认格式被使用“Wed Jan 02 02:03:55 1980”。日期的格式符号与ANSI C函数strftime中的一致。但增加了一个格式符号%l,表示毫秒,占三个十进制位。
%m: 要输出的日志消息字符串;
%n: 换行符,会根据平台的不同而不同,但对于用户透明;
%p: 优先级,warn,debug,info等待;
%r: 自从layout被创建后的毫秒数;
%R: 从1970年1月1日0时开始到目前为止的秒数;
%u: 进程开始到目前为止的时钟周期数;
%x: NDC
(2)Appender
append对象指定日志输出到什么地方去,创建后需要和category对象绑定才能生效。一个apender只能和一个category对象绑定,但是一个category对象可以有多个appnder,可以输出到多个位置。常用的appender类如下:
- log4cpp::FileAppender // 输出到文件
- log4cpp::RollingFileAppender // 输出到回卷文件,即当文件到达某个大小后回卷
- log4cpp::OstreamAppender // 输出到一个ostream类
- log4cpp::StringQueueAppender // 输出到内存队列
- log4cpp::SyslogAppender // 本地syslog
- log4cpp::RemoteSyslogAppender // 输出到远程syslog服务器
其中SyslogAppender和RemoteSyslogAppender需要与Syslog配合使用(Syslog是类Unix系统的一个核心服务,用来提供日志服务)
(3)Category
Log4cpp中有一个总是可用并实例化好的Category,即根Category。使用log4cpp::Category::getRoot()可以得到根Category。在大多数情况下,一个应用程序只需要一个日志种类(Category),但是有时也会用到多个Category,此时可以使用根Category的getInstance方法来得到子Category。不同的子Category用于不同的场合。
(4)利用配置文件定制日志
配置文件示例:
log4cpp.rootCategory=DEBUG,rootAppender
log4cpp.appender.rootAppender=RollingFileAppender
log4cpp.appender.rootAppender.fileName=amp.log
log4cpp.appender.rootAppender.maxFileSize=8388608
log4cpp.appender.rootAppender.maxBackupIndex=10
log4cpp.appender.rootAppender.layout=PatternLayout
log4cpp.appender.rootAppender.layout.ConversionPattern=%d{%Y-%m-%d %H:%M:%S,%l}: %p %c %x: %m%n
本配置文件完成个功能是:
1、输出DEBUG及以上级别的日志(值越小,优先级越高)
2、将日志输出到回滚日志文件中,主文件大小810241024字节,名字是amp.log,
3、备份文件10个(名字是amp.log.1,amp.log.2,amp.log.3,一直到amp.log.10,每个都是主文件大小+1KB,这是log4cpp规定的)
4、输出格式是:时间: 优先级 category名称 NDC名称: 消息 换行,其中时间是“年-月-日 时:分:秒,毫秒”格式
使用:
#include "log4cpp/Category.hh"
#include "log4cpp/PropertyConfigurator.hh"
try{
log4cpp::PropertyConfigurator::configure("./log4cpp.conf");
}catch(log4cpp::ConfigureFailure& f){
cout<<f.what()<<endl;
}
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!