当前位置:   article > 正文

Linux之zlog的学习_zlog_get_category

zlog_get_category


前言

本篇仅仅是zlog的学习笔记,有错误请指正!


一、 分类(Category)、规则(Rule)和格式(Format)

  • 分类(Category)用于区分不同的输入。代码中的分类变量的名字是一个字符串,在一个程序里面可以通过获取不同的分类名的category用来后面输出不同分类的日志,用于不同的目的。
  • 格式(Format)是用来描述输出日志的格式,比如是否有带有时间戳,是否包含文件位置信息等,格式simple就是简单的用户输入的信息+换行符。
  • 规则(Rule)则是把分类、级别、输出文件、格式组合起来,决定一条代码中的日志是否输出,输出到哪里,以什么格式输出。
当程序执行下面的语句的时候

zlog_category_t *c;
c = zlog_get_category("my_zlog");

zlog_info(c, "hello, zlog");

zlog会找到c的名字是"my_zlog",对应的配置文件中的规则是

[rules]
my_zlog.DEBUG    >stdout; simple

然后库会检查,目前这条日志的级别是否符合规则中的级别来决定是否输出。因为INFO>=DEBUG,所以这条日志会被输出。并且根据这条规则,会被输出到stdout(标准输出) ,输出的格式是simple,在配置文件中定义是

[formats]
simple = "%m%n" 

最后在屏幕上打印

hello, zlog
这就是整个过程。用户要做就是写自己的信息。日志往哪里输出,以什么格式输出,都是库和配置文件来完成的。
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21

二、配置文件

大部分的zlog的行为取决于配置文件:把日志打到哪里去,用什么格式,怎么转档。
[]代表一个节的开始,四个小节的顺序不能变,依次为global-levels-formats-rules。
其中,global和levels可不写。

1.全局参数

全局参数以[global]开头。这一节可以忽略不写。

  • strict init
    如果"strict init"是true,zlog_init()将会严格检查所有的格式和规则,任何错误都会导致zlog_init() 失败并且返回-1。当"strict init"是false的时候,zlog_init()会忽略错误的格式和规则。 这个参数默认为true。
  • reload conf period
    这个选项让zlog能在一段时间间隔后自动重载配置文件。重载的间隔以每进程写日志的次数来定义。当写日志次数到了一定值后,内部将会调用zlog_reload()进行重载。每次zlog_reload()或者zlog_init()之后重新计数累加。因为zlog_reload()是原子性的,重载失败继续用当前的配置信息,所以自动重载是安全的。默认值是0,自动重载是关闭的。
  • buffer min 、 buffer max
    zlog在堆上为每个线程申请缓存。“buffer min"是单个缓存的最小值,zlog_init()的时候申请这个长度的内存。写日志的时候,如果单条日志长度大于缓存,缓存会自动扩充,直到到"buffer max”。 单条日志再长超过"buffer max"就会被截断。如果 “buffer max” 是 0,意味着不限制缓存,每次扩充为原先的2倍,直到这个进程用完所有内存为止。缓存大小可以加上 KB, MB 或 GB这些单位。默认来说"buffer min"是 1K , “buffer max” 是2MB。
  • default format
    这个参数是缺省的日志格式,默认值为:"%d %V [%p:%F:%L] %m%n"
    输出为:2012-02-14 17:03:12 INFO [3758:test_hello.c:39] hello, zlog
  • file perms
    这个指定了创建日志文件的缺省访问权限。必须注意的是最后的产生的日志文件的权限为"file perms"& ~umask。默认为600,只允许当前用户读写。
  • fsync period
    在每条规则写了一定次数的日志到文件后,zlog会调用fsync(3)来让操作系统马上把数据写到硬盘。次数是每条规则单独统计的,并且在zlog_reload()后会被清0。必须指出的是,在日志文件名是动态生成或者被转档的情况下,zlog不能保证把所有文件都搞定,zlog只fsync()那个时候刚刚write()的文件描述符。这提供了写日志速度和数据安全性之间的平衡。
  • rotate lock file
    指定了一个锁文件,用来保证多进程情况下日志安全转档。zlog会在zlog_init()时候以读写权限打开这个文件。确认你执行程序的用户有权限创建和读写这个文件。

2.日志等级自定义

这一节以[levels]开始。用于定义用户自己的日志等级,建议和用户自定义的日志记录宏一起使用。这一节可以忽略不写。
语法为:(level string) = (level int), (syslog level, optional)
(level int)必须在[1,253]这个范围内,越大越重要。(syslog level)是可选的,如果不设默认为LOG_DEBUG。

3.格式(Formats)

这一节以[formats]开始。用来定义日志的格式。语法为:(name) = “(actual formats)”
(name)被后面的规则使用。(name)必须由数字和字母组成,下划线"_"也算字母。(actual format)前后需要有双引号。 (actual formats)可以由转换字符组成。

4.规则(Rules)

这一节以[rules]开头。这个描述了日志是怎么被过滤、格式化以及被输出的。这节可以忽略不写,不过这样就没有日志输出了,所以不建议省略。
语法是:(category).(level) (output), (options, optional); (format name, optional)
当zlog_init()被调用的时候,所有规则都会被读到内存中。当zlog_get_category()被调用,规则就被被分配给分类。在实际写日志的时候,例如zlog_info()被调用的时候,就会比较这个INFO和各条规则的等级,来决定这条日志会不会通过这条规则输出。当zlog_reload()被调用的时候,配置文件会被重新读入,包括所有的规则,并且重新计算分类对应的规则。

  1. 级别配置
    zlog有6个默认的级别:“DEBUG”, “INFO”, “NOTICE”, “WARN”, “ERROR"和"FATAL”。就像其他的日志函数库那样, aa.DEBUG意味着任何大于等于DEBUG级别的日志会被输出。
表达式含义
*所有等级
aa.debug代码内等级>=debug
aa.=debug代码内等级==debug
aa.!debug代码内等级!=debug
  1. 分类匹配
    分类必须由数字和字母组成,下划线"_"也算字母。
总结配置文件规则分类匹配的代码分类不匹配的代码分类
*匹配所有* . *aa, aa_bb, aa_cc, xx, yyNONE
以_结尾的分类匹配本级及下级分类aa_.*aa,aa_bb, aa_bb_ccxx, yy
不以_结尾的精确匹配分类名aa.*aaaa_bb, aa_bb_cc
!匹配那些没有找到规则的分类!.*xxaa(as it matches rules above)
  1. 输出动作
    目前zlog支持若干种输出,语法是:[输出], [附加选项, 可选]; [format(格式)名, 可选]
动作输出字段附加选项
标准输出>stdout无意义
标准错误输出>stderr无意义
输出到syslog>syslogsyslog设施(facilitiy):LOG_USER(default), LOG_LOCAL[0-7]必填
管道输出cat
文件“文件路径”文件转档
同步IO文件“文件路径”
用户自定义输出$name"path"动态或者静态的用于record输出

三、zlog接口(API)

1.初始化和清理

int zlog_init(const char *confpath);  
/*从配置文件confpath中读取配置信息到内存。
如果confpath为NULL,会寻找环境变量ZLOG_CONF_PATH的值作为配置文件名。
如果环境变量ZLOG_CONF_PATH也没有,所有日志以内置格式写到标准输出上。
每个进程只有第一次调用zlog_init()是有效的,后面的多余调用都会失败并不做任何事情。*/

int zlog_reload(const char *confpath);
/*从confpath重载配置,并根据这个配置文件来重计算内部的分类规则匹配、重建每个线程的缓存、并设置原有的用户自定义输出函数。
可以在配置文件发生改变后调用这个函数。这个函数使用次数不限。如果confpath为NULL,会重载上一次zlog_init()或者zlog_reload()
使用的配置文件。如果zlog_reload()失败,上一次的配置依然有效。所以zlog_reload()具有原子性。*/

void zlog_fini(void);
/*清理所有zlog API申请的内存,关闭它们打开的文件。使用次数不限。*/
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

返回值:如果成功,zlog_init()和zlog_reload()返回0。失败的话,zlog_init()和zlog_reload()返回-1。详细错误会被写在由环境变量ZLOG_PROFILE_ERROR指定的错误日志里面。

2.分类(Category)操作

typedef struct zlog_category_s zlog_category_t;
zlog_category_t *zlog_get_category(const char *cname);
/*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。*/
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

返回值:如果成功,返回zlog_category_t的指针。如果失败,返回NULL。详细错误会被写在由环境变量ZLOG_PROFILE_ERROR指定的错误日志里面。

2.写日志函数及宏

下面3个函数是实际写日志的函数,输入的数据对应于配置文件中的%m。category来自于调用zlog_get_category()。

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, ...); 

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); 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28

参考资料:zlog使用手册

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/2023面试高手/article/detail/194991
推荐阅读
  

闽ICP备14008679号