高效c/c++日志工具zlog使用介绍
1. zlog简介
zlog的资料网上很多,这里不在详细说明;zlog是用c写的一个日志工具,非常小,而且高效,可以同时向控制台和文件中输出,日志接口与printf使用基本一样,所以使用起来很简单。
感觉唯一的缺点是配置稍微复杂点,不能动态修改输出级别;
2.使用介绍
2.1 zlog编译
zlog的很好编译,如果你是在x86平台上,就不用修改makefile,进入src目录下直接make就可以了;
如果是在交叉编译,移植到嵌入式设备上用,那么只需要修改src/makefile里的cc为交叉编译器的gcc,
还有一处ar修改为交叉编译器的ar:

然后make,一般都可以直接编译过,编译结束后,在src目录下生成两个库文件:
libzlog.so和libzlog.a
2.2 zlog配置文件
zlog使用时,需要先配置一下输出规则,需要写在一个文件里;下面简单介绍一下配置文件。
配置文件*.conf
配置文件具体内容如下:
[global]
#改变量可以不写,默认是true,如果使用设置为true时,Zlog就会严格检查所用格式和规则,否则,忽略所用格式和规则。
strict init = true
buffer min = 1024
buffer max = 2048
#转档指定锁文件,用于保证多进程下日志安全转档,使用默认的配置文件为锁文件。
#rotate lock file = zlog.lock
#日志访问权限,600 只允许当前用户访问
file perms = 600
[formats]
#使用默认日志输出格式 "%d %V [%p %F %L] %m%n" 输出日志格式为:%-5V按照日志级别按照左对齐
#2012-12-13 10:23:29 INFO [31668:test_hello.c:41] hello, zlog
simple = "%d.%-8.8us %-5V [%-8.8p.%-8.8t %F %L] %m%n"
#simple = "%d.%ms %m%n"
#simple2 = "%d.%us %m%n"
[rules]
#优先级从低到高 debug info notice warn fatal debug大于等于debug的优先级都能给通过debug输出。
my_cat.* >stderr;
#当hello.txt文件大小大于10MB时,会将hello.txt->hello.txt.0 0代表不删除任何文件
my_cat.INFO "hello.txt",10kb * 3 ~ "hello.txt.#r";simple
#my_cat.INFO "hello.txt",1MB ~ "hello-%d(%Y%m%d).#2s.txt";simple
#my_cat.INFO "hello.txt",1MB;simple
#my_cat.INFO "hello.txt",1MB;simple
2.3 zlog使用
zlog使用时首先要初始化配置,然后获取到一个句柄(指针),由于这个句柄是全局的,这在c中很正常,但是用c++久了,都不喜欢全局变量了,所以这里我用c++的单实例思想,把zlog初始化这部分封装了一下,这样用起来也简单,只需要把这两个文件包含进去,安照自己的需要,修改一下里面日志的路径和cat即可:
源文件log_manager.cpp:
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <dirent.h>
#include "log_manager.h"
/*********************************************************/
/*常量****************************************************/
const char* ConfigText =
"[global]\n"
"strict init = true\n"
"buffer min = 1024\n"
"buffer max = 2048\n"
"#日志访问权限,600 只允许当前用户访问\n"
"file perms = 600\n"
"[formats]\n"
"simple = \"%d.%-8.8us %-5V [%-8.8p.%-8.8t %F %L] %m%n\"\n"
"simple1= \"%m%n\"\n"
"[rules]\n"
"db_cat.warn >stderr;simple1\n"
"db_cat.ERROR \"./logs/test.txt\",1M * 3 ~ \"./logs/test.txt.#r\";simple\n";
//优先级从低到高 debug info notice warn error fatal debug大于等于debug的优先级都能给通过debug输出。
/*********************************************************/
static zlog_category_t * logHandler_m = NULL;
static int DetectConfigFile(const char *File);
/*****************************************************************************
函 数 名 : LogMgr.LogMgr
功能描述 : 日志模块初始化
输入参数 : 无
输出参数 : 无
返 回 值 :
修改历史 :
1.日 期 : 2012年12月19日 星期三
作 者 : fensjoy
修改内容 : 新生成函数
*****************************************************************************/
zlog_category_t * Init_zlog()
{
DetectConfigFile(LOG_CONFIG);
zlog_init(LOG_CONFIG);
logHandler_m = zlog_get_category(LOG_CAT);
if (!logHandler_m)
{
printf("%s in Init_zlog, get cat fail! line = %d\n",PRO_NAME, __LINE__);
zlog_fini();
remove(LOG_CONFIG);
exit(-1);
}
return logHandler_m;
};
/*****************************************************************************
函 数 名 : DetectConfigFile
功能描述 : 检测日志模块的配置文件是否存在,不存在则创建
输入参数 : const char *File
输出参数 : 无
返 回 值 : static
修改历史 :
1.日 期 : 2012年12月20日 星期四
作 者 : fensjoy
修改内容 : 新生成函数
*****************************************************************************/
static int DetectConfigFile(const char *File)
{
FILE *fp = NULL;
int iRet = 0;
DIR *log_p = NULL;
char *cmd_buf = NULL;
/*判断日志文件保存目录是否存在,不存在则创建*/
log_p = opendir(LOG_PATH);
if ( log_p == NULL )
{
printf("%s in DetectConfigFile, the log dir is not exist, now creat: %s!\n", PRO_NAME,LOG_PATH);
cmd_buf = new char[64];
printf("%s in DetectConfigFile, the log dir is not exist, now creat!\n", PRO_NAME);
snprintf(cmd_buf, 64, "mkdir -p %s &", LOG_PATH);
iRet = system(cmd_buf);
delete [] cmd_buf;
}
else
{
closedir(log_p);
}
if ( access(File, F_OK) != 0 )
{
printf("%s log config file not exist,now creat!\n", PRO_NAME);
fp = fopen(File, "w+");
if(fp == NULL)
{
perror("#[db]: in DetectConfigFile, fopen config file error!");
return -1;
}
iRet = fwrite(ConfigText, 1, strlen(ConfigText), fp);
if ( iRet < 0 )
{
perror("#[para]: in DetectConfigFile, fwrite error!");
fclose(fp);
return -1;
}
fclose(fp);
}
return 0;
}
/*****************************************************************************
函 数 名 : getZlogHandler
功能描述 : 获取zlog日志句柄
输入参数 : 无
输出参数 : 无
返 回 值 : zlog_category_t
修改历史 :
1.日 期 : 2014年1月24日 星期五
作 者 : fensjoy
修改内容 : 新生成函数
*****************************************************************************/
zlog_category_t * getZlogHandler()
{
if ( NULL == logHandler_m )
{
logHandler_m = Init_zlog();
}
return logHandler_m;
}
头文件log_manager.h
/******************************************************************************
版权所有 (C), 2001-2014,
******************************************************************************
文 件 名 : log_manger.h
版 本 号 : 初稿
作 者 : fensjoy
生成日期 : 2013年6月5日 星期三
最近修改 :
功能描述 : log_manger.cpp 的头文件
函数列表 :
修改历史 :
1.日 期 : 2013年6月5日 星期三
作 者 : fensjoy
修改内容 : 创建文件
******************************************************************************/
#ifndef __LOG_MANGER_H__
#define ___LOG_MANGER_H__
#include <iostream>
#include "zlog.h"
#define PRO_NAME "#[db]: "
#define LOG_CONFIG "./test_log.conf"
#define LOG_PATH "./"
#define LOG_CAT "test_cat" //注意这里要与配置文件中保持一致,否则无法输出
//extern zlog_category_t * logHandler_m;
zlog_category_t * Init_zlog();
zlog_category_t * getZlogHandler();
#endif /* __LOG_MANGER_H__ */
测试main函数:
#include <iostream>
#include "log_manager.h"
using namespace std;
int main(int argc, char **argv)
{
zlog_category_t *pLog = Init_zlog();
zlog_notice(pLog, "hello zlog!");
zlog_error(pLog, "this msg both to console and log file!");
zlog_debug(pLog, "this msg is debug level, just to console!");
return 0;
}
是不是很简单~;
make 编译后直接运行:

