一篇文章看懂zlog日志使用

一篇文章看懂zlog日志使用

1. What’s zlog

zlog是一个高可靠性、高性能、线程安全、灵活、概念清晰的纯C日志函数库

正因为zlog是一个日志函数库,故zlog没有独立的进程进行维护,需依赖实际调用zlog的进程,故需留意进程崩溃时的日志丢失情况。但也因为zlog是一个日志函数库,故其具有简单易用的特点,虽然简单但能满足普通日志记录的需求。

zlog日志满足以下几点日志核心需求:

  1. 支持格式化输出,如给日志添加时间、文件位置信息等
  2. 支持日志按输出等级进行输出过滤
  3. 支持异步\同步文件存储
  4. 支持日志按时间、按大小存储
  5. 支持日志滚动存储
  6. 多线程和多进程环境下保证安全转档

因此这么看下来,对于简单的日志记录,zlog将会是不错的选择,如果不需要过大复杂的功能,可以理解为时 rsyslog + logrotate的基础版了

2. Install

  1. zlog的github地址为:https://github.com/HardySimpson/zlog

  2. 使用git clone至本地,之后使用git check 切换至发布tag

  3. 使用如下命令安装至本地

    make PREFIX=/usr/local
    sudo make PREFIX=/usr/local/ install
    

    PREFIX指定了安装目标路径,安装完成之后确保能够被链接器找到,需要进行如下设置:

    /etc/ld.so.conf文件下添加安装路径

    sudo vi /etc/ld.so.conf
    

    添加/usr/local/lib,之后执行以下命令

    sudo ldconfig
    
  4. 之后就可以编写自己的程序#include "zlog.h"包含头文件之后,调用zlog API函数使用zlog了

3. Usage

zlog 有三个关键概念:分类(Category)、规则(Rule)和格式(Format)。

分类(Category)用于区分不同的输入。代码中的分类变量的名字是一个字符串,在一个程序里面可以通过获取不同的分类名的category用来后面输出不同分类的日志,用于不同的目的。

格式(Format)是用来描述输出日志的格式,比如是否有带有时间戳,是否包含文件位置信息等,上面的例子里面的格式simple就是简单的用户输入的信息+换行符。

规则(Rule)则是把分类、级别、输出文件、格式组合起来,决定一条代码中的日志是否输出,输出到哪里,以什么格式输出。

所以,当程序执行下面的语句的时候

zlog_category_t *c;

c = zlog_get_category("my_cat");

zlog_info(c, "hello, zlog"); 

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

[rules]

my_cat.DEBUG    >stdout; simple 

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

[formats]

simple = "%m%n"

最后在屏幕上打印

hello, zlog 

这就是整个过程。用户要做就是写自己的信息。日志往哪里输出,以什么格式输出,都是库和配置文件来完成的。

3.1 API usage

  1. 包含头文件

    #include "zlog.h"
    
  2. zlog初始化有两个方式

    1. 方式A,使用zlog_init()和zlog_get_category()接口

      #include <stdio.h>
      #include "zlog.h"
      
      int main(void)
      {
      	int ret = 0;
          zlog_category_t *cate = NULL;
          
          ret = zlog_init("test.conf");
          if (ret != 0) {
              printf("zlog init fail!\n");
              return -1;
          }
          
          cate = zlog_get_category("main");
          if (!cate) {
              printf("zlog category fail!\n");
              zlog_fini();
              return -2;
          }
      
          zlog_debug(cate, "hello world, debug!\n");
          zlog_info(cate, "hello world, info!\n");
          zlog_warn(cate, "hello world, warn!\n");
          zlog_error(cate, "hello world, error!\n");
      
          zlog_fini();
      
          return 0;
      }
      

      以上代码中

      • 使用zlog_init()加载配置文件,从配置文件confpath中读取配置信息到内存
      • 使用 zlog_get_category()从zlog的全局分类表里面找到分类,用于以后输出日志。如果没有的话,就建一个。然后它会遍历所有的规则,寻找和cname匹配的规则并绑定。
      • 之后调用zlog_debugzlog_infozlog_warnzlog_error输出不同等级的日志
      • 最后调用 zlog_fini()清理所有zlog API申请的内存,关闭它们打开的文件。使用次数不限。
    2. 方式B,使用 dzlog_init() 接口

      #include <stdio.h>
      #include "zlog.h"
      
      int main(int argc, char** argv)
      {
          int rc = 0;
      
          rc = dzlog_init("test.conf", "main");
          if (rc) {
              printf("zlog_intit failed\n");
              return -1;
          }
      
          int i = 0;
          while (i < 100000) {
              dzlog_info("hello, zlog");
              i++;
          }
      
          zlog_fini();
      
          return 0;
      }
      

      以上代码中,dzlog_init()zlog_init()一样做初始化,就是多需要一个默认分类名cname的参数。zlog_reload()zlog_fini()可以和以前一样使用,用来刷新配置,或者清理。

      dzlog 是忽略分类(zlog_category_t) 的一组简单zlog 接口。它采用内置的一个默认分类,这个分类置于锁的保护下。这些接口也是线程安全的。

      dzlog_set_category() 是用来改变默认分类用的。上一个分类会被替换成新的。同样不用担心内存释放的问题,zlog_fini() 最后会清理。

