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

写程序的过程中肯定会遇到错误,怎么去发现错误?简单的办法是自己去看代码的执行过程,发现一些错误所在
的点。但是很多时候这一招不管用,怎么办?只好在关键点上使用printf函数去打印一些变量的值或提示信息来发现一
些错误。最后当然是使用gdb去调试啦,不过gdb不是今天的主角。而是怎么简单的使用printf来记录和分类一些程序
日志信息。
       下面我将介绍下怎么使用printf打印一些日志,让我们在调试的时候更快的发现程序的错误。我们约定可以使用
[ERRORS] ,[WARNINGS] ,[INFO]标识分别来区分错误,警告,信息三类日志信息,例如:
 


  1.  
  2. fd=open("/home/user/debug/config.ini",O_RDONLY);
     
  3. if(fd<=0)
     
  4. {
     
  5.        printf("[ERRORS][OpenFile.c][Init()] open file failed!/n");
     
  6.        return EXCEPTION;
     
  7. }
复制代码



在 printf("[ERRORS][OpenFile.c][Init()] open file failed!/n")中我们可以明确知道的信息是当前打印的改行日志是
属于错误日志,位于文件OpenFile.c的Init()函数当中。

 

  1. int Ret;
     
  2. char szText[1024];
     

  3.  
  4. Ret=0;
     
  5. memset(szText,0,sizeof(szText));
     

  6.  
  7. #ifdef __DEBUG__
     
  8.       printf("[INFO][Convertion.c][Convert()] Before Convert:%s/n",szText);
     
  9. #endif
     

  10.  
  11. nRet=Convert(szText);
     
  12. if(nRet==EXCEPTION)
     
  13. {
     
  14.       printf("[INFO][Convertion.c][Convert()] Convert failed!/n");
     
  15.       return EXCEPTION;
     
  16. }
     

  17.  
  18. #ifdef __DEBUG__
     
  19.       printf("[INFO][Convertion.c][Convert()] After Convert:%s/n",szText);
     
  20. #endif
复制代码


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

下面为大家提供本人自己整理的一个比较成熟日志打印程序:
      说明:
                程序运行会在$HOME/mysrc/test路径下创建一个名为log的文件夹,之后会在log文件夹下创建以当天
