`
小糟老头
  • 浏览: 9623 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
文章分类
社区版块
存档分类
最新评论

linux c++ 日志小技巧:打印变量名和变量值。跟踪函数出口入口

阅读更多

如果在log中记录一个变量的值,如: 

const char* url = “iteye.com”;

一般要写:   printf("url = %s",url);

当变量比较多的时候,万一把format里面的%s写错了,是会造成严重问题的。

更不好的地方在于:这么写麻烦罗嗦。基于程序员懒惰的天性,干脆省事,不写log

 

利于c、c++提供的宏  #,以及c++的函数重载,可以实现类型安全的观察变量

调用:

                  Watch(url) :

输出:        url=iteye.com

 

实例: 

string UniqKey::getUniqKey(const string& src)
{
	TraceMe(UniqKey);
	Watch(src);	
}

 输出:

 

enter UniqKey::getUniqKey
   
     getUniqKey src = “xxxxxxx"

exit UniqKey::getUniqKey

  

上面的traceMe,利于类的析构和初始化跟踪函数入口和出口,是常见技巧。这里特别的是在里面包含了__FUNCTION__

使用起来更加简单。只需写类名,即可自动带上函数名,免得每个手拷贝函数名的麻烦

 

优点:

      1. watch宏,类型安全,解决了printf里面的%s %d写错导致错误的问题

       2.直接用变量名写入log,隐形要求把变量名取得更有意义。同时带入了函数名字,一目了然

      3.TraceMe 宏,只需要写入类名,不许函数名。比常规的需要输类名加函数名简洁的多

 

 

#ifndef __SimpleLog_H
#define __SimpleLog_H

#include<string>
using namespace std;


#define Watch(VarName)\
	do{\
		const char * name=""#VarName; \
		char fullName[100]={0};\
		sprintf(fullName,"%s %s",__FUNCTION__,name);\
		Trace::GetInstance()->log(fullName, VarName); }while (0)



#define TraceMe(className)\
		const char * __name__=""#className; \
		char __functionName__[100]={0};\
		sprintf(__functionName__,"%s",__FUNCTION__);\
		Trace __traceMe__(__name__,__functionName__);


//this is a ruby like 'p'
void p(char* format,...);


class Trace
{
	
public:
	//Trace(const char * msg=NULL);
	Trace(const char * msg=NULL, const char* functionName=NULL);
	~Trace();
	//TODO: overload all the POD
	void log(const char * name, int value);

	//void log(const char * name, float value);
	void log(const char * name, const std::string& value);
	void log(const char * name, const char * value);
	//void log(const char * name, CObject value);

	static Trace* GetInstance();

public:
	const char * msg;
	const char * functionName;
	static Trace* instance;
};


#endif

 

#include "SimpleLog.h"

#include <stdio.h>
#include <stdarg.h>
//#include "Object.h"

using namespace std;

void p ( char *Format, ... )
{
    char logContent[80960]={0};
    va_list argList;
    va_start(argList, Format);
    vsnprintf(logContent, sizeof (logContent)-1, Format, argList);
    va_end(argList);
    puts(logContent);

    fflush(stdout);

}


Trace* Trace::instance = NULL;

//grep -v "< exit" |grep -v "> enter"
Trace::Trace(const char * msg, const char * functionName):msg(msg),functionName(functionName)
{
	
	if(msg!=NULL && functionName==NULL)
	{
		p("enter %s",msg);
	}
	if(msg!=NULL && functionName!=NULL)
	{
		p("enter %s::%s",msg,functionName);
	}
}


Trace::~Trace()
{
	
	if(msg!=NULL && functionName==NULL)
	{
		p("exit %s",msg);
	}
	
	if(msg!=NULL && functionName!=NULL)
	{
		p("exit %s::%s",msg,functionName);

	}

		
}

Trace* Trace::GetInstance()
{
	if(instance==NULL)
		instance=new Trace();
	return instance;
}


void Trace::log(const char * name, int value)
{
	p("%-5s[ %-15s]= %d","", name, value);
}



void Trace::log(const char * name, const string& value)
{
	log(name,value.c_str());

}
void Trace::log(const char * name, const char * value)
{
	p("%-5s[ %-15s]= %s","", name, value);
}


 

 

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics