您的位置:首页 > 运维架构 > Linux

Linux中调试程序使用打印日志纠错的技巧

2011-02-28 20:46 951 查看
写程序的过程中肯定会遇到错误,怎么去发现错误?简单的办法是自己去看代码的执行过程,发现一些错误所在

的点。但是很多时候这一招不管用,怎么办?只好在关键点上使用printf函数去打印一些变量的值或提示信息来发现一

些错误。最后当然是使用gdb去调试啦,不过gdb不是今天的主角。而是怎么简单的使用printf来记录和分类一些程序

日志信息。

下面我将介绍下怎么使用printf打印一些日志,让我们在调试的时候更快的发现程序的错误。我们约定可以使用

[ERRORS] ,[WARNINGS] ,[INFO]标识分别来区分错误,警告,信息三类日志信息,例如:

fd=open("/home/user/debug/config.ini",O_RDONLY);

if(fd<=0)

{

printf("[ERRORS][OpenFile.c][Init()] open file failed!/n");

return EXCEPTION;

}

复制代码

在 printf("[ERRORS][OpenFile.c][Init()] open file failed!/n")中我们可以明确知道的信息是当前打印的改行日志是

属于错误日志,位于文件OpenFile.c的Init()函数当中。

int Ret;

char szText[1024];

Ret=0;

memset(szText,0,sizeof(szText));

#ifdef __DEBUG__

printf("[INFO][Convertion.c][Convert()] Before Convert:%s/n",szText);

#endif

nRet=Convert(szText);

if(nRet==EXCEPTION)

{

printf("[INFO][Convertion.c][Convert()] Convert failed!/n");

return EXCEPTION;

}

#ifdef __DEBUG__

printf("[INFO][Convertion.c][Convert()] After Convert:%s/n",szText);

#endif

复制代码

在这段代码中,我们可以通过在对用头文件中添加#define __DEBUG__的宏定义来达到打印调试日志信息。

下面为大家提供本人自己整理的一个比较成熟日志打印程序:

说明:

程序运行会在$HOME/mysrc/test路径下创建一个名为log的文件夹,之后会在log文件夹下创建以当天

系统时间为名称的日志文件,例如系统时间为2011年2月19日,则当天的日志文件名为:20110219.log。

/*********************************************************

*Author: lizhangjie

*Date: 2011-02-15

*Description: Log Printging Functions

*********************************************************/

#include "pub.h"

/*这个是全局日志文件指针,定义并初始化*/

static FILE *gpLogFile=NULL;

char *GetSystemTime()

{

struct tm struTmNow;

time_t struTimeNow;

static char szSystemTime[128];

memset(szSystemTime,'/0',sizeof(szSystemTime));

if(time(&struTimeNow)==(time_t)-1)

{

printf("[ERRORS][Log.c][SystemTime()] time() failed!/n");

return NULL;

}

/*转换成本地时间*/

struTmNow=*localtime(&struTimeNow);

sprintf(szSystemTime,"%04d%02d%02d",struTmNow.tm_year+1900,/

struTmNow.tm_mon+1,struTmNow.tm_mday);

#ifdef __DEBUG__

printf("[INFO][Log.c][SystemTime()] 成功获取系统时间:%s/n",szSystemTime);

#endif

return szSystemTime;

}

char *GetPrtLogFileName()

{

/*definition*/

struct tm struTmNow;

time_t struTimeNow;

static char szFileName[256];

/*initializing*/

memset(szFileName,0,sizeof(szFileName));

if(time(&struTimeNow)==(time_t)-1)

{

printf("[ERRORS][Log.c][GetPrtLogFileName()] time() failed!/n");

return NULL;

}

struTmNow=*localtime(&struTimeNow);

sprintf(szFileName,"%04d%02d%02d.log",struTmNow.tm_year+1900,/

struTmNow.tm_mon+1,struTmNow.tm_mday);

#ifdef __DEBUG__

printf("[INFO][Log.c][GetPrtLogFileName()] 成功组成文件名:%s/n",szFileName);

#endif

return szFileName;

}

int InitPrtLogFile()

{

/*definition*/

/*日志文件路径*/

char szFilePath[256];

static char szFileName[256];

/*initializing*/

memset(szFilePath,0,sizeof(szFilePath));

memset(szFileName,0,sizeof(szFilePath));

/*如果日志文件已打开,返回NORMAL*/

if(gpLogFile!=NULL)

{

if(access(szFileName,F_OK|W_OK)==0)

{

if(strcmp(szFileName,GetPrtLogFileName())==0)

{

printf("[INFO][Log.c][InitPrtLogFile()] 日志文件已存在!/n");

return NORMAL;

}

}

}

/*获取HOME环境变量*/

if(getenv("HOME"))

{

/*log日志文件夹路径位于$HOME/log*/

sprintf(szFilePath,"%s/mysrc/test/log",getenv("HOME"));

#ifdef __DEBUG__

printf("组成路径:%s/n",szFilePath);

#endif

/*在指定目录下创建文件夹*/

if((mkdir(szFilePath,S_IRUSR|S_IWUSR|S_IXUSR)==-1)&&(errno!=EEXIST))

{

printf("[ERRORS][Log.c][InitPtrLogFile()] mkdir() failed!/n");

return EXCEPTION;

}

#ifdef __DEBUG__

printf("[INFO][Log.c][InitPtrLogFile()] log文件夹创建成功!/n");

#endif

sprintf(szFileName,"%s/mysrc/test/log/%s",getenv("HOME"),GetPrtLogFileName());

printf("[INFO][Log.c][InitPrtLogFile()] 路径和文件名获取成功:%s/n",szFileName);

}

else

{

printf("[ERRORS][Log.c][InitPtrLogFile()] getenv() failed!/n");

return EXCEPTION;

}

/*关闭日志文件*/

if(gpLogFile!=NULL)

fclose(gpLogFile);

gpLogFile=fopen(szFileName,"a+");

if(gpLogFile==NULL)

{

printf("[ERRORS][Log.c][InitPtrLogFile()] fopen() failed!/n");

return EXCEPTION;

}

if(chmod(szFileName,S_IRUSR|S_IWUSR)==-1)

{

printf("[ERRORS][Log.c][InitPtrLogFile()] chmod() failed!/n");

return EXCEPTION;

}

return NORMAL;

}

void PrtLog(char *pszDebugStr,char *pszFormatStr,...)

{

/*definition*/

va_list listArg;

static int nFileLineNum;

if(InitPrtLogFile()==NORMAL)

{

va_start(listArg,pszFormatStr);

/*将时间和打印位置写入日志文件*/

fprintf(gpLogFile,"[%s]%s/n/t",GetSystemTime(),pszDebugStr);

/*将日志内容写入日志文件*/

vfprintf(gpLogFile,pszFormatStr,listArg);

va_end(listArg);

/*将内存缓冲中的数据回写到硬盘*/

fflush(gpLogFile);

/*日志文件行数超过限制时做相应处理*/

if(nFileLineNum++>LOG_FILE_MAX_LINE_NUM)

{

/*文件指针重新定位到文件打开时的初始位置*/

fseek(gpLogFile,0,SEEK_SET);

/*日志文件行数清零*/

nFileLineNum=0;

}

}

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: