沉淀之log4c的二次封装

    老大对log4c做了一下二次封装,将log4c的日志功能引入到我们的项目里面来使用,看了一下他封装的方式,感触还是比较大的:log4c好比一套完整的武术套路,从头打到尾,表演效果很不错;老大封装之后的日志功能,感觉就是将这个套路里面的一拳一脚拆开,在打架的时候拿出来用在恰当的地方。
    三个文件,一个path.c、一个log.h、一个log.c都在下面;

path.c
  1. #include <stddef.h>
  2. #include <sys/types.h>
  3. #include <sys/stat.h>
  4. #include <fcntl.h>
  5. #include <stdio.h>
  6. #include <errno.h>
  7. #define MAX_NAME 256
  8. static char root_path[MAX_NAME] = {"TSC_ROOT not init"};
  9. static char app_name[MAX_NAME] = {0};
  10. void tsc_path_init()
  11. {
  12. char* root = getenv("TSC_ROOT");
  13. if(root != NULL)
  14. {
  15. strncpy(root_path,root,sizeof(root_path)-1);
  16. }
  17. }
  18. const char* tsc_path()
  19. {
  20. return (const char*)root_path;
  21. }
  22. static int file_read(const char* path,char* out,int out_len)
  23. {
  24. int fd = open(path,O_RDONLY);
  25. if(fd == -1)
  26. return errno;
  27. int rt = read(fd,out,out_len);
  28. close(fd);
  29. return rt;
  30. }
  31. const char* tsc_app_name()
  32. {
  33. if(app_name[0] != '')
  34. return app_name;
  35. int pid = getpid();
  36. char path[256];
  37. sprintf(path,"/proc/%d/cmdline",pid);
  38. int len = file_read(path,path,sizeof(path));
  39. if(len<=0)
  40. return NULL;
  41. char* ptr = (char*)path+len;
  42. while(ptr!=path&&*ptr!='/')
  43. ptr--;
  44. ptr = (*ptr=='/')?(ptr+1):ptr;
  45. strncpy(app_name,ptr,sizeof(app_name)-1);
  46. return (const char*)app_name;
  47. }

hal.h
  1. #ifndef __TSC_HAL_log_H_
  2. #define __TSC_HAL_log_H_
  3. #ifdef TSC_X86
  4. #include <stdio.h>
  5. #else
  6. #endif
  7. #ifdef __cplusplus
  8. extern "C" {
  9. #endif
  10. enum {
  11. TSC_LOG_NONE = 0, /* No log. */
  12. TSC_LOG_EMERG = 1, /* System is unusable. */
  13. TSC_LOG_ALERT = 2, /* Action must be taken immediately.*/
  14. TSC_LOG_CRIT = 3, /* Critical conditions. */
  15. TSC_LOG_ERROR = 4, /* Error conditions. */
  16. TSC_LOG_WARNING = 5, /* Warning conditions. */
  17. TSC_LOG_NOTICE = 6, /* Normal but significant condition.*/
  18. TSC_LOG_INFO = 7, /* Infomational. */
  19. TSC_LOG_DEBUG = 8, /* Debug-level message. */
  20. TSC_LOG_ALL = 9 /* All log. */
  21. };
  22. #ifdef TSC_X86
  23. extern int tsc_log_level;
  24. #else
  25. #endif
  26. /*
  27. * set the rolling log
  28. * @param f_size
  29. * log file max size
  30. * @param f_num
  31. * log file max number
  32. * @param dir
  33. * log file output directory
  34. * @param prefix
  35. * log file name
  36. */
  37. void tsc_log_init(int f_size,int f_num,char* log_dir,char* log_prefix);
  38. void tsc_log_fini();
  39. static inline int tsc_log_level_set(int level)
  40. {
  41. if(level >= TSC_LOG_NONE && level <= TSC_LOG_ALL)
  42. {
  43. tsc_log_level = level;
  44. return 0;
  45. }
  46. return -1;
  47. }
  48. static inline int tsc_log_level_get(void)
  49. {
  50. return tsc_log_level;
  51. }
  52. void tsc_debug(const char* fmt,...);
  53. void tsc_info(const char* fmt,...);
  54. void tsc_notice(const char* fmt,...);
  55. void tsc_warn(const char* fmt,...);
  56. void tsc_error(const char* fmt,...);
  57. void tsc_crit(const char* fmt,...);
  58. void tsc_alert(const char* fmt,...);
  59. void tsc_emerg(const char* fmt,...);
  60. #ifdef __cplusplus
  61. }
  62. #endif
  63. #endif //_TSC_HAL_LOG_H_

hal.c
  1. #include <unistd.h>
  2. #include <assert.h>
  3. #include <stdio.h>
  4. #include <stdarg.h>
  5. #include "log4c.h"
  6. #include "log4c/rollingpolicy_type_sizewin.h"
  7. #include "tsc_hal_log.h"
  8. extern const char* tsc_path();
  9. extern const char* tsc_app_name();
  10. int tsc_log_level = TSC_LOG_ALL;
  11. log4c_category_t* __log4c_category__ = NULL;
  12. log4c_appender_t* __log4c_appender__ = NULL;
  13. rollingfile_udata_t* __log4c_rf__ = NULL;
  14. log4c_rollingpolicy_t* __log4c_rp__ = NULL;
  15. rollingpolicy_sizewin_udata_t* __log4c_sw__ = NULL;
  16. log4c_layout_t* __log4c_layout__ = NULL;
  17. const char* __log_prefix__ = "log";
  18. /********************************** log4cpp ******************************************/
  19. extern rollingfile_udata_t* rollingfile_make_udata(void);
  20. extern int rollingfile_udata_set_logdir(rollingfile_udata_t* rfudatap,const char* logdir);
  21. extern int rollingfile_udata_set_files_prefix(rollingfile_udata_t *rfudatap,const char* prefix);
  22. extern int rollingfile_udata_set_policy(rollingfile_udata_t* rfudatap,log4c_rollingpolicy_t* policyp);
  23. extern const log4c_layout_type_t log4c_layout_type_dated_r;
  24. extern const log4c_appender_type_t log4c_appender_type_rollingfile;
  25. /*************************************************************************************/
  26. /**************************************************
  27. * 函数名称 : tsc_log_init
  28. * 函数功能 : 日志功能初始化
  29. * 输 入 : f_size @单个文件大小; f_num @留存文件数量
  30. * log_dir @日志存放目录; log_prefix 日志后缀
  31. * 输 出 :
  32. * 返 回 :
  33. * 作 者 :
  34. * 创建日期 : 2016/08/25
  35. * 其他说明 :
  36. **************************************************/
  37. void tsc_log_init(int f_size,int f_num,char* log_dir,char* log_prefix)
  38. {
  39. //如果传入的参数为空那么按照特定方式去组织一个目录
  40. if(log_dir == NULL)
  41. {
  42. char _log_dir[1024];
  43. assert(tsc_path() != NULL);
  44. assert(tsc_app_name() != NULL);
  45. snprintf(_log_dir,sizeof(_log_dir)-1,"%s/log/%s",tsc_path(),tsc_app_name());
  46. log_dir = _log_dir;
  47. }
  48. //参数检查,为空则设置为默认的后缀格式
  49. if(log_prefix == NULL)
  50. {
  51. log_prefix = (char*)__log_prefix__;
  52. }
  53. if(__log4c_category__ == NULL)
  54. {
  55. //建立category对象
  56. assert((__log4c_category__ = log4c_category_new("")) != NULL);
  57. //建立appender对象
  58. assert((__log4c_appender__ = log4c_appender_new("tsc_log_appender")) != NULL);
  59. //文件循环方式,切换条件
  60. assert((__log4c_rf__ = rollingfile_make_udata()) != NULL);
  61. assert((__log4c_rp__ = log4c_rollingpolicy_new("tsc_log_rfpolicy")) != NULL);
  62. assert((__log4c_sw__ = sizewin_make_udata()) != NULL);
  63. //新建layout
  64. assert((__log4c_layout__ = log4c_layout_new("tsc_log_layout")) != NULL);
  65. //为category设置优先级,设置appender
  66. log4c_category_set_priority(__log4c_category__,LOG4C_PRIORITY_DEBUG);
  67. log4c_category_set_appender(__log4c_category__,__log4c_appender__);
  68. //将建好的appender进行实例化
  69. log4c_appender_set_type(__log4c_appender__,&log4c_appender_type_rollingfile);
  70. log4c_appender_set_udata(__log4c_appender__,__log4c_rf__);
  71. //设置文件循环策略属性
  72. rollingfile_udata_set_logdir(__log4c_rf__,log_dir);
  73. rollingfile_udata_set_files_prefix(__log4c_rf__,log_prefix);
  74. rollingfile_udata_set_policy(__log4c_rf__,__log4c_rp__);
  75. //设置日志文件切换条件
  76. log4c_rollingpolicy_set_udata(__log4c_rp__,__log4c_sw__);
  77. sizewin_udata_set_file_maxsize(__log4c_sw__,f_size);
  78. sizewin_udata_set_max_num_files(__log4c_sw__,f_num);
  79. //实例化layout,并与appender进行绑定
  80. log4c_rollingpolicy_init(__log4c_rp__,__log4c_rf__);
  81. log4c_layout_set_type(__log4c_layout__,&log4c_layout_type_dated_r);
  82. log4c_appender_set_layout(__log4c_appender__,__log4c_layout__);
  83. }
  84. }
  85. void tsc_log_fini()
  86. {
  87. if(__log4c_category__ != NULL)
  88. {
  89. log4c_category_delete(__log4c_category__);
  90. }
  91. if(__log4c_appender__ != NULL)
  92. {
  93. log4c_appender_delete(__log4c_appender__);
  94. }
  95. if(__log4c_rp__ != NULL)
  96. {
  97. log4c_rollingpolicy_delete(__log4c_rp__);
  98. }
  99. if(__log4c_layout__ != NULL)
  100. {
  101. log4c_layout_delete(__log4c_layout__);
  102. }
  103. }
  104. void tsc_debug(const char* fmt,...)
  105. {
  106. if(tsc_log_level >= TSC_LOG_DEBUG)
  107. {
  108. va_list argptr;
  109. va_start(argptr,fmt);
  110. log4c_category_vlog(__log4c_category__,LOG4C_PRIORITY_DEBUG,fmt,argptr);
  111. va_end(argptr);
  112. }
  113. }
  114. void tsc_info(const char* fmt,...)
  115. {
  116. if(tsc_log_level >= TSC_LOG_INFO)
  117. {
  118. va_list argptr;
  119. va_start(argptr,fmt);
  120. log4c_category_vlog(__log4c_category__,LOG4C_PRIORITY_INFO,fmt,argptr);
  121. va_end(argptr);
  122. }
  123. }
  124. void tsc_notice(const char* fmt,...)
  125. {
  126. if(tsc_log_level >= TSC_LOG_NOTICE)
  127. {
  128. va_list argptr;
  129. va_start(argptr,fmt);
  130. log4c_category_vlog(__log4c_category__,LOG4C_PRIORITY_NOTICE,fmt,argptr);
  131. va_end(argptr);
  132. }
  133. }
  134. void tsc_warn(const char* fmt,...)
  135. {
  136. if(tsc_log_level >= TSC_LOG_WARNING)
  137. {
  138. va_list argptr;
  139. va_start(argptr,fmt);
  140. log4c_category_vlog(__log4c_category__,LOG4C_PRIORITY_WARN,fmt,argptr);
  141. va_end(argptr);
  142. }
  143. }
  144. void tsc_error(const char* fmt,...)
  145. {
  146. if(tsc_log_level >= TSC_LOG_ERROR)
  147. {
  148. va_list argptr;
  149. va_start(argptr,fmt);
  150. log4c_category_vlog(__log4c_category__,LOG4C_PRIORITY_ERROR,fmt,argptr);
  151. va_end(argptr);
  152. }
  153. }
  154. void tsc_crit(const char* fmt,...)
  155. {
  156. if(tsc_log_level >= TSC_LOG_CRIT)
  157. {
  158. va_list argptr;
  159. va_start(argptr,fmt);
  160. log4c_category_vlog(__log4c_category__,LOG4C_PRIORITY_CRIT,fmt,argptr);
  161. va_end(argptr);
  162. }
  163. }
  164. void tsc_alert(const char* fmt,...)
  165. {
  166. if(tsc_log_level >= TSC_LOG_ALERT)
  167. {
  168. va_list argptr;
  169. va_start(argptr,fmt);
  170. log4c_category_vlog(__log4c_category__,LOG4C_PRIORITY_ALERT,fmt,argptr);
  171. va_end(argptr);
  172. }
  173. }
  174. void tsc_emerg(const char* fmt,...)
  175. {
  176. if(tsc_log_level >= TSC_LOG_EMERG)
  177. {
  178. va_list argptr;
  179. va_start(argptr,fmt);
  180. log4c_category_vlog(__log4c_category__,LOG4C_PRIORITY_FATAL,fmt,argptr);
  181. va_end(argptr);
  182. }
  183. }

最后给一个测试用例:
main.c
  1. #include <stdio.h>
  2. #include <unistd.h>
  3. #include <pthread.h>
  4. #include "tsc_hal_log.h"
  5. int main()
  6. {
  7. pthread_t thread1,thread2;
  8. printf("%f ",3.14159);
  9. tsc_log_init(10240000, 1024000, "../../log/", "log.txt");
  10. tsc_warn("this is a warn string %d", 234);
  11. tsc_error("this is an error string %c", 'k');
  12. tsc_crit("this is a crit string %s", "zhangcf");
  13. tsc_alert("this is a alert string %f",3.145);
  14. tsc_emerg("this is a emerg string %ld", 123456789);
  15. tsc_debug("this is a debug string");
  16. tsc_info("this is a info string");
  17. tsc_notice("this is a notice string");
  18. tsc_log_fini();
  19. return 0;
  20. }






原文地址:https://www.cnblogs.com/cfzhang/p/2b3280e2117074f49c0056398a5fbf31.html