高效c/c++日志工具zlog使用介绍

简介: 高效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


相关实践学习
日志服务之使用Nginx模式采集日志
本文介绍如何通过日志服务控制台创建Nginx模式的Logtail配置快速采集Nginx日志并进行多维度分析。
目录
相关文章
|
6天前
|
Linux 应用服务中间件 PHP
性能工具之linux常见日志统计分析命令
通过本文的介绍,我相信同学们一定会发现 linux三剑客强大之处。在命令行中,它还能够接受,和执行外部的 AWK 程序文件,可以对文本信息进行非常复杂的处理,可以说“只有想不到的,没有它做不到的。
60 1
|
6天前
|
存储 C++
基于C++的简易文件压缩与解压缩工具设计与实现
基于C++的简易文件压缩与解压缩工具设计与实现
21 3
|
6天前
|
数据可视化
R语言两阶段最小⼆乘法2SLS回归、工具变量法分析股息收益、股权溢价和surfaces曲面图可视化
R语言两阶段最小⼆乘法2SLS回归、工具变量法分析股息收益、股权溢价和surfaces曲面图可视化
|
6天前
|
监控 Linux 开发者
【专栏】`head`命令是Linux系统中用于快速查看文件开头内容的工具,常用于处理日志文件
【4月更文挑战第28天】`head`命令是Linux系统中用于快速查看文件开头内容的工具,常用于处理日志文件。基本用法包括指定查看行数(如`head -n 10 file.txt`)和与其他命令(如`grep`)结合使用。高级用法涉及动态查看日志、过滤内容、管道操作及在脚本中的应用。实际应用案例包括监控系统日志、排查错误和分析应用日志。使用时注意文件存在性、行数选择及权限问题。熟练掌握head命令能提升工作效率,结合其他工具可实现更多功能,助力Linux用户提升技能。
|
6天前
|
安全 编译器 C语言
C++:编程语言中的强大工具
C++:编程语言中的强大工具
15 0
|
6天前
工具变量法(两阶段最小二乘法2SLS)线性模型分析人均食品消费时间序列数据和回归诊断2
工具变量法(两阶段最小二乘法2SLS)线性模型分析人均食品消费时间序列数据和回归诊断
|
6天前
|
机器学习/深度学习 前端开发 数据挖掘
R语言计量经济学:工具变量法(两阶段最小二乘法2SLS)线性模型分析人均食品消费时间序列数据和回归诊断
R语言计量经济学:工具变量法(两阶段最小二乘法2SLS)线性模型分析人均食品消费时间序列数据和回归诊断
|
6天前
|
C++
glog --- C++日志库
glog --- C++日志库
|
6天前
|
存储 监控 数据可视化
linux日志分析工具与命令
在Linux中,日志分析常用命令行工具如`tail`(实时追踪日志)、`head`(显示日志开头)、`grep`(搜索关键词)、`awk`(复杂文本处理)、`sed`(文本替换)、`less`(分页查看)和`cat`(输出内容)。此外,还有日志分析工具如Logwatch(自动分析邮件摘要)、rsyslog/syslog-ng(日志收集)、Graylog(集中式管理)、ELK Stack(日志收集、解析、存储和可视化)和Splunk(企业级日志管理)。这些工具帮助管理员监控系统、排查问题、进行安全审计并获取业务洞察。
27 1
|
6天前
|
C++
C++11日志之spdlog
C++11日志之spdlog
28 1