首页 > 技术文章 > 分享一个日志系统源码(C语言)

prophet-ss 2017-12-12 01:27 原文

代码路径:https://github.com/prophetss/C-log

  这是一个简单、高效和轻量级C语言写的的日志系统,linux下不需要第三方库安装。目前主要是在linux下编写和测试,通用分支(这里)为一个基于Apache的APR(一个C语言跨平台的开源库)编写的跨平台版本,由于精力有限只基于最简单的日志打印功能进行了改写,仅供参考。

  日志系统支持多线程多句柄、印级别控制、IO缓存设置、备份控制、日志文件大小控制、异常退出堆栈打印、加密(AES-128)、压缩(lz4)和散列校验(MD5)。所有配置和接口都在log.h内。堆栈打印是接收所有异常退出信号时打印堆栈,输出文件名通过TRACE_PRINT_PATH宏控制,在其信号处理时还对所有日志句柄进行刷新处理,减少日志丢失可能。下面介绍下接口使用:

日志创建:

  //log_filename:输出文件名。

  //max_file_size:每个文件最大上限。

  //max_file_bak:最大备份文件数量,备份文件名为输出文件名末尾+备份序号,如有其它需要可自行修改。

  //max_iobuf_size:IO缓存大小,可以设为0无缓存。

  //cflag:三个宏选项,NORMALIZE, ENCRYPT, COMPRESS 或者 ENCRYPT|COMPRESS,分别对应正常,只加密/压缩,加密和压缩。

  //password:密码,在cflag有设ENCRYPT时生效。

  //返回为一个log句柄,可以创建多个,数量最大值由MAX_HANDLE_NUM宏控制。

  log_t* log_create(const char *log_filename, size_t max_file_size, size_t max_file_bak, size_t max_iobuf_size, int cflag, const char *password);

刷新和销毁为:

  //刷新是将IO缓存内数据刷新到文件内,lh为创建返回的句柄指针。

  void log_flush(log_t *lh);

  void log_destory(log_t *lh);

日志打印:

  /*日志内容可以是任意类型,由format控制(类似printf函数的format)。日志等级设置为四个宏LOG_DEBUG、LOG_INFO、LOG_WARN和LOG_ERROR(如有需要更多细分可以很方便添加扩展),代码中低于此等级的打印不会生效,LOG_CLOSE为关闭日志功能,所有打印在编译期间过滤不影响效率。LOG_DEBUG会额外输出:时间  文件名【行号】线程号: ***(日志内容)。*/

  #define log_debug(lh, format, ...)

  #define log_info(lh, format, ...)

  #define log_warn(lh, format, ...)

  #define log_error(lh, format, ...)

日志解密、解压和散列:

  //in_filename:待解密文件名,解密完成不删除

  //out_filename:解密后文件名

  //password:对应创建log句柄的密码

  //返回0-成功,其他-失败。

  int log_decipher(const char *in_filename, const char *out_filename, const char *password);

  //src_filename:带解压文件,解压完不删除

  //dst_filename:解压后文件名

  //返回0-成功,其他-失败。解缩内部有校验。

  //注意加密是在每条日志写入IO缓存前进行的,压缩是备份时整个文件进行压缩的,所以如果同时加密压缩,先解压再解密

  int log_uncompress(const char *src_filename, const char *dst_filename);

  //filename:待散列文件名

  //digest:输出转化为32个十六进制字符,如果digest为NULL,内部会自动申请内存,否则其size至少应为33(32加尾部'\0')

  //返回:digest

  char* log_md5(const char *filename, char *digest);

 

  所有具体使用有个简单测试例子在sample文件夹内,直接make就可以生成,详细可看代码,内部还有一个多线程安全时间计时器可以精确到纳秒,计数器个数可以由TIMEKEEPER_NUM这个宏控制,详细功能可以看这里

  最后欢迎提问和反馈问题,不胜感激!

推荐阅读