1. zlog日志系统
- zlog是一个高性能, 线程安全, 灵活, 概念清晰的纯C日志函数库. 作者编写的初衷是因为log4c不给力, 而log4j, log4cxx等log4系列的日志函数库在概念上不正确. zlog继承了unix操作系统中syslog的伟大传统, 将日志系统的分类, 级别, 输出方向, 输出格式完全解耦.
1.1 zlog下载(Linux环境下)
-
zlog下载地址: https://github.com/HardySimpson/zlog
-
下载到window上, 通过Secure CRT远程登陆我们的虚拟机或者服务器. 使用rz命令将master.zip文件添加进去.
或者在Linux下: ~$ wget https://github.com/HardySimpson/zlog/archive/refs/heads/master.zip -
压缩包是 .zip格式 . ubuntu通常已经安装zip, 如果没有zip, 那么安装zip: sudo apt install zip unzip
解压: unzip master.zip -
文件夹内容如下:
1.2 zlog动态库的安装与使用
- make
- sudo make install
我们可以看到动态库与头文件分别拷贝到了 ‘/usr/local/lib/’ 与 ‘/usr/local/include/’ 路径下
在程序运行之前, 保证libzlog.so在系统的动态链接库加载器可以找到的目录下.
$ sudo vim /etc/li.so.conf
/usr/local/lib
$ sudo ldconfig
2. zlog配置文件
2.1 配置文件
-
配置文件代码如下:
[global] strict init = true [formats] simple = "%d(%F %r) %V [%p:%F:%L] %m%n" [rules] test_normal.NOTICE "./test.log" ; simple test_debug.DEBUG "./test.log"; simple
zlog中有四个概念: category, levels, format, rule
其中: [global] 为全局参数
-strict init 如果是true, zlog_init()函数将严格检测所有的格式和规则, 任何错误都会导致zlog_init()失败并且返回-1.
-strict init 如果是false的时候, zlog_init()会忽略错误的格式和规则
-simple输出格式为: 2021-04-12 10:30:52 am NOTICE [27007:lightd.c:176] hello其中: [levels] 用于定义用户自己的日志等级, 建议和用户自定义的日志记录宏一起使用. 若不自定义等级可不写.
-语法为: (level string) = (level int), (syslog level, optional)
(level int)必须在[1,253]这个范围内, 越大越重要. (syslog level)是可选的, 如果不设默认为LOG_DEBUG.
zlog有6个默认级别: “DEBUG”, “INFO”, “NOTICE”, “WARN”, “ERROR”, “FATAL”其中: [format] 是用来描述输出日志的格式.
-simple = “%d(%F %r) %V [%p:%F:%L] %m%n”
-simple输出格式为: 2021-04-12 10:30:52 am NOTICE [27007:lightd.c:176] hello其中[rules]: 是把分类, 级别, 输出文件, 格式组合起来. 决定一条代码中的日志是否输出, 输出到哪里, 以及什么格式输出.
- 更加详细的zlog配置文件的信息可以参考zlog配置文件
2.2 zlog函数API
-
zlog常用函数API如下:
-
int zlog_init(const char *config) // 打开配置文件, 成功返回0.
zlog_init()从配置文件confpath中读取配置信息到内存. 如果confpath为NULL, 会寻找环境变量ZLOG_CONF_PATH的值作为配置文件名. 如果环境变量ZLOG_CONF_PATH也没有, 所有日志以内置格式写到标准输出上. 每个进程只有第一次调用zlog_init()是有效的, 后面的多余调用都会失败并不做任何事情. -
zlog_category_t *zlog_get_category(const char *cname) // 在配置文件中找到分类, 确定该分类对于的打印级别, 打印大于等于该级别的消息.
zlog_get_category()从zlog的全局分类表里面找到分类, 用于以后输出日志. 如果没有的话, 就建一个. 然后它会遍历所有的规则, 寻找和cname匹配的规则并绑定. 如果成功, 返回zlog_category_t的指针. 如果失败, 返回NULL. 详细错误会被写在由环境变量ZLOG_PROFILE_ERROR指定的错误日志里面. -
列表宏
zlog_fatal(cat, format, …) //打印fata级别的消息
zlog_error(cat, format, …) //打印error级别的消息
zlog_warn(cat, format, …) //打印warn级别的消息
zlog_notice(cat, format, …) //打印notice级别的消息
zlog_info(cat, format, …) //打印info级别的消息
zlog_debug(cat, format, …) //打印debug级别的消息
这些函数不返回. 如果有错误发生, 详细错误会被写在由环境变量ZLOG_PROFILE_ERROR指定的错误日志里面. -
void zlog_fini(void) //释放zlogAPI申请的内存
zlog_fini()清理所有zlog API申请的内存,关闭它们打开的文件。使用次数不限。
3. zlog日志系统测试用例
3.1 测试用例:
-
test.conf 配置文件代码如下:
[global] strict init = ture [formats] simple = "%d(%F %r) %V [%p:%F:%L] %m%n" [rules] test_normal.NOTICE "./test.log" ; simple test_debug.DEBUG "./test.log"; simple
-
test.c代码如下:
#include <stdio.h> #include "zlog.h" int main(int argc, char **argv) { zlog_category_t *zc =NULL; char *conf_file = "./test.conf"; int rc = -1; rc = zlog_init(conf_file); if( rc ) { printf("zlog_init false\n"); return -1; } zc = zlog_get_category("test_notice"); //注意'test_normal' 与配置文件中相匹配, 级别大于等于的会打印到日志中. if( !zc ) { printf("zlog_get_category false\n"); return -2; } zlog_debug(zc, "zlog_debug"); zlog_info(zc, "zlog_info"); zlog_notice(zc, "zlog_notice"); zlog_warn(zc, "zlog_warn"); zlog_error(zc, "zlog_error"); zlog_fatal(zc, "zlog_fatal"); zlog_fini(); return 0; }
3.2 运行结果
-
我们可以查看到产生了test.log文件, 通过查看该文件可以看到, 日志级别大于等于NOTICE的输出到了日志文件中.
-
在项目中需要进行日志级别的区别, 比如进行debug模式, 我们zlog日志系统中可以在配置文件中提前写好debug的分类, zlog_get_category() 函数进行一下选择即可
-
以上为zlog简单使用.
-
参考zlog使用手册
4. valgrind检测是否存在内存泄漏
- 在编写程序, 特别时调用第三方库时, 难免会发生内存泄漏. 在程序写完之后, 要保持一个良好的习惯, 使用valgring检测是否存在内存泄漏.
其中: --tool=memcheck是指定使用memcheck工具 --leak-check=full指的是完全检查内存泄漏, --show-reachable=yes是显示内存泄漏的地点. - 总堆使用量: 85次分配, 85次释放, 846,092字节分配.
- 所有堆块都已释放–不可能有泄漏.