沉淀之log4c的二次封装
老大对log4c做了一下二次封装,将log4c的日志功能引入到我们的项目里面来使用,看了一下他封装的方式,感触还是比较大的:log4c好比一套完整的武术套路,从头打到尾,表演效果很不错;老大封装之后的日志功能,感觉就是将这个套路里面的一拳一脚拆开,在打架的时候拿出来用在恰当的地方。
三个文件,一个path.c、一个log.h、一个log.c都在下面;
path.c
#include <stddef.h>#include <sys/types.h>#include <sys/stat.h>#include <fcntl.h>#include <stdio.h>#include <errno.h>#define MAX_NAME 256static char root_path[MAX_NAME] = {"TSC_ROOT not init"};static char app_name[MAX_NAME] = {0};void tsc_path_init(){char* root = getenv("TSC_ROOT");if(root != NULL){strncpy(root_path,root,sizeof(root_path)-1);}}const char* tsc_path(){return (const char*)root_path;}static int file_read(const char* path,char* out,int out_len){int fd = open(path,O_RDONLY);if(fd == -1)return errno;int rt = read(fd,out,out_len);close(fd);return rt;}const char* tsc_app_name(){if(app_name[0] != '\0')return app_name;int pid = getpid();char path[256];sprintf(path,"/proc/%d/cmdline",pid);int len = file_read(path,path,sizeof(path));if(len<=0)return NULL;char* ptr = (char*)path+len;while(ptr!=path&&*ptr!='/')ptr--;ptr = (*ptr=='/')?(ptr+1):ptr;strncpy(app_name,ptr,sizeof(app_name)-1);return (const char*)app_name;}
hal.h
#ifndef __TSC_HAL_log_H_#define __TSC_HAL_log_H_#ifdef TSC_X86#include <stdio.h>#else#endif#ifdef __cplusplusextern "C" {#endifenum {TSC_LOG_NONE = 0, /* No log. */TSC_LOG_EMERG = 1, /* System is unusable. */TSC_LOG_ALERT = 2, /* Action must be taken immediately.*/TSC_LOG_CRIT = 3, /* Critical conditions. */TSC_LOG_ERROR = 4, /* Error conditions. */TSC_LOG_WARNING = 5, /* Warning conditions. */TSC_LOG_NOTICE = 6, /* Normal but significant condition.*/TSC_LOG_INFO = 7, /* Infomational. */TSC_LOG_DEBUG = 8, /* Debug-level message. */TSC_LOG_ALL = 9 /* All log. */};#ifdef TSC_X86extern int tsc_log_level;#else#endif/** set the rolling log* @param f_size* log file max size* @param f_num* log file max number* @param dir* log file output directory* @param prefix* log file name*/void tsc_log_init(int f_size,int f_num,char* log_dir,char* log_prefix);void tsc_log_fini();static inline int tsc_log_level_set(int level){if(level >= TSC_LOG_NONE && level <= TSC_LOG_ALL){tsc_log_level = level;return 0;}return -1;}static inline int tsc_log_level_get(void){return tsc_log_level;}void tsc_debug(const char* fmt,...);void tsc_info(const char* fmt,...);void tsc_notice(const char* fmt,...);void tsc_warn(const char* fmt,...);void tsc_error(const char* fmt,...);void tsc_crit(const char* fmt,...);void tsc_alert(const char* fmt,...);void tsc_emerg(const char* fmt,...);#ifdef __cplusplus}#endif#endif //_TSC_HAL_LOG_H_
hal.c
#include <unistd.h>#include <assert.h>#include <stdio.h>#include <stdarg.h>#include "log4c.h"#include "log4c/rollingpolicy_type_sizewin.h"#include "tsc_hal_log.h"extern const char* tsc_path();extern const char* tsc_app_name();int tsc_log_level = TSC_LOG_ALL;log4c_category_t* __log4c_category__ = NULL;log4c_appender_t* __log4c_appender__ = NULL;rollingfile_udata_t* __log4c_rf__ = NULL;log4c_rollingpolicy_t* __log4c_rp__ = NULL;rollingpolicy_sizewin_udata_t* __log4c_sw__ = NULL;log4c_layout_t* __log4c_layout__ = NULL;const char* __log_prefix__ = "log";/********************************** log4cpp ******************************************/extern rollingfile_udata_t* rollingfile_make_udata(void);extern int rollingfile_udata_set_logdir(rollingfile_udata_t* rfudatap,const char* logdir);extern int rollingfile_udata_set_files_prefix(rollingfile_udata_t *rfudatap,const char* prefix);extern int rollingfile_udata_set_policy(rollingfile_udata_t* rfudatap,log4c_rollingpolicy_t* policyp);extern const log4c_layout_type_t log4c_layout_type_dated_r;extern const log4c_appender_type_t log4c_appender_type_rollingfile;/*************************************************************************************//*************************************************** 函数名称 : tsc_log_init* 函数功能 : 日志功能初始化* 输 入 : f_size @单个文件大小; f_num @留存文件数量* log_dir @日志存放目录; log_prefix 日志后缀* 输 出 :* 返 回 :* 作 者 :* 创建日期 : 2016/08/25* 其他说明 :**************************************************/void tsc_log_init(int f_size,int f_num,char* log_dir,char* log_prefix){//如果传入的参数为空那么按照特定方式去组织一个目录if(log_dir == NULL){char _log_dir[1024];assert(tsc_path() != NULL);assert(tsc_app_name() != NULL);snprintf(_log_dir,sizeof(_log_dir)-1,"%s/log/%s",tsc_path(),tsc_app_name());log_dir = _log_dir;}//参数检查,为空则设置为默认的后缀格式if(log_prefix == NULL){log_prefix = (char*)__log_prefix__;}if(__log4c_category__ == NULL){//建立category对象assert((__log4c_category__ = log4c_category_new("")) != NULL);//建立appender对象assert((__log4c_appender__ = log4c_appender_new("tsc_log_appender")) != NULL);//文件循环方式,切换条件assert((__log4c_rf__ = rollingfile_make_udata()) != NULL);assert((__log4c_rp__ = log4c_rollingpolicy_new("tsc_log_rfpolicy")) != NULL);assert((__log4c_sw__ = sizewin_make_udata()) != NULL);//新建layoutassert((__log4c_layout__ = log4c_layout_new("tsc_log_layout")) != NULL);//为category设置优先级,设置appenderlog4c_category_set_priority(__log4c_category__,LOG4C_PRIORITY_DEBUG);log4c_category_set_appender(__log4c_category__,__log4c_appender__);//将建好的appender进行实例化log4c_appender_set_type(__log4c_appender__,&log4c_appender_type_rollingfile);log4c_appender_set_udata(__log4c_appender__,__log4c_rf__);//设置文件循环策略属性rollingfile_udata_set_logdir(__log4c_rf__,log_dir);rollingfile_udata_set_files_prefix(__log4c_rf__,log_prefix);rollingfile_udata_set_policy(__log4c_rf__,__log4c_rp__);//设置日志文件切换条件log4c_rollingpolicy_set_udata(__log4c_rp__,__log4c_sw__);sizewin_udata_set_file_maxsize(__log4c_sw__,f_size);sizewin_udata_set_max_num_files(__log4c_sw__,f_num);//实例化layout,并与appender进行绑定log4c_rollingpolicy_init(__log4c_rp__,__log4c_rf__);log4c_layout_set_type(__log4c_layout__,&log4c_layout_type_dated_r);log4c_appender_set_layout(__log4c_appender__,__log4c_layout__);}}void tsc_log_fini(){if(__log4c_category__ != NULL){log4c_category_delete(__log4c_category__);}if(__log4c_appender__ != NULL){log4c_appender_delete(__log4c_appender__);}if(__log4c_rp__ != NULL){log4c_rollingpolicy_delete(__log4c_rp__);}if(__log4c_layout__ != NULL){log4c_layout_delete(__log4c_layout__);}}void tsc_debug(const char* fmt,...){if(tsc_log_level >= TSC_LOG_DEBUG){va_list argptr;va_start(argptr,fmt);log4c_category_vlog(__log4c_category__,LOG4C_PRIORITY_DEBUG,fmt,argptr);va_end(argptr);}}void tsc_info(const char* fmt,...){if(tsc_log_level >= TSC_LOG_INFO){va_list argptr;va_start(argptr,fmt);log4c_category_vlog(__log4c_category__,LOG4C_PRIORITY_INFO,fmt,argptr);va_end(argptr);}}void tsc_notice(const char* fmt,...){if(tsc_log_level >= TSC_LOG_NOTICE){va_list argptr;va_start(argptr,fmt);log4c_category_vlog(__log4c_category__,LOG4C_PRIORITY_NOTICE,fmt,argptr);va_end(argptr);}}void tsc_warn(const char* fmt,...){if(tsc_log_level >= TSC_LOG_WARNING){va_list argptr;va_start(argptr,fmt);log4c_category_vlog(__log4c_category__,LOG4C_PRIORITY_WARN,fmt,argptr);va_end(argptr);}}void tsc_error(const char* fmt,...){if(tsc_log_level >= TSC_LOG_ERROR){va_list argptr;va_start(argptr,fmt);log4c_category_vlog(__log4c_category__,LOG4C_PRIORITY_ERROR,fmt,argptr);va_end(argptr);}}void tsc_crit(const char* fmt,...){if(tsc_log_level >= TSC_LOG_CRIT){va_list argptr;va_start(argptr,fmt);log4c_category_vlog(__log4c_category__,LOG4C_PRIORITY_CRIT,fmt,argptr);va_end(argptr);}}void tsc_alert(const char* fmt,...){if(tsc_log_level >= TSC_LOG_ALERT){va_list argptr;va_start(argptr,fmt);log4c_category_vlog(__log4c_category__,LOG4C_PRIORITY_ALERT,fmt,argptr);va_end(argptr);}}void tsc_emerg(const char* fmt,...){if(tsc_log_level >= TSC_LOG_EMERG){va_list argptr;va_start(argptr,fmt);log4c_category_vlog(__log4c_category__,LOG4C_PRIORITY_FATAL,fmt,argptr);va_end(argptr);}}
最后给一个测试用例:
main.c
#include <stdio.h>#include <unistd.h>#include <pthread.h>#include "tsc_hal_log.h"int main(){pthread_t thread1,thread2;printf("%f\n",3.14159);tsc_log_init(10240000, 1024000, "../../log/", "log.txt");tsc_warn("this is a warn string %d", 234);tsc_error("this is an error string %c", 'k');tsc_crit("this is a crit string %s", "zhangcf");tsc_alert("this is a alert string %f",3.145);tsc_emerg("this is a emerg string %ld", 123456789);tsc_debug("this is a debug string");tsc_info("this is a info string");tsc_notice("this is a notice string");tsc_log_fini();return 0;}
浙公网安备 33010602011771号