系统时间为名称的日志文件,例如系统时间为2011年2月19日,则当天的日志文件名为:20110219.log。
 

  1. /*********************************************************
     
  2. *Author: lizhangjie
     
  3. *Date: 2011-02-15
     
  4. *Description: Log Printging Functions
     
  5. *********************************************************/
     

  6.  
  7. #include "pub.h"
     

  8.  
  9. /*这个是全局日志文件指针,定义并初始化*/
     
  10. static FILE *gpLogFile=NULL;
     

  11.  
  12. char *GetSystemTime()
     
  13. {
     
  14.       struct tm struTmNow;
     
  15.       time_t struTimeNow;
     
  16.       static char szSystemTime[128];
     

  17.  
  18.      memset(szSystemTime,'/0',sizeof(szSystemTime));
     

  19.  
  20.      if(time(&struTimeNow)==(time_t)-1)
     
  21.      {
     
  22.             printf("[ERRORS][Log.c][SystemTime()] time() failed!/n");
     
  23.             return NULL;
     
  24.       }
     

  25.  
  26.       /*转换成本地时间*/
     
  27.       struTmNow=*localtime(&struTimeNow);
     

  28.  
  29.       sprintf(szSystemTime,"%04d%02d%02d",struTmNow.tm_year+1900,/
     
  30.       struTmNow.tm_mon+1,struTmNow.tm_mday);
     

  31.  
  32. #ifdef __DEBUG__
     
  33.       printf("[INFO][Log.c][SystemTime()] 成功获取系统时间:%s/n",szSystemTime);
     
  34. #endif
     

  35.  
  36.       return szSystemTime;
     
  37. }
     

  38.  
  39. char *GetPrtLogFileName()
     
  40. {
     
  41.       /*definition*/
     
  42.       struct tm struTmNow;
     
  43.       time_t struTimeNow;
     
  44.       static char szFileName[256];
     

  45.  
  46.       /*initializing*/
     
  47.       memset(szFileName,0,sizeof(szFileName));
     
  48.       if(time(&struTimeNow)==(time_t)-1)
     
  49.       {
     
  50.             printf("[ERRORS][Log.c][GetPrtLogFileName()] time() failed!/n");
     
  51.             return NULL;
     
  52. }
     

  53.  
  54.       struTmNow=*localtime(&struTimeNow);
     
  55.       sprintf(szFileName,"%04d%02d%02d.log",struTmNow.tm_year+1900,/
     
  56.       struTmNow.tm_mon+1,struTmNow.tm_mday);
     

  57.  
  58. #ifdef __DEBUG__
     
  59.       printf("[INFO][Log.c][GetPrtLogFileName()] 成功组成文件名:%s/n",szFileName);
     
  60. #endif
     

  61.  
  62.       return szFileName;
     
  63. }
     

  64.  
  65. int InitPrtLogFile()
     
  66. {
     
  67.       /*definition*/
     
  68.       /*日志文件路径*/
     
  69.       char szFilePath[256];
     
  70.       static char szFileName[256];
     

  71.  
  72.       /*initializing*/
     
  73.       memset(szFilePath,0,sizeof(szFilePath));
     
  74.       memset(szFileName,0,sizeof(szFilePath));
     

  75.  
  76.       /*如果日志文件已打开,返回NORMAL*/
     
  77.       if(gpLogFile!=NULL)
     
  78.       {
     
  79.             if(access(szFileName,F_OK|W_OK)==0)
     
  80.             {
     
  81.                   if(strcmp(szFileName,GetPrtLogFileName())==0)
     
  82.                   {
     
  83.                         printf("[INFO][Log.c][InitPrtLogFile()] 日志文件已存在!/n");
     
  84.                         return NORMAL;
     
  85.                   }
     
  86.             }
     
  87.       }
     

  88.  
  89.       /*获取HOME环境变量*/
     
  90.       if(getenv("HOME"))
     
  91.       {
     
  92.             /*log日志文件夹路径位于$HOME/log*/
     
  93.             sprintf(szFilePath,"%s/mysrc/test/log",getenv("HOME"));
     

  94.  
  95.       #ifdef __DEBUG__
     
  96.             printf("组成路径:%s/n",szFilePath);
     
  97.       #endif
     

  98.  
  99.       /*在指定目录下创建文件夹*/
     
  100.       if((mkdir(szFilePath,S_IRUSR|S_IWUSR|S_IXUSR)==-1)&&(errno!=EEXIST))
     
  101.       {
     
  102.             printf("[ERRORS][Log.c][InitPtrLogFile()] mkdir() failed!/n");
     
  103.             return EXCEPTION;
     
  104.       }
     

  105.  
  106. #ifdef __DEBUG__
     
  107.       printf("[INFO][Log.c][InitPtrLogFile()] log文件夹创建成功!/n");
     
  108. #endif
     

  109.  
  110.       sprintf(szFileName,"%s/mysrc/test/log/%s",getenv("HOME"),GetPrtLogFileName());
     
  111.       printf("[INFO][Log.c][InitPrtLogFile()] 路径和文件名获取成功:%s/n",szFileName);
     
  112.       }
     
  113.       else
     
  114.       {
     
  115.             printf("[ERRORS][Log.c][InitPtrLogFile()] getenv() failed!/n");
     
  116.             return EXCEPTION;
     
  117.       }
     

  118.  
  119.       /*关闭日志文件*/
     
  120.       if(gpLogFile!=NULL)
     
  121.       fclose(gpLogFile);
     

  122.  
  123.       gpLogFile=fopen(szFileName,"a+");
     
  124.       if(gpLogFile==NULL)
     
  125.       {
     
  126.             printf("[ERRORS][Log.c][InitPtrLogFile()] fopen() failed!/n");
     
  127.             return EXCEPTION;
     
  128.       }
     

  129.  
  130.       if(chmod(szFileName,S_IRUSR|S_IWUSR)==-1)
     
  131.       {
     
  132.             printf("[ERRORS][Log.c][InitPtrLogFile()] chmod() failed!/n");
     
  133.             return EXCEPTION;
     
  134.       }
     

  135.  
  136.       return NORMAL;
     
  137. }
     

  138.  

  139.  
  140. void PrtLog(char *pszDebugStr,char *pszFormatStr,...)
     
  141. {
     
  142.       /*definition*/
     
  143.       va_list listArg;
     
  144.       static int nFileLineNum;
     

  145.  
  146.       if(InitPrtLogFile()==NORMAL)
     
  147.       {
     
  148.             va_start(listArg,pszFormatStr);
     

  149.  
  150.             /*将时间和打印位置写入日志文件*/
     
  151.             fprintf(gpLogFile,"[%s]%s/n/t",GetSystemTime(),pszDebugStr);
     

  152.  
  153.             /*将日志内容写入日志文件*/
     
  154.             vfprintf(gpLogFile,pszFormatStr,listArg);
     

  155.  
  156.             va_end(listArg);
     

  157.  
  158.             /*将内存缓冲中的数据回写到硬盘*/
     
  159.             fflush(gpLogFile);
     

  160.  
  161.             /*日志文件行数超过限制时做相应处理*/
     
  162.             if(nFileLineNum++>LOG_FILE_MAX_LINE_NUM)
     
  163.             {
     
  164.                   /*文件指针重新定位到文件打开时的初始位置*/
     
  165.                   fseek(gpLogFile,0,SEEK_SET);
     
  166.                   /*日志文件行数清零*/
     
  167.                   nFileLineNum=0;
     
  168.             }
     
  169.       }
     
  170. }

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值