第一次使用log4qt日志系统,之前没有使用过log4j,log4cplus等,简单的记录下使用过程。
log4qt是Apache的log4j的qt移植版本,log4j是在java下面使用的一个超强大的日志系统,只要引起一个包一句代码就可以使用,做java开发的小伙伴应该都不陌生。
log4qt是一些大牛参考log4j整理的一套在C++上使用的日志系统,使用参考log4j的使用,log4qt是开源的,使用的过程中我发现有多个版本源码,且各不相等,实现也各不相同,有一些配置选项并没有实现,需要自己修改源码,比如说设置输出等级,打印文件名、函数名、行号等信息。
在log4qt的基础上,研究源码,自己实现打印文件名、函数名、行号等信息,这个还是比较有用的,在出现bug的时候比较好定位。
首先log4qt是一个开源的源码,可以在官网进行下载源码:https://sourceforge.net/projects/log4qt/,为了方便使用将其编译成一个dll进行使用,在使用的工程里面加载dll和相应的头文件即可。
一、在qt上创建一个dll工程,将log4qt源码添加到工程里面 include(log4qt/log4qt.pri)
二、创建一个继承QObject的单列,关键步骤是在一个名字为 LOG4QT_DECLARE_QCLASS_LOGGER的宏,这样才可以使用log4qt 否则不可使用 ,在构造函数里面加载log4qt的配置文件log4qt.conf 如图:
配置文件如下 log4qt.conf: 具体配置可以自己百度研究这里就不多说了,参考log4j的配置方式(有些配置项在qt可能没有实现)
log4j.rootLogger=INFO, rollingFile
log4j.additivity.org.apache=true
log4j.appender.rollingFile=Log4Qt::RollingFileAppender
log4j.appender.rollingFile.ImmediateFlush=true
log4j.appender.rollingFile.AppendFile=true
log4j.appender.rollingFile.File=C:/Users/Dione/AppData/Local/log4Test/log4qt.log
log4j.appender.rollingFile.MaxFileSize=4096KB
log4j.appender.rollingFile.MaxBackupIndex=50
log4j.appender.rollingFile.layout=Log4Qt::PatternLayout
log4j.appender.rollingFile.layout.ConversionPattern=[%p] %d(%r) --> %m %n
最简单使用如下:
QBLog4Qt::instance()->debug("debug");
QBLog4Qt::instance()->info("debug");
QBLog4Qt::instance()->warn("debug");
QBLog4Qt::instance()->error("debug");
QBLog4Qt::instance()->fatal("debug");
三、在使用的过程中我发现 配置输出日志信息带文件名、函数名、行号等信息无效,经过阅读源码发现,log4qt根本就可以实现对应的配置选项(至少我下载的版本是没有实现的),参考qt debug类实现log4qt的文件名、函数名、行号信息输出。
添加一个QBLog4Helper类,通过宏定义的方式实现 :
#define Log4Debug QBLog4Helper(__FILE__, __LINE__, Q_FUNC_INFO).debug
为了实现跟debug的输出格式一致,列如可以输出多个参数,参数个1-n个 参数类型任意等,使用C++11的类模板动态参数:
QString TemplateParameter (){ return ""; }
template
QString TemplateParameter(T head, Args ... args) { return QString("%1 ").arg(head) + TemplateParameter(args...); }
template
void debug(T head, Args ... args){
QString logmsg = QString("%1 ").arg(head) + TemplateParameter(args...);
writelogToLocal(LGDebugMsg,logmsg);
}
这样实现后就可以这样使用了:
QString str = "String";
char* p = "char*";
int i = 1;
double d= 1.1;
char c = 'c';
float f = 1.111;
Log4Info(str);
Log4Info(str,p);
Log4Info(str,p,i);
Log4Info(str,p,i,d);
Log4Info(str,p,i,d,c);
Log4Info(str,p,i,d,c,f);
Log4Info(str,p,i,d,c,f,"汉字");
Log4Info(str,p,i,d,c,f,"汉字","log4qt!");
Log4qt<<"1"<<1<<1.1<<'c'<<"汉字"<<"log4qt!";
这样使用是不是很爽呢。输出保存的日志结果如下:
[INFO] 2018-09-12 16:00:21.085(124) --> start used log4qt!
[INFO] 2018-09-12 16:00:21.085(124) --> [file(..\log4Test\main.cpp) func(int qMain(int, char**)) line(16) pid(0x28028)] --> String
[INFO] 2018-09-12 16:00:21.086(125) --> [file(..\log4Test\main.cpp) func(int qMain(int, char**)) line(17) pid(0x28028)] --> String char*
[INFO] 2018-09-12 16:00:21.086(125) --> [file(..\log4Test\main.cpp) func(int qMain(int, char**)) line(18) pid(0x28028)] --> String char* 1
[INFO] 2018-09-12 16:00:21.086(125) --> [file(..\log4Test\main.cpp) func(int qMain(int, char**)) line(19) pid(0x28028)] --> String char* 1 1.1
[INFO] 2018-09-12 16:00:21.086(125) --> [file(..\log4Test\main.cpp) func(int qMain(int, char**)) line(20) pid(0x28028)] --> String char* 1 1.1 c
[INFO] 2018-09-12 16:00:21.086(125) --> [file(..\log4Test\main.cpp) func(int qMain(int, char**)) line(21) pid(0x28028)] --> String char* 1 1.1 c 1.111
[INFO] 2018-09-12 16:00:21.086(125) --> [file(..\log4Test\main.cpp) func(int qMain(int, char**)) line(22) pid(0x28028)] --> String char* 1 1.1 c 1.111 汉字
[INFO] 2018-09-12 16:00:21.087(126) --> [file(..\log4Test\main.cpp) func(int qMain(int, char**)) line(23) pid(0x28028)] --> String char* 1 1.1 c 1.111 汉字 log4qt!
[INFO] 2018-09-12 16:00:21.087(126) --> [file(..\log4Test\main.cpp) func(int qMain(int, char**)) line(25) pid(0x28028)] --> 1
[INFO] 2018-09-12 16:00:21.087(126) --> [file(..\log4Test\main.cpp) func(int qMain(int, char**)) line(25) pid(0x28028)] --> 1
[INFO] 2018-09-12 16:00:21.087(126) --> [file(..\log4Test\main.cpp) func(int qMain(int, char**)) line(25) pid(0x28028)] --> 1.1
[INFO] 2018-09-12 16:00:21.087(126) --> [file(..\log4Test\main.cpp) func(int qMain(int, char**)) line(25) pid(0x28028)] --> c
[INFO] 2018-09-12 16:00:21.087(126) --> [file(..\log4Test\main.cpp) func(int qMain(int, char**)) line(25) pid(0x28028)] --> 汉字
[INFO] 2018-09-12 16:00:21.087(126) --> [file(..\log4Test\main.cpp) func(int qMain(int, char**)) line(25) pid(0x28028)] --> log4qt!
[INFO] 2018-09-12 16:00:21.088(127) --> stop used log4qt!
完整的工程下载地址(dll工程和测试工程):https://download.csdn.net/download/u012532263/10686200
仅供学习参数使用,谢谢! by Dione