log.cpp 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194
  1. #include "stdafx.h"
  2. #include "log.h"
  3. //#include <sys/file.h>
  4. //#include <stdarg.h>
  5. #include <time.h>
  6. #include <stdlib.h>
  7. //#include <string.h>
  8. //#include <errno.h>
  9. #include <io.h>
  10. //#include <sys/stat.h>
  11. #include <direct.h>
  12. #ifndef R_OK
  13. #define R_OK 4
  14. #endif
  15. #ifndef W_OK
  16. #define W_OK 2
  17. #endif
  18. #ifndef X_OK
  19. #define X_OK 6
  20. #endif
  21. #ifndef F_OK
  22. #define F_OK 0
  23. #endif
  24. Log_Writer WARN_W;
  25. Log_Writer INFO_W;
  26. char Log_Writer::m_buffer[_LOG_BUFFSIZE] = {0};
  27. bool log_init(LogLevel l, const char* p_modulename, const char* p_logdir)
  28. {
  29. //如果路径存在文件夹,则判断是否存在
  30. if (_access(p_logdir, 0) == -1)
  31. {
  32. if (mkdir(p_logdir ) < 0)
  33. fprintf(stderr, "create folder failed\n");
  34. }
  35. char _location_str[MAX_PATH];
  36. _snprintf(_location_str, MAX_PATH, "%s\\%s.log", p_logdir, p_modulename);
  37. INFO_W.loginit(l, _location_str);
  38. _snprintf(_location_str, MAX_PATH, "%s\\%s.error", p_logdir, p_modulename);
  39. //warning级别以上日志去WARN_W 去向由宏决定的 请见macro_define.h
  40. if(l > LL_WARNING)
  41. WARN_W.loginit(l, _location_str);
  42. else
  43. WARN_W.loginit(LL_WARNING, _location_str);
  44. return true;
  45. }
  46. const char* Log_Writer::logLevelToString(LogLevel l)
  47. {
  48. switch ( l )
  49. {
  50. case LL_DEBUG:
  51. return "DEBUG";
  52. case LL_TRACE:
  53. return "TRACE";
  54. case LL_NOTICE:
  55. return "NOTICE";
  56. case LL_WARNING:
  57. return "WARN" ;
  58. case LL_ERROR:
  59. return "ERROR";
  60. default:
  61. return "UNKNOWN";
  62. }
  63. }
  64. bool Log_Writer::checklevel(LogLevel l)
  65. {
  66. if(l >= m_system_level)
  67. return true;
  68. else
  69. return false;
  70. }
  71. bool Log_Writer::loginit(LogLevel l, const char *filelocation, bool append, bool issync)
  72. {
  73. MACRO_RET(NULL != fp, false);
  74. m_system_level = l;
  75. m_isappend = append;
  76. m_issync = issync;
  77. if(strlen(filelocation) >= (sizeof(m_filelocation) -1))
  78. {
  79. fprintf(stderr, "the path of log file is too long:%d limit:%d\n", strlen(filelocation), sizeof(m_filelocation) -1);
  80. exit(0);
  81. }
  82. //本地存储filelocation 以防止在栈上的非法调用调用
  83. strncpy(m_filelocation, filelocation, sizeof(m_filelocation));
  84. m_filelocation[sizeof(m_filelocation) -1] = '\0';
  85. if('\0' == m_filelocation[0])
  86. {
  87. fp = stdout;
  88. fprintf(stderr, "now all the running-information are going to put to stderr\n");
  89. return true;
  90. }
  91. fp = fopen(m_filelocation, append ? "a":"w");
  92. if(fp == NULL)
  93. {
  94. fprintf(stderr, "cannot open log file,file location is %s\n", m_filelocation);
  95. exit(0);
  96. }
  97. //setvbuf (fp, io_cached_buf, _IOLBF, sizeof(io_cached_buf)); //buf set _IONBF _IOLBF _IOFBF
  98. setvbuf (fp, (char *)NULL, _IOLBF, _LOG_BUFFSIZE);
  99. fprintf(stderr, "now all the running-information are going to the file %s\n", m_filelocation);
  100. return true;
  101. }
  102. int Log_Writer::premakestr(char* m_buffer, LogLevel l)
  103. {
  104. time_t now;
  105. now = time(&now);;
  106. struct tm vtm = *localtime(&now);
  107. // 获取今年年份;
  108. //__time64_t gmt = time(NULL); // 获取当前日历时间(1900-01-01开始的Unix时间戳);
  109. //struct tm gmtm = { 0 };
  110. //localtime_s(&gmtm, &gmt); // 时间戳转成本地时间;
  111. return _snprintf(m_buffer, _LOG_BUFFSIZE, "%s: %02d-%02d %02d:%02d:%02d ", logLevelToString(l),
  112. vtm.tm_mon + 1, vtm.tm_mday, vtm.tm_hour, vtm.tm_min, vtm.tm_sec);
  113. }
  114. bool Log_Writer::log(LogLevel l, char* logformat, ...)
  115. {
  116. MACRO_RET(!checklevel(l), false);
  117. int _size;
  118. int prestrlen = 0;
  119. memset(m_buffer, 0, _LOG_BUFFSIZE);
  120. char * star = m_buffer;
  121. prestrlen = premakestr(star, l);
  122. star += prestrlen;
  123. va_list args = NULL;
  124. va_start(args, logformat);
  125. _size = _vstprintf_s(star, _LOG_BUFFSIZE - prestrlen, logformat, args);//_vstprintf_s _vsntprintf
  126. va_end(args);
  127. if(NULL == fp)
  128. fprintf(stderr, "%s", m_buffer);
  129. else
  130. _write(m_buffer, prestrlen + _size);
  131. return true;
  132. }
  133. bool Log_Writer::_write(char *_pbuffer, int len)
  134. {
  135. if(0 != _access(m_filelocation, W_OK))
  136. {
  137. AutoThreadSection _cs(&m_mutex);
  138. //锁内校验 access 看是否在等待锁过程中被其他线程loginit了 避免多线程多次close 和init
  139. if(0 != _access(m_filelocation, W_OK))
  140. {
  141. logclose();
  142. loginit(m_system_level, m_filelocation, m_isappend, m_issync);
  143. }
  144. }
  145. if(1 == fwrite(_pbuffer, len, 1, fp)) //only write 1 item
  146. {
  147. if(m_issync)
  148. fflush(fp);
  149. *_pbuffer='\0';
  150. }
  151. else
  152. {
  153. int x = errno;
  154. fprintf(stderr, "Failed to write to logfile. errno:%s message:%s", strerror(x), _pbuffer);
  155. return false;
  156. }
  157. return true;
  158. }
  159. LogLevel Log_Writer::get_level()
  160. {
  161. return m_system_level;
  162. }
  163. bool Log_Writer::logclose()
  164. {
  165. if(fp == NULL)
  166. return false;
  167. fflush(fp);
  168. fclose(fp);
  169. fp = NULL;
  170. return true;
  171. }