高效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 ...
随机推荐
- 安装FeedReader添加RSS订阅
#0x1 FeedReader FeedReader是一款功能齐全,界面优美的GTK+ 3RSS阅读器客户端,用于在线RSS服务. FeedReader目前支持Feedbin,Feedly,Fresh ...
- Python List comprehension列表推导式
http://blog.chinaunix.net/uid-28631822-id-3488324.html 具体内容需要进一步学习
- vue中使用ts时如何导入mixins
方法一 // mixins.ts import { Vue } from "vue-property-decorator"; export class TableSelect ex ...
- 数据可视化之DAX篇(二十二)一文搞懂Power BI中的排名问题
https://zhuanlan.zhihu.com/p/68384001 本文聊聊在PowerBI中如何进行各种类型的排名问题. PowerBI中计算排名主要使用RANKX函数,关于该函数的具体语法 ...
- 数据可视化之PowerQuery篇(八)利用PowerQuery,进行更加灵活的数据分列
https://zhuanlan.zhihu.com/p/66540160 常规分列 我们最常见的就是有固定分隔符的规范数据,这种直接就按照分隔符拆分就可以了, 如果没有分割符怎么办?依然是上面的数据 ...
- Python函数05/内置函数/闭包
Python函数05/内置函数/闭包 目录 Python函数05/内置函数/闭包 内容大纲 1.内置函数(二) 2.匿名函数及内置函数(重要) 3.闭包 4.今日总结 5.今日练习 内容大纲 1.内置 ...
- 数据可视化实例(八): 边缘直方图(matplotlib,pandas)
https://datawhalechina.github.io/pms50/#/chapter6/chapter6 边缘直方图 (Marginal Histogram) 边缘直方图具有沿 X 和 Y ...
- 【高性能Mysql 】读书笔记(三)
第5章 创建高性能的索引 本文为<高性能Mysql 第三版>第四章读书笔记,Mysql版本为5.5 索引基础 索引的重要性:找一本800面的书的某一段内容,没有目录也没有页码(页码也可类比 ...
- [Qt插件]-03创建Qt Designer自定义部件
如何创建自定义部件并添加到Qt Designer来爽快的拖动部件可视化界面设计? Qt Designer基于插件的架构使得它可以使用用户设计或者第三方提供的自定义部件,就像使用标准的Qt部件一样. ...
- Go Pentester - HTTP Servers(3)
Building Middleware with Negroni Reasons use middleware, including logging requests, authenticating ...