在做桌面程序时候,记录日志是一种很好的错误排查方法,特别是离线系统。
在重要的方法上,往往需要记录进入此方法和离开此方法的日志,用于执行效率、是否崩溃的判断。
假设,对于日志的记录,存在如下方法:
// 省略部分
class Log
{
public:
static void log(LogLevel logLevel, QString functionName, QString message);
private:
Log() = delete;
Log(const Log& other) = delete;
Log &operator=(const Log& other) = delete;
};
#define LOG Log::log
2.2 记录一条日志
记录一条日志,调用如下方法:
LOG(LL_INFO, "VideoPrecessThread::run", "Enter function.");
2.3 在方法上的使用
例如,有一个重要的方法VideoPrecessThread::run
,需要记录进入和离开此方法方法的痕迹,如下所示:
void VideoPrecessThread::run()
{
LOG(LL_INFO, "VideoPrecessThread::run", "Enter function.");
// 省略部分
LOG(LL_INFO, "VideoPrecessThread::run", "Leave function.");
}
3. 问题分析
3.1 问题所在
这样可能存在如下的问题:
- 这个方法中存在多个返回,那么需要多处记录离开的痕迹,多、重复、容易漏记
- 如果带有返回值的情况,需要在真正离开方法之前就记录
对于上述的第2种情况,如下所示:
bool VideoPrecessThread::check()
{
LOG(LL_INFO, "VideoPrecessThread::run", "Enter function.");
// 省略部分
LOG(LL_INFO, "VideoPrecessThread::run", "Leave function."); // 1
return true; // 2
}
在上面的代码中,在“2”处才真正离开,但是在“1”就记录了离开。
3.2 可能的解决办法观察上面的函数,有什么方法能够方便记录呢?
有一种方法就是利用对象的生命周期,如果在方法的最开始的时候创建一个对象,如果不是通过指针new出来的,那么它的生命周期将在执行完当前方法时候结束,就会进行析构,那么就可以创建一个对象,在其构造函数里面记录进入此函数的方法,在析构中记录离开的方法,那么就能满足这种要求。
头文件FunctionTrackerLogger.h
:
#ifndef FUNCTIONTRACKERLOGGER_H
#define FUNCTIONTRACKERLOGGER_H
#include
#include
class FunctionTrackerLogger
{
public:
FunctionTrackerLogger(QString functionName);
~FunctionTrackerLogger();
private:
QString functionName;
};
#endif // FUNCTIONTRACKERLOGGER_H
源文件FunctionTrackerLogger.cpp
:
#include "FunctionTrackerLogger.h"
#include "Log.h"
FunctionTrackerLogger::FunctionTrackerLogger(QString functionName)
{
this->functionName = functionName;
LOG(LL_INFO, functionName, "Enter funtion.");
}
FunctionTrackerLogger::~FunctionTrackerLogger()
{
LOG(LL_INFO, functionName, "Leave funtion.");
}
调用的时候的使用:
bool VideoPrecessThread::check()
{
FunctionTrackerLogger logger = "VideoPrecessThread::check";
if(条件1)
{
return false; // 1
}
if(条件2)
{
return false; // 2
}
return true; // 3
}
这样无论在上述的1、2、3那处退出,都能得到如下等效的两条日志:
LOG(LL_INFO, "VideoPrecessThread::check", "Enter funtion.");
LOG(LL_INFO, "VideoPrecessThread::check", "Leave funtion.");
如果代码在这个函数执行中崩溃,那么只能得到进入函数的记录。
5. 带参数的方法的记录对于带参数的方法的记录,不在这里累赘叙述,详见《C++中跟踪执行方法的一种简便日志记录方法(补充参数记录)》一文。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)