用C++实现一个Log系统

注册 Vultr VPS 送你10美金 免费玩4个月


提要

最近在写一些C++的图形代码,在调试和测试过程中都会需要在终端打印一些信息出来。之前的做法是直接用

std::cout<<"Some Word"<<std::endl;

这样做其实非常的麻烦,每次都要打很多的字母还有特殊符号,除去我要打印的内容,还需要按下28下键盘,简直不能忍!

参考Unity里面的打log的方式

Debug.Log("Some Word");

或者Qt中的处理方式

qDebug() << "Some Word";

这两种都方便太多。

今天要实现的Log系统需要满足的特性有:

1.很方便地在终端打印各种类型数据信息;

2.可以区分Log等级;

3.打印信息的同时能够提供打印语句的文件,函数名,行号

类说明

简单地画了下UML,主要分为下面几个类

简单说一下类的作用

MessageLogContext

记录Log的上下文,也就是Log处在的文件,函数名,行号。

MessageLogger

主要的Log类,提供了上次调用的一些接口,注意一下这个宏比较有意思

qDebug MessageLogger(__FILE__, __FUNCTION__, __LINE__).debug

这样当使用

qDebug()

的时候,

宏替换就直接转换成了MessageLogger的构造函数

MessageLogger(__FILE__, __FUNCTION__, __LINE__).debug()

等于是先构造MessageLogger,然后调用这个对象的debug()方法。

Debug

具体处理Debug信息的类。

用了一个内部Stream结构体来记录Debug信息,记得在使用前要new,析构的时候delete掉。

重构了很多的<<方法,就是为了能处理多种数据类型,包括自定义的类。还可以通过模板来打印stl里面的东西。

LogToConsole是将log信息打印到终端的函数,在析构函数中会被调用。如果想要实现更加炫酷的打印log方式(各种颜色),扩展这个函数就好了。

整个Log的流程如下图

测试代码

void DebugTest()
{
	Vector2 v = Vector2(1, 1);
	Vector2 v2 = Vector2(2, 1);
	Vector3 v3 = Vector3(0, 2, 1);
	Vector3 v4 = Vector3(0, 2, 1);
	Vector3 v5 = Vector3(23, 112, 22);
	Vector3 v6 = Vector3(23, 112, 22);
	std::vector<Vector3> vec;
	vec.push_back(v3);
	vec.push_back(v4);
	vec.push_back(v5);
	vec.push_back(v6);
	vec.push_back(v6);
	vec.push_back(v6);
	vec.push_back(v6);
	vec.push_back(v6);
	std::string testStr = "vector Test";
	qDebug() << "Hello Debug";
	qDebug() <<""<< v << v2<< v3;
	qDebug() << v3;
	qWarning() << vec;
}

运行结果

代码清单

MessageLogContext.h

注册 Vultr VPS 送你10美金 免费玩4个月