C语言封装自己的日志函数

78 篇文章 0 订阅
本文介绍了如何使用C语言封装一个日志函数,包括宏定义BUF_SIZE、log_st结构体、log_init初始化函数、log_debug日志输出函数以及log_checksize文件大小检查函数。该日志系统支持输出到屏幕、文件,且能根据配置控制文件大小和命名规则。
摘要由CSDN通过智能技术生成

来自:http://www.cpplive.com/html/871.html

C语言的时候,您是否还在使用printf函数来输出日志呢?您是否考虑过将printf函数打印的内容存到文件中去呢?您是否想拥有一个可选择的既支持输出到屏幕又支持存储到文件中的日志函数呢?很高兴的告诉您,如果您愿意的话,欢迎使用本人编写的一个一套日志函数,该套函数由五部分组成,分别是宏变量BUF_SIZE、结构体log_st、log_init函数、log_debug函数和log_checksize函数。其中宏变量BUF_SIZE用来限制每次输出的日志的最大长度;结构体用来存储用户需求,包括文件路径、文件描述符号、单个文件最大大小、输出方式标志、文件命名标志等;log_init函数用来完成用户需求录入、文件创建等功能,在mian函数的开始调用一次即可;log_debug函数的功能跟printf很类似,是在printf基础上进行的扩充,实现将日志输出到屏幕或者写入到文件,在需要打印日志的地方调用该函数;log_checksize函数用来检测日志文件大小是否超过最大大小限制,它需要您定时或者定点调用它,如果一直不调用,则日志文件将不受指定的最大大小限制。

一、定义宏变量BUF_SIZE

  1. #define BUF_SIZE 1024  

二、定义log_st结构体

  1. typedef struct _log_st log_st;  
  2. struct _log_st  
  3. {  
  4.     char path[128];  
  5.     int fd;  
  6.     int size;  
  7.     int level;  
  8.     int num;  
  9. };  

三、定义log_init函数
参数说明:path——您要存储的文件路径;size——单个文件的最大大小,如果超过该大小则新建新的文件用来存储;level——日志输出方式,建议在上层限制其值的范围为0到3,0表示日志既不输出到屏幕也不创建文件和保存到文件,1表示日志保存到文件但不输出到屏幕,2表示日志既输出到屏幕也保存到文件,3表示日志只输出到文件而不创建文件和存入文件;num——日志文件命名方式,非0表示以(int)time(NULL)作为文件名来保存文件,文件数量随着日志量的递增而递增;0表示以“.new”和“.bak”为文件名来保存文件,文件数量不超过两个,随着日志量的递增,旧的日志文件将被新的覆盖,更直观的说就是说.new”和“.bak”文件只保存最近的日志。

  1. log_st *log_init(char *path, int size, int level, int num)  
  2. {  
  3.     char new_path[128] = {0};  
  4.     if (NULL == path || 0 == level) return NULL;  
  5.     log_st *log = (log_st *)malloc(sizeof(log_st));  
  6.     memset(log, 0, sizeof(log_st));  
  7.     if (level != 3)  
  8.     {  
  9.         //the num use to control file naming  
  10.         log->num = num;  
  11.         if(num)  
  12.             snprintf(new_path, 128, "%s%d", path, (int)time(NULL));  
  13.         else  
  14.             snprintf(new_path, 128, "%s.new", path);  
  15.         if(-1 == (log->fd = open(new_path, O_RDWR|O_APPEND|O_CREAT|O_SYNC, S_IRUSR|S_IWUSR|S_IROTH)))  
  16.         {  
  17.             free(log);  
  18.             log = NULL;  
  19.             return NULL;  
  20.         }  
  21.     }  
  22.     strncpy(log->path, path, 128);  
  23.     log->size = (size > 0 ? size:0);  
  24.     log->level = (level > 0 ? level:0);  
  25.     return log;  
  26. }  

四、定义log_debug函数

  1. void log_debug(log_st *log, const char *msg, ...)  
  2. {  
  3.     va_list ap;  
  4.     time_t now;  
  5.     char *pos;  
  6.     char _n = '\n';  
  7.     char message[BUF_SIZE] = {0};  
  8.     int nMessageLen = 0;  
  9.     int sz;  
  10.     if(NULL == log || 0 == log->level) return;  
  11.     now = time(NULL);  
  12.     pos = ctime(&now);  
  13.     sz = strlen(pos);  
  14.     pos[sz-1]=']';  
  15.     snprintf(message, BUF_SIZE, "[%s ", pos);  
  16.     for (pos = message; *pos; pos++);  
  17.     sz = pos - message;  
  18.     va_start(ap, msg);  
  19.     nMessageLen = vsnprintf(pos, BUF_SIZE - sz, msg, ap);  
  20.     va_end(ap);  
  21.     if (nMessageLen <= 0) return;  
  22.     if (3 == log->level)  
  23.     {  
  24.         printf("%s\n", message);  
  25.         return;  
  26.     }  
  27.     if (2 == log->level)  
  28.         printf("%s\n", message);  
  29.     write(log->fd, message, strlen(message));  
  30.     write(log->fd, &_n, 1);  
  31.     fsync(log->fd);  
  32. }  

五、定义log_checksize函数

  1. void log_checksize(log_st *log)  
  2. {  
  3.     struct stat stat_buf;  
  4.     char new_path[128] = {0};  
  5.     char bak_path[128] = {0};  
  6.     if(NULL == log || 3 == log->level || '\0' == log->path[0]) return;  
  7.     memset(&stat_buf, 0, sizeof(struct stat));  
  8.     fstat(log->fd, &stat_buf);  
  9.     if(stat_buf.st_size > log->size)  
  10.     {  
  11.         close(log->fd);  
  12.         if(log->num)  
  13.             snprintf(new_path, 128, "%s%d", log->path, (int)time(NULL));  
  14.         else  
  15.         {  
  16.             snprintf(bak_path, 128, "%s.bak", log->path);  
  17.             snprintf(new_path, 128, "%s.new", log->path);  
  18.             remove(bak_path); //delete the file *.bak first  
  19.             rename(new_path, bak_path); //change the name of the file *.new to *.bak  
  20.         }  
  21.         //create a new file  
  22.         log->fd = open(new_path, O_RDWR|O_APPEND|O_CREAT|O_SYNC, S_IRUSR|S_IWUSR|S_IROTH);  
  23.     }  
  24. }  
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值