1.在log.h中定义了一个LOG打印函数,利用QT自己的机制 qlogging,将自己想打印的Log打输送到QMessage logger中
#define LOGD(msg) {qDebug()<<QString("[%1] [%2] [D] [%3] %4") \
.arg(CURRENT_TIME_MS_LOG)\
.arg(THREAD_ID , 4) \
.arg(QString(TAG).mid(0,20) , 20 , QChar(' ')) \
.arg((msg));};
2.利用qInstallMessageHandler来获取QMessage logger中输入的信息,利用signal emitLogPrint将数据分类、打印和记录
static void myMessageOutput(QtMsgType type,
const QMessageLogContext &context,
const QString &msg)
{
Q_UNUSED(context)
LogServer::instance()->emitLogPrint(int(type) , msg + "\n");
fprintf((type == QtInfoMsg ? stdout : stderr),
"%s\n", msg.toStdString().c_str());
}
qInstallMessageHandler(myMessageOutput);
3.我想在不改变大致框架的情况下,修改记录Log的level
enum MsgType {
DebugLevel,
InfoLevel,
WarningLevel,
CriticalLevel,
};
#define LOGD(msg) if (DebugLevel >= Variable) {qDebug()<<QString("[%1] [%2] [D] [%3] %4") \
.arg(CURRENT_TIME_MS_LOG)\
.arg(THREAD_ID , 4) \
.arg(QString(TAG).mid(0,20) , 20 , QChar(' ')) \
.arg((msg));};
4.做了以下的尝试:
- 不修改#define 的使用方式使用全局变量来修改variable,判断是否执行函数体;
- 将#define修改为inline + 使用全局变量来修改variable,判断是否执行函数体;
- 定义一个class中存在一个static变量,通过静态成员变量来判断是否执行函数体;
5.存在以下问题
- 在.h中定义全局变量会因为.h被多次include而导致重定义;
- 在.h中声明extern,在log.cpp中定义,会因为多个其他dll会调用log.h中的LOGD导致未定义错误;
- 修改#define 为inline会因为LOGD多次使用时没有主动添加";"导致修改过多;
- 增加一个class使用static成员变量也存在会因为多个其他dll会调用log.h中的LOGD导致未定义错误;
6.最终解决办法
- 还是使用静态成员变量,但是将类export出去,给所有的dll共享;
-
enum MsgType { DebugLevel, InfoLevel, WarningLevel, CriticalLevel, }; #ifdef UTIL_LIBRARY_EXPORT #define UTIL_LIBRARY_API Q_DECL_EXPORT #else #define UTIL_LIBRARY_API Q_DECL_IMPORT #endif class UTIL_LIBRARY_API LogLevel { public: static QAtomicInt currentLogLevel; };
-
在.pro文件中使用DEFINES += UTIL_LIBRARY_EXPORT,定义UTIL_LIBRARY_EXPORT
-
在.cpp中定义
QAtomicInt UTIL_LIBRARY_API LogLevel::currentLogLevel = 0;