hlog.cpp 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120
  1. #include "hlog.h"
  2. #include <stdio.h>
  3. #include <string.h>
  4. #include <stdarg.h>
  5. #include <mutex>
  6. #include "htime.h" // for get_datetime
  7. #define SECONDS_PER_DAY 86400
  8. static char s_logfile[256] = DEFAULT_LOG_FILE;
  9. static int s_loglevel = DEFAULT_LOG_LEVEL;
  10. static bool s_logcolor = false;
  11. static int s_remain_days = DEFAULT_LOG_REMAIN_DAYS;
  12. static FILE* s_logfp = NULL;
  13. static char s_logbuf[LOG_BUFSIZE];
  14. static char s_cur_logfile[256] = {0};
  15. static std::mutex s_mutex;
  16. static void ts_logfile(time_t ts, char* buf, int len) {
  17. struct tm* tm = localtime(&ts);
  18. snprintf(buf, len, "%s-%04d-%02d-%02d.log",
  19. s_logfile,
  20. tm->tm_year+1900,
  21. tm->tm_mon+1,
  22. tm->tm_mday);
  23. }
  24. int hlog_set_file(const char* logfile) {
  25. if (logfile == NULL || strlen(logfile) == 0) return -10;
  26. strncpy(s_logfile, logfile, sizeof(s_logfile));
  27. // remove suffix .log
  28. char* suffix = strrchr(s_logfile, '.');
  29. if (suffix && strcmp(suffix, ".log") == 0) {
  30. *suffix = '\0';
  31. }
  32. time_t ts_now = time(NULL);
  33. ts_logfile(ts_now, s_cur_logfile, sizeof(s_cur_logfile));
  34. if (s_logfp) {
  35. fclose(s_logfp);
  36. s_logfp = NULL;
  37. }
  38. s_logfp = fopen(s_cur_logfile, "a");
  39. // remove logfile before s_remain_days
  40. if (s_remain_days > 0) {
  41. time_t ts_rm = ts_now - s_remain_days * SECONDS_PER_DAY;
  42. char rm_logfile[256] = {0};
  43. ts_logfile(ts_rm, rm_logfile, sizeof(rm_logfile));
  44. remove(rm_logfile);
  45. }
  46. return s_logfp ? 0 : -1;
  47. }
  48. void hlog_set_level(int level) {
  49. s_loglevel = level;
  50. }
  51. void hlog_set_remain_days(int days) {
  52. s_remain_days = days;
  53. }
  54. void hlog_enable_color(bool enable) {
  55. s_logcolor = enable;
  56. }
  57. int hlog_printf(int level, const char* fmt, ...) {
  58. if (level < s_loglevel)
  59. return -10;
  60. const char* pcolor = "";
  61. const char* plevel = "";
  62. #define CASE_LOG(id, str, clr) \
  63. case id: plevel = str; pcolor = clr; break;
  64. switch (level) {
  65. FOREACH_LOG(CASE_LOG)
  66. }
  67. #undef CASE_LOG
  68. if (!s_logcolor)
  69. pcolor = "";
  70. std::lock_guard<std::mutex> locker(s_mutex);
  71. if (!s_logfp) {
  72. if (hlog_set_file(s_logfile) != 0)
  73. return -20;
  74. }
  75. if (ftell(s_logfp) > MAX_LOG_FILESIZE) {
  76. fclose(s_logfp);
  77. s_logfp = fopen(s_cur_logfile, "w");
  78. if (!s_logfp)
  79. return -30;
  80. }
  81. datetime_t now = get_datetime();
  82. int len = snprintf(s_logbuf, LOG_BUFSIZE, "%s[%04d-%02d-%02d %02d:%02d:%02d.%03d][%s]: ",
  83. pcolor, now.year, now.month, now.day, now.hour, now.min, now.sec, now.ms, plevel);
  84. va_list ap;
  85. va_start(ap, fmt);
  86. len += vsnprintf(s_logbuf + len, LOG_BUFSIZE-len, fmt, ap);
  87. va_end(ap);
  88. fprintf(s_logfp, "%s\n", s_logbuf);
  89. if (s_logcolor) {
  90. fprintf(s_logfp, CL_CLR);
  91. }
  92. fflush(s_logfp);
  93. return len;
  94. }