zlog日志库(笔记) —— zlog接口(API)
引入头文件
zlog所有接口都是线程安全的,使用时只需要包含头文件
#include "zlog.h"
初始化和清理
总览
ini zlog_init(const char *confpath);
int zlog_reload(const char *confpath);
void zlog_fini(void);
接口描述
zlog_init: 从配置文件confpath读取配置信息到内存。如果confpath为NULL,会寻找环境变量ZLOG_CONF_PATH的值作为配置文件名;如果环境变量 ZLOG_CONF_PATH为空,所有日志以内置格式写到标准输出(stdout)上。每个进程只有第一次调用zlog_init()有效,后面多余调用都会失败并且不做任何事情。
zlog_reload(): 从confpath重载配置,并根据该配置文件重新计算内部的分类规则匹配、重建每个线程的缓存,并设置原有的用户自定义输出函数。可以做配置文件发生改变后调用该函数。该函数调用次数不限。如果confpath为NULL,会重载上一次zlog_init()或zlog_reload()时使用的配置文件;如果zlog_reload()失败,上一次的配置依然有效。所以zlog_reload()具有原子性。
zlog_fini(): 清理所有zlog API申请的内存,关闭它们打开的文件。使用次数不限。
返回值
如果成功,zlog_init()和zlog_reload()返回0;失败,zlog_init()和zlog_reload()返回-1。详细错误,会被写到由环境变量ZLOG_PROFILE_ERROR指定的错误日志里去。
分类(Category)操作
总览
typedef struct zlog_category_st zlog_category_t;
zlog_category_t *zlog_get_category(const char *name);
接口描述
zlog_get_category() 从zlog的全局分类表里找到分类,用于以后输出日志;如果没有的话,就新建一个。然后,函数会遍历所有的规则,寻找和cname匹配的规则并绑定。
配置文件规则中的分类名匹配cname的规律描述如下:
1)*匹配任意cname;
2)以下划线("")结尾的分类名同时匹配本级分类和下级分类,例如"aa"匹配aa, aa_, aa_bb, aa_bb_cc这几个cname;
3)不以下划线("_")结尾的分类名精确匹配cname,例如"aa_bb"匹配"aa_bb"这个cname;
4)"!"匹配目前还没有规则的cname;
每个zlog_category_t*对应的规则,在zlog_relaod()时会被自动重新计算。不用担心内存释放,zlog_fini()最后会清理一切。
返回值
如果调用成功,返回zlog_category_t的指针;如果失败,返回NULL。详细错误,会被写到由环境变量ZLOG_PROFILE_ERROR指定的错误日志里去。
写日志函数及宏
总览
void zlog(zlog_category_t * category,
const char *file, size_t filelen,
const char *func, size_t funclen,
long line, int level,
const char *format, ...) ZLOG_CHECK_PRINTF(8,9);
void vzlog(zlog_category_t * category,
const char *file, size_t filelen,
const char *func, size_t funclen,
long line, int level,
const char *format, va_list args);
void hzlog(zlog_category_t * category,
const char *file, size_t filelen,
const char *func, size_t funclen,
long line, int level,
const void *buf, size_t buflen);
接口描述
3个函数是实际写日志的函数,输入的数据对应于配置文件中的%m。category来源于调用zlog_get_category()。
zlog()和vzlog()根据format输出,就像printf(3)和vprintf(3)。vzlog()相当于zlog(),不过它用一个va_list参数args,来表示可变参数列表,而不是"..."。vzlog()内部使用了va_copy宏,args内容在vzlog()后保持不变,可参考stdarg(3)。
hzlog()有些区别,它产生下面这样的输出,长度buf_len的内存buf以16进制的形式表示出来。
hex_buf_len=[5365]
0 1 2 3 4 5 6 7 8 9 A B C D E F 0123456789ABCDEF
0000000001 23 21 20 2f 62 69 6e 2f 62 61 73 68 0a 0a 23 20 #! /bin/bash..#
0000000002 74 65 73 74 5f 68 65 78 20 2d 20 74 65 6d 70 6f test_hex - tempo
0000000003 72 61 72 79 20 77 72 61 70 70 65 72 20 73 63 72 rary wrapper scr
参数file和line填写为__FILE__和__LINE__宏,用于标识日志是在哪个文件和哪一行发生的。参数func填写为__func__ (C99)或__FUNCTION__ (GCC),如果编译器不支持的话,就填写为"
level是一个整数,应该在下面几个里面取值:
typedef enum {
ZLOG_LEVEL_DEBUG = 20,
ZLOG_LEVEL_INFO = 40,
ZLOG_LEVEL_NOTICE = 60,
ZLOG_LEVEL_WARN = 80,
ZLOG_LEVEL_ERROR = 100,
ZLOG_LEVEL_FATAL = 120,
} zlog_level;
每个函数都有便于使用的宏,如:
#define zlog_fatal(cat, ...) \
zlog(cat, __FILE__, sizeof(__FILE__)-1, __func__, sizeof(__func__)-1, __LINE__, \
ZLOG_LEVEL_FATAL, __VA_ARGS__)
由于编译器下,可变参数的使用有所区别,因此这里不展示所有编译器下的宏实现。只列出所有宏列表:
/* 便于用户调用的写日志接口(宏函数) */
/* zlog macros */
zlog_fatal(cat, format, ...)
zlog_error(cat, format, ...)
zlog_warn(cat, format, ...)
zlog_notice(cat, format, ...)
zlog_info(cat, format, ...)
zlog_debug(cat, format, ...)
/* vzlog macros */
vzlog_fatal(cat, format, args)
vzlog_error(cat, format, args)
vzlog_warn(cat, format, args)
vzlog_notice(cat, format, args)
vzlog_info(cat, format, args)
vzlog_debug(cat, format, args)
/* hzlog macros */
hzlog_fatal(cat, buf, buf_len)
hzlog_error(cat, buf, buf_len)
hzlog_warn(cat, buf, buf_len)
hzlog_notice(cat, buf, buf_len)
hzlog_info(cat, buf, buf_len)
hzlog_debug(cat, buf, buf_len)
返回值
无返回值。如果有错误发生,详细错误会被写在由环境变量ZLOG_PROFILE_ERROR指定的错误日志里面。
MDC操作
总览
int zlog_put_mdc(const char *key, const char *value);
char *zlog_get_mdc(const char *key);
void zlog_remove_mdc(const char *key);
void zlog_clean_mdc(void);
接口描述
MDC(Mapped Diagnostic Context) 是一个线程拥有的键-值表,和分类没什么关系。
key-value是字符串,长度不能超过MAXLEN_PATH(1024);如果超过,则会被截断。
记住这个表是和线程绑定到,每个线程都有自己的表,所以在一个线程内的调用不会影响其他线程,也就是说对其操作是线程安全的。
返回值
zlog_put_mdc()成功返回0,失败返回-1。
zlog_get_mdc成功返回value的指针;失败返回没有相应的key,则返回NULL。
如果有错误发生,详细错误会被写在由环境变量ZLOG_PROFILE_ERROR指定的错误日志里面。
dzlog接口
总览
int dzlog_init(const char *confpath, const char *cname);
int dzlog_set_category(const char *cname);
void dzlog(const char *file, size_t filelen,
const char *func, size_t funclen,
long line, int level,
const char *format, ...);
void vdzlog(const char *file, size_t filelen,
const char *func, size_t funclen,
long line, int level,
const char *format, va_list args);
void hdzlog(const char *file, size_t filelen,
const char *func, size_t funclen,
long line, int level,
const void *buf, size_t buflen);
接口描述
dzlog是忽略分类(zlog_category_t)的一组简单zlog接口。它采用内置的一个默认分类,该分类置于锁的保护之下。这些接口也是线程安全的。忽略了分类,意味着用户不需要操心创建、存储、传输zlog_category_t类型的变量。当然,也可以在用dzlog接口的同时,用一般的zlog接口函数。
dzlog_init()和zlog_init()一样做初始化,就是多需要一个默认分类名cname的参数。zlog_reload()、zlog_fini()可以和以前一样使用,用来刷新配置,或者清理。
dzlog_set_category()用来改变默认分类用的。上一个分类会被替换成新的。同样不用担心内存释放问题,zlog_fini()最后会做清理。
dzlog相关便捷宏,也定义中zlog.h里面。
/* 采用内置的默认分类 */
dzlog_fatal(format, ...)
dzlog_error(format, ...)
dzlog_warn(format, ...)
dzlog_notice(format, ...)
dzlog_info(format, ...)
dezlog_debug(format, ...)
vdzlog_fatal(format, args)
vdzlog_error(format, args)
vdzlog_warn(format, args)
vdzlog_notice(format, args)
vdzlog_info(format, args)
vdzlog_debug(format, args)
hdzlog_fatal(buf, buf_len)
hdzlog_error(buf, buf_len)
hdzlog_warn(buf, buf_len)
hdzlog_noticebuf, buf_len)
hdzlog_info(buf, buf_len)
hdzlog_debug(buf, buf_len)
返回值
成功调用,dzlog_init()和dzlog_set_category()返回0;失败时,dzlog_init()和dzlog_set_category()返回-1。详细错误会被写在ZLOG_PROFILE_ERROR指定错误日志里面。
用户自定义输出
总览
typedef struct zlog_msg_s {
char *buf;
size_t len;
char *path;
} zlog_msg_t;
typedef int (*zlog_record_fn)(zlog_msg_t *msg);
int zlog_set_record(const char *name, zlog_record_fn record);
接口描述
zlog允许用户自定义输出函数。输出函数需要绑定到某条特殊规则(rules)上。例:
[rules]
*.* $name, "record path %c %d"; simple
zlog_set_record()做绑定动作。规则中,输出段有$name,会被用来做用户自定义输出。输出函数record。该函数需要为zlog_record_fn格式。
zlog_msg_t结构的各成员描述如下:
- path 来自规则的逗号后的字符串,该字符串会被动态解析,输出当前path,就像动态文件路径一样;
- buf和len是zlog格式化后的日志信息和长度;
所有zlog_set_record()做的绑定,在zlog_reload()使用后继续有效。
返回值
成功调用时,返回0;失败返回-1。详细错误会被写在ZLOG_PROFILE_ERROR指定错误日志里面。
调试和诊断
总览
void zlog_profile(void);
接口描述
环境变量ZLOG_PROFILE_ERROR指定zlog本身的错误日志。
环境变量ZLOG_PROFILE_DEBUG指定zlog本身的调试日志。
zlog_profile()打印所有内存中的配置信息到ZLOG_PROFILE_ERROR。可以把这个和配置文件比较,看看有没有问题。