c语言日志管理系统 --- zlog

前言

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

一.源码安装

源码获取(源码资源很多,其他安装方法也可以)

spy@ubuntu:~$ git clone https://github.com/HardySimpson/zlog.git //获取源码
spy@ubuntu:~$ cd zlog //进入zlog文件夹
spy@ubuntu:~/zlog/$ ls //查看
Changelog  COPYING  doc  INSTALL  makefile  README.md  src  test  TODO  tools

spy@ubuntu:~/zlog/$ make //进行安装
make install 需要sudo权限  若安装到其他路径 需要cd当前文件src中修改makefile文件修改如下图
spy@ubuntu:~/zlog/$ sudo make install 

这里我设置安装的路径为50行  ../bulid_linux    修改该文件后回到上级文件zlog下执行make install即可

执行安装后

二.zlog常用函数接口(API)

1、初始化:

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

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

     void zlog_fini(void);
     zlog_fini()清理所有zlog API申请的内存,关闭它们打开的文件。使用次数不限。

返回值如果成功,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的规律描述如下:

    匹配任意cname。
    以下划线_结尾的分类名同时匹配本级分类和下级分类。例如aa_匹配aa, aa_, aa_bb, aa_bb_cc这几个cname。
    不以下划线_结尾的分类名精确匹配cname。例如aa_bb匹配aa_bb这个cname。
    ! 匹配目前还没有规则的cname。
    每个zlog_category_t *对应的规则,在zlog_reload()的时候会被自动重新计算。不用担心内存释放,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, ...); 

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_fatal(cat, format, …)

zlog_error(cat, format, …)

zlog_warn(cat, format, …)

zlog_notice(cat, format, …)

zlog_info(cat, format, …)

zlog_debug(cat, format, …)

三.zlog使用及文件配置

每一个[ ]代表一个小节,四个小节的顺序需严格按照[global] [levels] [formats] [rules]语法为 key = value

一、文件配置

配置文件格式为

[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"
file perms = 600
[levels]

[formats]

[rules]

[global] 全局参数

strict init
如果"strict init"是true,zlog_init()将会严格检查所有的格式和规则,任何错误都会导致zlog_init() 失败并且返回-1。当"strict init"是false的时候,zlog_init()会忽略错误的格式和规则。 这个参数默认为true。

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。

rotate lock file
锁文件,确保多线程程序在记录日志时引发的安全问题,默认为日志文件走作为锁。

default format
这个参数是缺省的日志格式,默认值为:"%d %V [%p:%F:%L] %m%n"
这种格式产生的输出类似这样:
2012-02-14 17:03:12 INFO [3758:test_hello.c:39] hello, zlog

[levels] 日志等级

这一小节可以在配置文件中忽略

//默认等级
DEBUG = 20, LOG_DEBUG
INFO = 40, LOG_INFO
NOTICE = 60, LOG_NOTICE
WARN = 80, LOG_WARNING
ERROR = 100, LOG_ERR
FATAL = 120, LOG_ALERT
UNKNOWN = 254, LOG_ERR

如果修改则需要在配置文件的[level]一节中 定义

配置文件格式为

[global]

[levels]
OTHER = 30, LOG_DEBUG

[formats]

[rules]

配置文件中配置后  对于zlog 整数30 代表了一个等级字符串(OTHER) 这个整数必须位于[1,253]之间,不能超过这个范围,数字越大等级越高。

[Formats] 格式

用来定义日志的格式。语法为:

name) = “(actual formats)”

(name)被后面的规则使用。(name)必须由数字和字母组成,下划线"_"也算字母。(actual format)前后需要有双引号。

配置文件格式为

[gloabal]

[levels]

[formats]
ms = "%d.%ms %m%n"
us = "%d.%us %m%n"

nu1 = "%m%n"
nu2 = "%d(%m-%d %T) %-10V [%p:%F:%L] %m%n"
nu3 = "%d(%m-%d %T) %-5c [%p:%F:%L] %m%n"

[rules]

#%n: 换行符
#%m: 用户从zlog函数输入的日志信息
#%c: 分类名
#%V: 日志级别
#%p: 进程id
#%F: 源代码文件名
#%L: 源代码行数
#%ms: 毫秒,3位数字字符串
#%us: 微秒,6位数字字符串
#%d(): 日志的时间。 如果不跟小括号,默认是%d(%F %T) | %F: 年-月-日 (%Y-%m-%d) | %T: 小时:分钟:秒 (%H:%M:%S)
#%-5c: 左对齐,最小宽度5

[rules] 规则

用于描述日志是怎么被过滤、格式化以及被输出的。这节可以若忽略不写,日志输没有输出,这也是配置文件中不可缺省的重要部分。

[global]

[levels]

[formats]

[rules]

my.ERROR    "./test.log";nu1   //my为zlog_get_category("my");定义的要匹配的字符串('my.ERROR' 表示代码内等级大于等于ERROR 输出到文件./test.log中);nu1为format中定义的格式类型 
my.=DEBUG   >stdout .= 表示代码内等级为DEBUG 输出到标准输出
    

1.级别匹配


2.分类匹配

 

四、简单测试

  配置文件     vim test.conf  (可省略的为默认状态)

[global]
strict init = true

[levels]
DEBUG = 20,LOG_DEBUG
INFO = 40,LOG_INFO

[rules]

my.ERROR           "./test.log" 
my.=error          >stdout 

 

测试代码:

#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include "zlog.h"

int main (char argc, char **argv)
{
    zlog_category_t *zc = NULL;    
    char            *conf_file = "./test.conf";
    int             rv = -1;
    rv = zlog_init(conf_file);
    
    if(rv)
    {
        printf("init  zlog failed\n");
        return -1;
        zlog_fini();
     }
    
    zc = zlog_get_category("my");
    if( !zc ) {
        printf("zlog_get_category false\n");
        return -2;
    }

    zlog_debug(zc, "zlog, debug\n"); 
    //zlog_debug(zc, "zlog, debug %d\n",a); 可加格式控制
    
    zlog_info(zc, "zlog ,info\n ");
    zlog_notice(zc, "zlog, notice\n");
    zlog_warn(zc, "zlog, warn\n");
    zlog_error(zc, "zlog, error\n");
    zlog_fatal(zc, "zlog,fatal\n");
  
    zlog_fini();
    return 0;
    
}

输出结果

查看日志 test.log

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值