一个进程安全的日志类, Linux实现

项目中需要分类日志功能,且日志由多个进程产生,所以写了这个类。

  1. #ifndefCAPPLOG_H_
  2. #defineCAPPLOG_H_
  3. #include"Generic.h"
  4. enumLOG_TYPE
  5. {
  6. LOG_DEAGNOSTIC_MSG=0x00000000,
  7. LOG_EVENT=0x00000001,
  8. LOG_ACTIVITY=0x00000002,
  9. LOG_ERROR=0x00000004,
  10. };
  11. classCAppLog{
  12. public:
  13. CAppLog();
  14. virtual~CAppLog();
  15. staticvoidappendDeagnosticMsg(constchar*lpszFmt,...);
  16. staticvoidappendEvent(constchar*lpszFmt,...);
  17. staticvoidappendActivity(constchar*lpszFmt,...);
  18. staticvoidappendError(constchar*lpszFmt,...);
  19. private:
  20. staticsem_t*s_pLogFileSem;
  21. staticvoidappend(LOG_TYPEemType,constchar*lpszText);
  22. };
  23. #endif/*CAPPLOG_H_*/

以下是它的实现

  1. /*
  2. *CAppLog.cpp
  3. *
  4. *Createdon:Jan1,2009
  5. *Author:root
  6. */
  7. #include"CAppLog.h"
  8. #include"CSystemHelper.h"
  9. #defineLOG_SEM_NAME"LogFileSem"
  10. sem_t*CAppLog::s_pLogFileSem=NULL;
  11. CAppLogg_oAppLog;
  12. CAppLog::CAppLog(){
  13. if(s_pLogFileSem==NULL)
  14. {
  15. s_pLogFileSem=sem_open(LOG_SEM_NAME,O_CREAT,0666,1);
  16. }
  17. }
  18. CAppLog::~CAppLog(){
  19. if(s_pLogFileSem!=NULL)
  20. {
  21. sem_close(s_pLogFileSem);
  22. s_pLogFileSem=NULL;
  23. }
  24. }
  25. voidCAppLog::append(LOG_TYPEemType,constchar*lpszText)
  26. {
  27. charszBuffer[10240]={0};
  28. intnRet=readlink("/proc/self/exe",szBuffer,sizeof(szBuffer));
  29. if(nRet<=0||nRet>=PATH_MAX)
  30. return;
  31. stringstrTemp(szBuffer);
  32. stringstrDir=strTemp.substr(0,strTemp.rfind('/')+1);
  33. stringstrExe=strTemp.substr(strTemp.rfind('/')+1);
  34. time_tulNow={0};
  35. time(&ulNow);
  36. tm*pNow=localtime(&ulNow);
  37. memset(szBuffer,0,sizeof(szBuffer));
  38. sprintf(szBuffer,"%sLog/%04d/%04d-%02d/"
  39. ,strDir.c_str()
  40. ,1900+pNow->tm_year
  41. ,1900+pNow->tm_year
  42. ,1+pNow->tm_mon
  43. );
  44. CSystemHelper::createDirectory(szBuffer);
  45. sprintf(szBuffer,"%sLog/%04d/%04d-%02d/%04d-%02d-%02d.log"
  46. ,strDir.c_str()
  47. ,1900+pNow->tm_year
  48. ,1900+pNow->tm_year
  49. ,1+pNow->tm_mon
  50. ,1900+pNow->tm_year
  51. ,1+pNow->tm_mon
  52. ,pNow->tm_mday
  53. );
  54. sem_wait(s_pLogFileSem);
  55. {
  56. ofstreamstream(szBuffer,ios::out|ios::app);
  57. if(stream)
  58. {
  59. charszFormated[20480]={0};
  60. sprintf(szFormated,"\r\n%02d[%02d:%02d:%02dPID=%05dTID=%05ldEXE=%-15s]%s"
  61. ,emType
  62. ,pNow->tm_hour
  63. ,pNow->tm_min
  64. ,pNow->tm_sec
  65. ,getpid()
  66. ,(long)syscall(SYS_gettid)
  67. ,strExe.c_str()
  68. ,lpszText
  69. );
  70. stream<<szFormated;
  71. stream.flush();
  72. stream.close();
  73. }
  74. }
  75. sem_post(s_pLogFileSem);
  76. }
  77. voidCAppLog::appendDeagnosticMsg(constchar*lpszFmt,...)
  78. {
  79. va_listarg;
  80. va_start(arg,lpszFmt);
  81. charszBuffer[10240]={0};
  82. vsprintf(szBuffer,lpszFmt,arg);
  83. va_end(arg);
  84. CAppLog::append(LOG_DEAGNOSTIC_MSG,szBuffer);
  85. }
  86. voidCAppLog::appendEvent(constchar*lpszFmt,...)
  87. {
  88. va_listarg;
  89. va_start(arg,lpszFmt);
  90. charszBuffer[10240]={0};
  91. vsprintf(szBuffer,lpszFmt,arg);
  92. va_end(arg);
  93. CAppLog::append(LOG_EVENT,szBuffer);
  94. }
  95. voidCAppLog::appendActivity(constchar*lpszFmt,...)
  96. {
  97. va_listarg;
  98. va_start(arg,lpszFmt);
  99. charszBuffer[10240]={0};
  100. vsprintf(szBuffer,lpszFmt,arg);
  101. va_end(arg);
  102. CAppLog::append(LOG_ACTIVITY,szBuffer);
  103. }
  104. voidCAppLog::appendError(constchar*lpszFmt,...)
  105. {
  106. va_listarg;
  107. va_start(arg,lpszFmt);
  108. charszBuffer[10240]={0};
  109. vsprintf(szBuffer,lpszFmt,arg);
  110. va_end(arg);
  111. CAppLog::append(LOG_ERROR,szBuffer);
  112. }


使用起来很简单,将类加入到工程,然后在需要的地方包含此类的头文件,然后直接调用静态方法。这里用到了一个辅助类的函数 CSystemHelper::createDirectory,它的实现如下:

  1. voidCSystemHelper::createDirectory(constchar*lpszDir)
  2. {
  3. stringstrDir(lpszDir);
  4. intnIndex=0;
  5. while(nIndex!=string::npos)
  6. {
  7. intnFind=strDir.find("/",nIndex+1);
  8. stringstrTemp=strDir.substr(0,nFind+1);
  9. DIR*dir=opendir(strTemp.c_str());
  10. if(dir!=NULL)
  11. closedir(dir);
  12. else
  13. mkdir(strTemp.c_str(),S_IRWXU|S_IRWXG|S_IROTH|S_IXOTH);
  14. nIndex=nFind;
  15. }
  16. }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值