运行:
log文件内容:
用起来确实很简单,我感觉zlog比较适合用于程序的性能分析,即程序长时间运行时,记录程序运行状态,然后分析程序性能,以便于后期优化;另外zlog有个地方需要注意下,就是在日志文件达到设置的大小时,切换日志文件,如果这时程序输出日志过多间隔也比较短(100毫秒)左右时,程序会挂掉,这时zlog的一个bug。一般程序输出日志没那么多时,不会出现
源代码已上传CSDN:
https://download.csdn.net/download/wuquan_1230/10931319
由于上传时下载积分最低选项是1,所以无法设置为0,如果没有积分可以微信公众号给我发消息,
我发你邮箱
微信订阅号:

高效c/c++日志工具zlog使用介绍的更多相关文章
- .NET日志工具介绍
最近项目需要一个日志工具来跟踪程序便于调试和测试,为此研究了一下.NET日志工具,本文介绍了一些主流的日志框架并进行了对比.发表出来与大家分享. 综述 所谓日志(这里指程序日志)就是用于记录程序执行过 ...
- 渗透测试之BurpSuite工具的使用介绍(三)
若希望从更早前了解BurpSuite的介绍,请访问第二篇(渗透测试之BurpSuite工具的使用介绍(二)):https://www.cnblogs.com/zhaoyunxiang/p/160002 ...
- 高效使用Java构建工具,Maven篇|云效工程师指北
大家好,我是胡晓宇,目前在云效主要负责Flow流水线编排.任务调度与执行引擎相关的工作. 作为一个有多年Java开发测试工具链开发经验的CRUD专家,使用过所有主流的Java构建工具,对于如何高效使用 ...
- 细说Java主流日志工具库
概述 在项目开发中,为了跟踪代码的运行情况,常常要使用日志来记录信息. 在Java世界,有很多的日志工具库来实现日志功能,避免了我们重复造轮子. 我们先来逐一了解一下主流日志工具. java.util ...
- Java主流日志工具库
在项目开发中,为了跟踪代码的运行情况,常常要使用日志来记录信息.在Java世界,有很多的日志工具库来实现日志功能,避免了我们重复造轮子.我们先来逐一了解一下主流日志工具. 1.java.util.lo ...
- 【工具推荐】ELMAH——可插拔错误日志工具
今天看到一篇文章(构建ASP.NET网站十大必备工具(2)),里面介绍了一个ELMAH的错误日志工具,于是研究了一下. ELMAH 是 Error Logging Modules and Handle ...
- Android-LogCat日志工具(二)
既然是Java语言,那么对于很多人来说,用System.out.println() 方法来打印日志是最熟悉.最简单不过了.不过在真正的项目开发中,是极度不建议使用 System.out.println ...
- Java 标准日志工具 Log4j 的使用(附源代码)
源代码下载 Log4j 是事实上的 Java 标准日志工具.会不会用 Log4j 在一定程度上可以说是衡量一个开发人员是否是一位合格的 Java 程序员的标准.如果你是一名 Java 程序员,如果你还 ...
- Android Studio 单刷《第一行代码》系列 02 —— 日志工具 LogCat
前情提要(Previously) 本系列将使用 Android Studio 将<第一行代码>(书中讲解案例使用Eclipse)刷一遍,旨在为想入坑 Android 开发,并选择 Andr ...
随机推荐
- 终于理解Python中的迭代器和生成器了!
迭代器和生成器 目录 迭代器和生成器 可迭代对象和迭代器 基础概念 判断 for循环本质 不想用for循环迭代了,如何使用迭代器? 列表推导式 生成器Generator 概念 如何实现和使用? 生成器 ...
- windows dos 批量重命名文件
描述 在工作中经常出现 在同一目录下有一些 很多相同扩展名的文件但是名字看起来很乱各不同,我们想将它们统一重命名一下统一的格式,如果一个个去改名字太麻烦了. 这里我门就可以使用windows下 dos ...
- java 基本语法(十七)Lambda (四)构造器引用与数组引用
1.构造器引用格式:类名::new 2.构造器引用使用要求:和方法引用类似,函数式接口的抽象方法的形参列表和构造器的形参列表一致.抽象方法的返回值类型即为构造器所属的类的类型 3.构造器引用举例: / ...
- 爬虫04 /asyncio、selenium规避检测、动作链、无头浏览器
爬虫04 /asyncio.selenium规避检测.动作链.无头浏览器 目录 爬虫04 /asyncio.selenium规避检测.动作链.无头浏览器 1. 协程asyncio 2. aiohttp ...
- 数据可视化之分析篇(九)PowerBI数据分析实践第三弹 | 趋势分析法
https://zhuanlan.zhihu.com/p/133484654 以财务报表分析为例,介绍通用的分析方法论,整体架构如下图所示: (点击查看大图) 我会围绕这五种不同的方法论,逐步阐述他们 ...
- ASP.NET Core策略授权和 ABP 授权
目录 ASP.NET Core 中的策略授权 策略 定义一个 Controller 设定权限 定义策略 存储用户信息 标记访问权限 认证:Token 凭据 颁发登录凭据 自定义授权 IAuthoriz ...
- 将python3打包成为exe可执行文件(pyinstaller)
我们工作中可能会遇到,客户需要一个爬虫或者其他什么功能的python脚本. 这个时候,如果我们直接把我们的python脚本发给客户,会有两个问题: 1.客户的电脑或者服务器可能并没有安装python环 ...
- 仔细想想SpringAOP也不难嘛,面试没有必要慌
文章已托管到GitHub,大家可以去GitHub查看阅读,欢迎老板们前来Star! 搜索关注微信公众号 码出Offer 领取各种学习资料! LOGO SpringAOP 一.什么是AOP AOP(As ...
- 切换npm源的几种方法
我们在使用官方提供的npm源安装各种依赖包的时候,下载速度会很慢,通常需要更换npm源. 我们可以在终端中输入命令 npm config list 来查看 npm 源地址,默认地址为 metrics- ...
- spring-cloud-alibaba-sentinel和feign配合使用,启动报Caused by: java.lang.AbstractMethodError: com.alibaba.cloud.sentinel.feign.SentinelContractHolder.parseAndValidateMetadata(Ljava/lang/Class;)Ljava/util/List
背景 我在学习spring-cloud-alibaba技术栈期间,在学习服务熔断与限流的时候,服务启动发生了以下异常 #这是控制台最上面的 sun.misc.Unsafe.park(Native Me ...