C++中跟踪执行方法的一种简便日志记录方法

14 篇文章 0 订阅

1. 缘起

在做桌面程序时候,记录日志是一种很好的错误排查方法,特别是离线系统。
在重要的方法上,往往需要记录进入此方法和离开此方法的日志,用于执行效率、是否崩溃的判断。

2. 普通方法

2.1 方法定义

假设,对于日志的记录,存在如下方法:

// 省略部分
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 问题所在

这样可能存在如下的问题:

  1. 这个方法中存在多个返回,那么需要多处记录离开的痕迹,多、重复、容易漏记
  2. 如果带有返回值的情况,需要在真正离开方法之前就记录

对于上述的第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出来的,那么它的生命周期将在执行完当前方法时候结束,就会进行析构,那么就可以创建一个对象,在其构造函数里面记录进入此函数的方法,在析构中记录离开的方法,那么就能满足这种要求。

4. 使用的方法

头文件FunctionTrackerLogger.h

#ifndef FUNCTIONTRACKERLOGGER_H
#define FUNCTIONTRACKERLOGGER_H

#include <QString>
#include <QMap>

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++中跟踪执行方法的一种简便日志记录方法(补充参数记录)》一文。

6. 扩展

通过使用QSharedPointer自定义析构函数,来进行离开日志的记录,参见《使用C++利用对象的生命周期来记录离开方法的日志》一文。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值