在开发qt应用程序中,经常使用打印调试软件。qt自己的qDebug()就满足了需求。但是当需要把一部分log记录到文件的时候qt就没有提供了。这个时候可以使用qDebug()的qInstallMsgHandler来指定打印回掉函数了。在回掉打开文件进行写文件操作。这样简单实现,简单用。但是对于对log写文件要求比较高的比较成熟的log系统。还是自己专门实现一个或者用现成优秀的log库。
推荐的有Log4Qt。但是这里为了打印的高度定制化,还是得自己开发的一个qt的log打印库。实现代码比较简约稳定。实现主要参考了qDebug的实现架构。核心字符串与各种输入对象的合并为一个字符串使用了qt的类“QDebug”。名字叫做“MyLog” ^_^。
用MyLog可以在终端打印出对应log的代码文件名称和行号(qDebug()没有这个功能)。行号可以方便快速定位调试位置。MyLog把info,debug,error在终端以不同的颜色显示。很直观的看到各个级别的log信息。MyLog还可以把平时写的调试打印打印到log文件中。如果对log文件的细节不满意,还可以根据接口实现自己的类。然后使用installer_logger安装你实现的记录器即可用你定义的方式输出log文件了。
MyLog项目在github上,欢迎使用并一起改进。地址如下:
https://github.com/robert1207/MyLog
git clone https://github.com/robert1207/MyLog
#using MyLog as the src (使用你自己的目录)
#include($$PWD/my_lib/MyLog/MyLogSrc.pri)
#using MyLog as a lib (使用你自己的目录)
include($$PWD/my_lib/MyLog/MyLogLib.pri)
#include "my_log_export.h"
QCoreApplication::setApplicationName("myappname");
QCoreApplication::setApplicationVersion("0.0.1");
QCoreApplication::setOrganizationName("com.company.myappname"); //设置程序名称,保存文件时候用到
QCoreApplication::setOrganizationDomain("com.company.myappname");
MyLogNS::FileLogger *fileLog = new MyLogNS::FileLogger();
int result = fileLog->open_log_file_at_dir("log");
if(result != 0) {
qDebug("error: %s", fileLog->get_error_str(result));
}
qDebug("log file path=%s", fileLog->get_log_file_abs_path());
MyLogIns.installer_logger(fileLog);
MyLogIns.installer_logger(new MyLogNS::ConsoleLogger());
MyLogIns.is_enable_auto_new_line= true; //default is true
MyLogIns.is_show_level_str= true; //default is true
MyLogIns.is_show_timestamp= true; //default is true
MyLogIns.is_show_file_name= true; //default is false
MyLogIns.is_show_function_name= true; //default is true
MyLogIns.is_show_line_number= true; //default is true
I << "str value=" << 1; //log info
D << "str value=" << 2; //log debug
E << "str value=" << 3; //log error
D << "Date:" << QDate::currentDate();
D << "Types:" << QString("String") << QChar('x') << QRect(0, 10, 50, 40);
#DEFINES += MYLOG_NO_I_OUTPUT
#DEFINES += MYLOG_NO_D_OUTPUT
#DEFINES += MYLOG_NO_E_OUTPUT
当你需要把记录的log以自己的储存方式储存的时候,就可以通过接口重新实现一个输出器。比如你想要通过网络打印。即把打印的log 通过网络请求输出。就可以按照如下步骤操作:
class LoggerInterface
{
public:
LoggerInterface();
virtual ~LoggerInterface();
public:
virtual void open() = 0;
virtual void close() = 0;
virtual void write(LogLevel level, const QString &msg, bool is_shift_to_next_line) = 0;
};
#include "logger_interface.h"
class NetLogger : public MyLogNS::LoggerInterface
{
public:
NetLogger();
virtual void open();//安装记录器的时候被调用,用于初始化
virtual void close();//在程序关闭的时候被调用,用于关闭文件
virtual void write(MyLogNS::LogLevel level, const QString &msg, bool is_shift_to_next_line);//参数分别是:打印等级,打印字符串,是否自动换行
};
MyLogIns.installer_logger(new NetLogger());
#include
#include
#include
#include
#include "my_log_export.h"
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
QCoreApplication::setApplicationName("appname");
QCoreApplication::setApplicationVersion("0.0.1");
QCoreApplication::setOrganizationName("com.company.appname");
QCoreApplication::setOrganizationDomain("com.company.appname");
MyLogNS::FileLogger *fileLog = new MyLogNS::FileLogger();
int result = fileLog->open_log_file_at_dir("log");
if(result != 0) {
qDebug("error: %s", fileLog->get_error_str(result));
}
qDebug("log file path=%s", fileLog->get_log_file_abs_path());
MyLogIns.installer_logger(fileLog);
MyLogIns.installer_logger(new MyLogNS::ConsoleLogger());
/*
MyLogIns.is_enable_auto_new_line= false; //default is true
MyLogIns.is_show_level_str= false; //default is true
MyLogIns.is_show_timestamp= false; //default is true
MyLogIns.is_show_file_name= false;
MyLogIns.is_show_function_name= false;
MyLogIns.is_show_line_number= false;*/
I << "value1 =" << 1;
D << "value2 =" << 2;
E << "value3 =" << 3;
D << "Date:" << QDate::currentDate();
D << "Types:" << QString("String") << QChar('x') << QRect(0, 10, 50, 40);
MainWindow w;
w.show();
return a.exec();
}