hlog.h 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184
  1. #ifndef HV_LOG_H_
  2. #define HV_LOG_H_
  3. /*
  4. * @功能:写日志
  5. *
  6. */
  7. /*
  8. * hlog is thread-safe
  9. */
  10. #include <string.h>
  11. #ifdef _WIN32
  12. #define DIR_SEPARATOR '\\'
  13. #define DIR_SEPARATOR_STR "\\"
  14. #else
  15. #define DIR_SEPARATOR '/'
  16. #define DIR_SEPARATOR_STR "/"
  17. #endif
  18. // __FILE__是完整路径宏,对于日志来说太长,这里我们提取出文件名__FILENAME__
  19. #ifndef __FILENAME__
  20. // #define __FILENAME__ (strrchr(__FILE__, DIR_SEPARATOR) ? strrchr(__FILE__, DIR_SEPARATOR) + 1 : __FILE__)
  21. #define __FILENAME__ (strrchr(DIR_SEPARATOR_STR __FILE__, DIR_SEPARATOR) + 1)
  22. #endif
  23. #include "hexport.h"
  24. #ifdef __cplusplus
  25. extern "C" {
  26. #endif
  27. // 定义一些终端颜色宏,方便区分日志级别
  28. #define CLR_CLR "\033[0m" /* 恢复颜色 */
  29. #define CLR_BLACK "\033[30m" /* 黑色字 */
  30. #define CLR_RED "\033[31m" /* 红色字 */
  31. #define CLR_GREEN "\033[32m" /* 绿色字 */
  32. #define CLR_YELLOW "\033[33m" /* 黄色字 */
  33. #define CLR_BLUE "\033[34m" /* 蓝色字 */
  34. #define CLR_PURPLE "\033[35m" /* 紫色字 */
  35. #define CLR_SKYBLUE "\033[36m" /* 天蓝字 */
  36. #define CLR_WHITE "\033[37m" /* 白色字 */
  37. #define CLR_BLK_WHT "\033[40;37m" /* 黑底白字 */
  38. #define CLR_RED_WHT "\033[41;37m" /* 红底白字 */
  39. #define CLR_GREEN_WHT "\033[42;37m" /* 绿底白字 */
  40. #define CLR_YELLOW_WHT "\033[43;37m" /* 黄底白字 */
  41. #define CLR_BLUE_WHT "\033[44;37m" /* 蓝底白字 */
  42. #define CLR_PURPLE_WHT "\033[45;37m" /* 紫底白字 */
  43. #define CLR_SKYBLUE_WHT "\033[46;37m" /* 天蓝底白字 */
  44. #define CLR_WHT_BLK "\033[47;30m" /* 白底黑字 */
  45. // XXX(id, str, clr)
  46. #define LOG_LEVEL_MAP(XXX) \
  47. XXX(LOG_LEVEL_DEBUG, "DEBUG", CLR_WHITE) \
  48. XXX(LOG_LEVEL_INFO, "INFO ", CLR_GREEN) \
  49. XXX(LOG_LEVEL_WARN, "WARN ", CLR_YELLOW) \
  50. XXX(LOG_LEVEL_ERROR, "ERROR", CLR_RED) \
  51. XXX(LOG_LEVEL_FATAL, "FATAL", CLR_RED_WHT)
  52. // 定义日志级别
  53. typedef enum {
  54. LOG_LEVEL_VERBOSE = 0,
  55. #define XXX(id, str, clr) id,
  56. LOG_LEVEL_MAP(XXX)
  57. #undef XXX
  58. LOG_LEVEL_SILENT
  59. } log_level_e;
  60. #define DEFAULT_LOG_FILE "libhv"
  61. #define DEFAULT_LOG_LEVEL LOG_LEVEL_INFO
  62. #define DEFAULT_LOG_REMAIN_DAYS 1
  63. #define DEFAULT_LOG_MAX_BUFSIZE (1<<14) // 16k
  64. #define DEFAULT_LOG_MAX_FILESIZE (1<<24) // 16M
  65. // logger: default file_logger
  66. // network_logger() see event/nlog.h
  67. typedef void (*logger_handler)(int loglevel, const char* buf, int len);
  68. // 实现了几种常见的日志处理器,标准输出、标准错误、写文件
  69. HV_EXPORT void stdout_logger(int loglevel, const char* buf, int len);
  70. HV_EXPORT void stderr_logger(int loglevel, const char* buf, int len);
  71. HV_EXPORT void file_logger(int loglevel, const char* buf, int len);
  72. // 在event模块中我们还实现了一个网络日志服务,
  73. // 连上的客户端就会收到日志,是不是有点像android的logcat呢
  74. // network_logger implement see event/nlog.h
  75. // HV_EXPORT void network_logger(int loglevel, const char* buf, int len);
  76. typedef struct logger_s logger_t;
  77. // 创建日志器
  78. HV_EXPORT logger_t* logger_create();
  79. // 销毁日志器
  80. HV_EXPORT void logger_destroy(logger_t* logger);
  81. // 设置日志处理器
  82. HV_EXPORT void logger_set_handler(logger_t* logger, logger_handler fn);
  83. // 设置日志级别
  84. HV_EXPORT void logger_set_level(logger_t* logger, int level);
  85. // level = [VERBOSE,DEBUG,INFO,WARN,ERROR,FATAL,SILENT]
  86. HV_EXPORT void logger_set_level_by_str(logger_t* logger, const char* level);
  87. // 设置一条日志最大的长度
  88. HV_EXPORT void logger_set_max_bufsize(logger_t* logger, unsigned int bufsize);
  89. // 启用日志颜色打印
  90. HV_EXPORT void logger_enable_color(logger_t* logger, int on);
  91. // 打印日志
  92. HV_EXPORT int logger_print(logger_t* logger, int level, const char* fmt, ...);
  93. // 下面是文件日志器的一些设置
  94. // below for file logger
  95. // 设置日志文件
  96. HV_EXPORT void logger_set_file(logger_t* logger, const char* filepath);
  97. // 设置日志文件最大尺寸
  98. HV_EXPORT void logger_set_max_filesize(logger_t* logger, unsigned long long filesize);
  99. // 16, 16M, 16MB
  100. HV_EXPORT void logger_set_max_filesize_by_str(logger_t* logger, const char* filesize);
  101. // 设置日志保留天数
  102. HV_EXPORT void logger_set_remain_days(logger_t* logger, int days);
  103. // 启用fsync
  104. // @NOTE: fsync用来强制刷新缓存到磁盘,日志的实时可见性更好,但会影响性能,
  105. // 在日志很多的场合,建议关闭此选项,可使用定时器定时调用logger_fsync去刷新到磁盘。
  106. HV_EXPORT void logger_enable_fsync(logger_t* logger, int on);
  107. // 强制调用fsync刷新缓存到磁盘
  108. HV_EXPORT void logger_fsync(logger_t* logger);
  109. // 获取当前的日志文件路径
  110. HV_EXPORT const char* logger_get_cur_file(logger_t* logger);
  111. // 提供一个默认的日志器
  112. // hlog: default logger instance
  113. HV_EXPORT logger_t* hv_default_logger();
  114. // hlog_xxx即使用默认的日志器
  115. // macro hlog*
  116. #define hlog hv_default_logger()
  117. #define hlog_set_file(filepath) logger_set_file(hlog, filepath)
  118. #define hlog_set_level(level) logger_set_level(hlog, level)
  119. #define hlog_set_level_by_str(level) logger_set_level_by_str(hlog, level)
  120. #define hlog_set_max_filesize(filesize) logger_set_max_filesize(hlog, filesize)
  121. #define hlog_set_max_filesize_by_str(filesize) logger_set_max_filesize_by_str(hlog, filesize)
  122. #define hlog_set_remain_days(days) logger_set_remain_days(hlog, days)
  123. #define hlog_enable_fsync() logger_enable_fsync(hlog, 1)
  124. #define hlog_disable_fsync() logger_enable_fsync(hlog, 0)
  125. #define hlog_fsync() logger_fsync(hlog)
  126. #define hlog_get_cur_file() logger_get_cur_file(hlog)
  127. #define hlogd(fmt, ...) logger_print(hlog, LOG_LEVEL_DEBUG, fmt " [%s:%d:%s]\n", ## __VA_ARGS__, __FILENAME__, __LINE__, __FUNCTION__)
  128. #define hlogi(fmt, ...) logger_print(hlog, LOG_LEVEL_INFO, fmt " [%s:%d:%s]\n", ## __VA_ARGS__, __FILENAME__, __LINE__, __FUNCTION__)
  129. #define hlogw(fmt, ...) logger_print(hlog, LOG_LEVEL_WARN, fmt " [%s:%d:%s]\n", ## __VA_ARGS__, __FILENAME__, __LINE__, __FUNCTION__)
  130. #define hloge(fmt, ...) logger_print(hlog, LOG_LEVEL_ERROR, fmt " [%s:%d:%s]\n", ## __VA_ARGS__, __FILENAME__, __LINE__, __FUNCTION__)
  131. #define hlogf(fmt, ...) logger_print(hlog, LOG_LEVEL_FATAL, fmt " [%s:%d:%s]\n", ## __VA_ARGS__, __FILENAME__, __LINE__, __FUNCTION__)
  132. // 在android平台,使用__android_log_print
  133. // below for android
  134. #if defined(ANDROID) || defined(__ANDROID__)
  135. #include <android/log.h>
  136. #define LOG_TAG "JNI"
  137. #undef hlogd
  138. #undef hlogi
  139. #undef hlogw
  140. #undef hloge
  141. #undef hlogf
  142. #define hlogd(...) __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, __VA_ARGS__)
  143. #define hlogi(...) __android_log_print(ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__)
  144. #define hlogw(...) __android_log_print(ANDROID_LOG_WARN, LOG_TAG, __VA_ARGS__)
  145. #define hloge(...) __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, __VA_ARGS__)
  146. #define hlogf(...) __android_log_print(ANDROID_LOG_FATAL, LOG_TAG, __VA_ARGS__)
  147. #endif
  148. // 更通用的日志宏
  149. // macro alias
  150. #if !defined(LOGD) && !defined(LOGI) && !defined(LOGW) && !defined(LOGE) && !defined(LOGF)
  151. #define LOGD hlogd
  152. #define LOGI hlogi
  153. #define LOGW hlogw
  154. #define LOGE hloge
  155. #define LOGF hlogf
  156. #endif
  157. #ifdef __cplusplus
  158. } // extern "C"
  159. #endif
  160. #endif // HV_LOG_H_