3.2 Configure file

在我们编写c代码时,调用 zlog_init()dzlog_init() 的时候都有传入一个配置文件的参数,接下来我们需要编写此配置文件。

文件名和路径可根据自己项目设定,但是需注意调用 zlog_init()dzlog_init() 的时的传参,上述代码中我们的配置文件叫test.conf,故我们在上述源文件目录下创建test.conf 文件,我们此处编写的配置文件内容如下:

#comments
[global]
# 规则检查
strict init = true

# 缓存最小值
buffer min = 1024

# 缓存最大值
buffer max = 2MB

# 指定锁文件,用来保证多进程情况下日志安全
# rotate lock file = /tmp/zlog.lock

# 缺省的日志格式
default format = "%d.%us %-6V (%c:%F:%L) - %m%n"

# 创建的日志文件的缺省访问权限,8进制,最终创建的日志文件权限为 "file perms" & ~umask
file perms = 600

# 日志写入指定次数后写入到触发zlog调用fsync将数据写入硬盘
# fsync period = 100

# [levels]
# TRACE = 10
# CRIT = 130, LOG_CRIT

[formats]
simple = "%m%n"
normal = "%d %m%n"

[rules]
# default.*       >stdout; simple
# *.*             "%12.2E(HOME)/log/%c.log", 1MB*12; simple
*.*             "./test.log"; normal
# *.*             "./simple.log", 1MB*12
*.*             "./test.%d(%F).log", 1MB*10 ~ "./test-%d(%F).#2r.log"
*.DEBUG           >stdout

以上配置文件中主要由四部分组成:[global] [levels] [formats] [rules] ,四部分的顺序不可调换!

  • [global] 此部分内容根据注释自己理解就行

  • [levels]用来设置输出等级的数值的,可以忽略,忽略则采用默认值,我们用默认值就够了,不用改,所以直接忽略

  • [formats] 设置输出的数据日志的格式,具体字段 %m %n的含义,可参考 《zlog使用手册》 —— 5.4.1 转换字符章节,此处定义了两种输出格式,同时在[global] 里面有设置一种默认输出格式

  • [rules]此部分用来设置,日志输出到哪里,采用什么格式输出,以及进行日志等级过滤

    • 首先是分类规则匹配,详见下表

    • 在这里插入图片描述

    • 之后是输出动作,可以输出到文件、标准输出、syslog、管道等等。

    • *.* "./test.log"; normal,举例,*.*表示匹配所有分类,"./test.log"表示输出至此文件,normal表示采用normal格式输出,注意输出动作 "./test.log"normal之间需要添加;

    • 日志输出到文件,日志名可以添加时间至文件名,以及设定单个文件大小,总文件个数限制,文件轮转,如*.* "./test.%d(%F).log", 1MB*10 ~ "./test-%d(%F).#2r.log"举例

      • *.*表示匹配所有分类

      • 1MB*10表示单个文件最大1MB,最多10个文件

      • %d(%F)表示日期格式为 年-月-日

      • #2s的意思是序号的长度最少为2位,从00开始编号,Rolling模式转档

      • 综上输出的日志文件格式为:./test.2023-10-01.log ,当此文件大于1M后发生日志轮转,轮转之后的文件为./test.2023-10-01.00.log

编译上述方式B代码,执行结果如下:

在这里插入图片描述

4. Reference

  1. 《zlog使用手册》
  2. zlog github仓库地址

创作不易,转载请注明出处!

关注、点赞+收藏,可快速查收博主有关分享!


相关推荐:

  • 6
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

爱出名的狗腿子

你的鼓励就是我最大的动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值