log_single.c 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222
  1. #include "precompile.h"
  2. #include "log_single.h"
  3. #include "log_base.h"
  4. #include "log.h"
  5. #include "spinlock.h"
  6. #include "fileutil.h"
  7. #include "strutil.h"
  8. #include <winpr/string.h>
  9. typedef struct singlelogfactory_t singlelogfactory_t;
  10. typedef struct singlelog_t {
  11. logbase_t base;
  12. char *file_path;
  13. FILE *fp;
  14. LONG use_lock;
  15. lock_t lock;
  16. LONG flush;
  17. int first_record;
  18. }singlelog_t;
  19. struct singlelogfactory_t {
  20. logfactory_t base;
  21. };
  22. static void singlefilefactory_destroy(void *self)
  23. {
  24. singlelogfactory_t *fac = (singlelogfactory_t *)self;
  25. if (fac) {
  26. if (fac->base.name)
  27. free(fac->base.name);
  28. free(fac);
  29. }
  30. }
  31. static void* singlefilefactory_create_log(void *self, const char* inst)
  32. {
  33. singlelogfactory_t *fac = (singlelogfactory_t *)self;
  34. singlelog_t *log = MALLOC_T(singlelog_t);
  35. log->base.level = XLOG_LEVEL_ALL;
  36. log->base.factory = self;
  37. log->base.inst_name = _strdup(inst);
  38. log->file_path = 0;
  39. log->fp = NULL;
  40. log->use_lock = 0;
  41. log->flush = 1;
  42. log->first_record = 0;
  43. fastlock_init(log->lock);
  44. return log;
  45. }
  46. static int singlefilefactory_set_log_param(void *self,
  47. void *log,
  48. const char *key,
  49. const char *value)
  50. {
  51. singlelogfactory_t *fac = (singlelogfactory_t *)self;
  52. singlelog_t *slog = (singlelog_t*)log;
  53. if (_stricmp(key, "file") == 0) {
  54. char *p;
  55. if (strchr(value, ':') == NULL) {
  56. char tmp[MAX_PATH];
  57. GetModuleFileNameA(NULL, tmp, MAX_PATH);
  58. p = strrchr(tmp, '\\');
  59. *(p+1) = 0;
  60. slog->file_path = strdup_printf("%s%s", tmp, value);
  61. } else {
  62. slog->file_path = _strdup(value);
  63. }
  64. p = strrchr(slog->file_path, '\\');
  65. if (p) {
  66. *p = 0;
  67. CreateDirRecursiveA(slog->file_path);
  68. *p = '\\';
  69. }
  70. } else if (_stricmp(key, "use_lock") == 0) {
  71. if (_stricmp(value, "true") == 0 || _stricmp(value, "1") == 0) {
  72. slog->use_lock = 1;
  73. }
  74. } else if (_stricmp(key, "flush") == 0) {
  75. if (_stricmp(value, "true") == 0 || _stricmp(value, "1") == 0) {
  76. slog->flush = 1;
  77. }
  78. } else if (_stricmp(key, "level") == 0) {
  79. if (_stricmp(value, "all") == 0) {
  80. slog->base.level = 0;
  81. } else if (_stricmp(value, "trace") == 0) {
  82. slog->base.level = 1;
  83. } else if (_stricmp(value, "debug") == 0) {
  84. slog->base.level = 2;
  85. } else if (_stricmp(value, "info") == 0) {
  86. slog->base.level = 3;
  87. } else if (_stricmp(value, "warn") == 0) {
  88. slog->base.level = 4;
  89. } else if (_stricmp(value, "error") == 0) {
  90. slog->base.level = 5;
  91. } else if (_stricmp(value, "fatal") == 0) {
  92. slog->base.level = 6;
  93. } else if (_stricmp(value, "none") == 0) {
  94. slog->base.level = 7;
  95. } else {
  96. return -1;
  97. }
  98. } else {
  99. return -1;
  100. }
  101. return 0;
  102. }
  103. static int singlefilefactory_init_log(void *self, void *log)
  104. {
  105. singlelogfactory_t *fac = (singlelogfactory_t *)self;
  106. singlelog_t *slog = (singlelog_t*)log;
  107. slog->fp = fopen(slog->file_path, "ab");
  108. if (slog->fp) {
  109. slog->first_record = !!ftell(slog->fp);
  110. }
  111. return slog->fp ? 0 : -1;
  112. }
  113. static int singlefilefactory_term_log(void *self, void *log)
  114. {
  115. singlelogfactory_t *fac = (singlelogfactory_t *)self;
  116. singlelog_t *slog = (singlelog_t*)log;
  117. if (slog->fp) {
  118. fclose(slog->fp);
  119. slog->fp = NULL;
  120. }
  121. slog->use_lock = 0;
  122. if (slog->file_path) {
  123. free(slog->file_path);
  124. slog->file_path = NULL;
  125. }
  126. return 0;
  127. }
  128. static void singlefilefactory_destroy_log(void *self, void *log)
  129. {
  130. singlelog_t *slog = (singlelog_t*)log;
  131. if (slog) {
  132. if (slog->base.inst_name)
  133. free(slog->base.inst_name);
  134. free(slog);
  135. }
  136. }
  137. static int singlefilefactory_record_log(void *self,
  138. void *log,
  139. int level,
  140. unsigned long ts_low,
  141. unsigned long ts_high,
  142. const char *s,
  143. int sn)
  144. {
  145. singlelogfactory_t *fac = (singlelogfactory_t *)self;
  146. singlelog_t *slog = (singlelog_t*)log;
  147. if (slog->fp) {
  148. SYSTEMTIME st;
  149. FILETIME utc_ft, local_ft;
  150. char tmp[64];
  151. int n;
  152. DWORD dwBytesWritten = 0;
  153. if (slog->use_lock) {
  154. fastlock_enter(slog->lock);
  155. }
  156. #ifdef _WIN32
  157. utc_ft.dwLowDateTime = (DWORD)ts_low;
  158. utc_ft.dwHighDateTime = (DWORD)ts_high;
  159. FileTimeToLocalFileTime(&utc_ft, &local_ft);
  160. FileTimeToSystemTime(&local_ft, &st);
  161. #else
  162. GetLocalTime(&st);
  163. #endif // _WIN32
  164. if (slog->first_record) {
  165. n = sprintf(tmp, "[%02d:%02d:%02d.%03d][%s] ",
  166. st.wHour, st.wMinute, st.wSecond, st.wMilliseconds, log_level2str(level));
  167. slog->first_record = 0;
  168. } else {
  169. n = sprintf(tmp, "\r\n[%02d:%02d:%02d.%03d][%s] ",
  170. st.wHour, st.wMinute, st.wSecond, st.wMilliseconds, log_level2str(level));
  171. }
  172. _fwrite_nolock(tmp, n, 1, slog->fp);
  173. _fwrite_nolock(s, sn, 1, slog->fp);
  174. if (slog->flush)
  175. _fflush_nolock(slog->fp);
  176. }
  177. if (slog->use_lock) {
  178. fastlock_leave(slog->lock);
  179. }
  180. return 0;
  181. }
  182. int singlefilefactory_create(logfactory_t **p_fac)
  183. {
  184. singlelogfactory_t *fac;
  185. if (!p_fac)
  186. return -1;
  187. fac = MALLOC_T(singlelogfactory_t);
  188. if (!fac) {
  189. return -1;
  190. }
  191. fac->base.name = _strdup("single");
  192. fac->base.record_log = &singlefilefactory_record_log;
  193. fac->base.init_log = &singlefilefactory_init_log;
  194. fac->base.set_log_param = &singlefilefactory_set_log_param;
  195. fac->base.term_log = &singlefilefactory_term_log;
  196. fac->base.create_log = &singlefilefactory_create_log;
  197. fac->base.destroy_log = &singlefilefactory_destroy_log;
  198. fac->base.destroy = &singlefilefactory_destroy;
  199. *p_fac = &fac->base;
  200. return 0;
  201. }