目前成熟的日志系统有很多,比如log4cxx,log4cpp等,今天一起来学习log4cxx吧,之所以学习这个,首先,这个日志库比较成熟,一直由apach基金在维护,而log4cpp缺乏维护.再者,这个库的性能相对高一些,大约为10w行/s.

log4cxx依赖于apach的另外两个开源库apr和apr-util.

准备工作:

首先下载 apr-1.7.0.tar.gz, apr-util-1.6.1.tar.gzlog4cxx库

百度网盘

提取码: kzwc

1. 安装依赖库apr和apr-util

#首先解压压缩包
$ tar -zxvf apr-1.7..tar.gz
$ cd apr-1.7. $ ./configure --prefix=/usr/local
$ make
$ sudo make install
#首先解压压缩包
$ tar -zxvf apr-util-1.6..tar.gz
$ cd apr-util-1.6. $ ./configure --prefix=/usr/local --with-apr=/usr/local
$ make
$ sudo make install

2.安装log4cxx

tar -zxvf apache-log4cxx-0.10..tar.gz
cd apache-log4cxx-0.10.
./configuer --prefix=/usr/local/ --with-apr=/usr/local/ --with-apr-util=/usr/local/ --with-charset=utf- --with-logchar=utf-
make
sudo make install

安装log4cxx可能会报错:

解决办法:

1 inputstreamreader.cpp:66: error: 'memmove' was not declared in this scope
2 make[3]: *** [inputstreamreader.lo] 错误 1
#这是由于以下几个文件缺少了标准库文件,添加上就可以了
3 src/main/cpp/inputstreamreader.cpp添加#include <string.h>
4 src/main/cpp/socketoutputstream.cpp添加#include <string.h>
5 src/examples/cpp/console.cpp添加#include <string.h>;#include <stdio.h>; 3. 封装log4cxx日志库
/*!
* Email: scictor@gmail.com
* Auth: scictor
* Date: 2019-9-8
* File: zlog4cxx.h
* Class: zlog4cxx (if applicable)
* Brief:
* Note:
*/ #ifndef ZLOG4CXX_H
#define ZLOG4CXX_H #include <log4cxx/logger.h>
#include <log4cxx/logstring.h>
#include <log4cxx/propertyconfigurator.h>
#include<string>
#include <stdio.h>
#include <stdlib.h>
#include <string.h> using namespace log4cxx;
using namespace log4cxx::helpers;
#include <stdarg.h>
using namespace std;
#define SAFE_DELETE_ARRAY(v_para)\
do \
{\
if (NULL != v_para) {\
delete[] v_para;\
v_para = NULL;\
}\
} while ()
//TRACE < DEBUG < INFO < WARN < ERROR < FATAL
typedef enum _LOG_LEVEL
{
LOG_TRACE_ = ,
LOG_DEBUG_,
LOG_INFO_,
LOG_WARN_,
LOG_ERROR_,
LOG_FATAL_
}LOG_LEVEL;
#ifndef IN
#define IN
#endif
#ifndef OUT
#define OUT
#endif
/*
写日志函数
IN const char* module,//在log4cxx.properties文件中设置了很多个append,这个参数用来设置模块,例如本实例中的fa
IN const LOG_LEVEL level,日志级别 ERROR、INFO等
IN const char* file,打印日志函数调用的文件
IN const char* function, 打印日志的函数
IN const int line, 打印日志的行号
IN const char* format,//打印日志的格式 如: "%s%d%f"
... //可变参数输入
*/
void log4cxx_package(IN const char* module,IN const LOG_LEVEL level, IN const char* file, IN const char* function,
IN const int line, IN const char* format, ...);//
//宏定义封装,__FILE__, __FUNCTION__, __LINE__ 分别是打印日志的文件名、函数名,行号
#define LOG(module,level, format,...) log4cxx_package(module,level, __FILE__, __FUNCTION__, __LINE__, format,__VA_ARGS__)
//按照不同的级别定义宏
#define FIRE_ERROR(format,...) LOG("fa",LOG_ERROR_, format,__VA_ARGS__)
#define FIRE_INFO(format,...) LOG("fa",LOG_INFO_, format,__VA_ARGS__)
#define FIRE_TRACE(format,...) LOG("fa",LOG_TRACE_, format,__VA_ARGS__)
#define FIRE_DEBUG(format,...) LOG("fa",LOG_DEBUG_, format,__VA_ARGS__)
#define FIRE_WARN(format,...) LOG("fa",LOG_WARN_, format,__VA_ARGS__)
#define FIRE_FATAL(format,...) LOG("fa",LOG_FATAL_, format,__VA_ARGS__) //
//初始化日志库,传入log4cxx.properties文件的名称
void log4cxx_init(IN const char* conffile);
//根据append或者模块名称来获取模块的日志指针。如果是root模块,直接用Logger::getRootLogger();获取
LoggerPtr get_logger_ptr(IN const char* user); #endif // ZLOG4CXX_H
源文件
/*!
* Email: scictor@gmail.com
* Auth: scictor
* Date: 2019-9-8
* File: zlog4cxx.cpp
* Class: zlog4cxx (if applicable)
* Brief:
* Note:
*/
#include "zlog4cxx.h" static std::string ensure_log_complete(IN const char* format,IN va_list args)
{
if (NULL == format)
{
return "";
} int iNum = ;
unsigned int uiSize = ;
string strLog(""); char *pcBuff = new(std::nothrow) char[uiSize];
if (NULL == pcBuff)
{
return strLog;
} while(true)
{
memset(pcBuff, ,uiSize); iNum = vsnprintf(pcBuff, uiSize, format, args);
if ((iNum > -) && (iNum < (int)uiSize))
{
strLog = pcBuff;
SAFE_DELETE_ARRAY(pcBuff); return strLog;
} //如果字符串值比默认分配大,则分配更大空间
uiSize = (iNum > -)?(int)(iNum + ):(uiSize * );
SAFE_DELETE_ARRAY(pcBuff); pcBuff = new(std::nothrow) char[uiSize];
if (NULL == pcBuff)
{
return strLog;
}
} SAFE_DELETE_ARRAY(pcBuff); return strLog;
}
/*
写日志函数
IN const char* module,//在log4cxx.properties文件中设置了很多个append,这个参数用来设置模块,例如本实例中的fa
IN const LOG_LEVEL level,日志级别 ERROR、INFO等
IN const char* file,打印日志函数调用的文件
IN const char* function, 打印日志的函数
IN const int line, 打印日志的行号
IN const char* format,//打印日志的格式 如: "%s%d%f"
... //可变参数输入
*/
void log4cxx_package(IN const char* module,IN const LOG_LEVEL level, IN const char* file, IN const char* function,
IN const int line, IN const char* format, ...)
{
if (level > LOG_FATAL_ || level < LOG_TRACE_)
{
return;
} if (NULL == file || NULL == function || NULL == format)
{
return;
} LoggerPtr pLogger=nullptr;
if (module!=NULL)
{
pLogger=get_logger_ptr(module);
}
if(pLogger==NULL)
{
pLogger= Logger::getRootLogger();
} char acTmp[] = { };
sprintf(acTmp,"%d",line); va_list args;
std::string strLog;
strLog = "[" + std::string(file) + ":" + std::string(function) + "(" + std::string(acTmp) + ")] "; va_start(args, format);
strLog += ensure_log_complete(format, args);
va_end(args); switch (level)
{
case LOG_TRACE_:
LOG4CXX_TRACE(pLogger, strLog.c_str());
break;
case LOG_DEBUG_:
LOG4CXX_DEBUG(pLogger, strLog.c_str());
break;
case LOG_INFO_:
LOG4CXX_INFO(pLogger, strLog.c_str());
break;
case LOG_WARN_:
LOG4CXX_WARN(pLogger, strLog.c_str());
break;
case LOG_ERROR_: LOG4CXX_ERROR(pLogger, strLog.c_str());
break;
case LOG_FATAL_:
LOG4CXX_FATAL(pLogger, strLog.c_str());
break;
default:
break;
} return;
} void log4cxx_init(IN const char* conffile)//初始化日志库
{
// 读取配置文件
using namespace log4cxx;
PropertyConfigurator::configure(File(conffile));
return ;
} LoggerPtr get_logger_ptr(IN const char* user)//获取日志模块指针
{
// 建立logger
return Logger::getLogger(user);
}

4. 测试

/*!
* Email: scictor@gmail.com
* Auth: scictor
* Date: 2019-9-8
* File: %{Cpp:License:FileName}
* Class: %{Cpp:License:ClassName} (if applicable)
* Brief:
* Note:
*/
#include <bits/stdc++.h>
#include "zlog4cxx.h"
using namespace std; int main(int argc,char **argv){
log4cxx_init("log4cxx.properties");
char *pStr = "YES";
FIRE_INFO("that is ok? %s", pStr);
printf("hello world!\n");
return ;
}

编译:

g++ zlog4cxx.cpp main.cpp -o xlog -llog4cxx

结果输出

 
												

一起学习log4cxx的更多相关文章

  1. ROS入门学习

    ROS学习笔记 ROS入门网站; ROS入门书籍 ROS主要包含包括功能包.节点.话题.消息类型和服务; ROS功能包/软件包(Packages) ROS软件包是一组用于实现特定功能的相关文件的集合, ...

  2. 从直播编程到直播教育:LiveEdu.tv开启多元化的在线学习直播时代

    2015年9月,一个叫Livecoding.tv的网站在互联网上引起了编程界的注意.缘于Pingwest品玩的一位编辑在上网时无意中发现了这个网站,并写了一篇文章<一个比直播睡觉更奇怪的网站:直 ...

  3. Angular2学习笔记(1)

    Angular2学习笔记(1) 1. 写在前面 之前基于Electron写过一个Markdown编辑器.就其功能而言,主要功能已经实现,一些小的不影响使用的功能由于时间关系还没有完成:但就代码而言,之 ...

  4. ABP入门系列(1)——学习Abp框架之实操演练

    作为.Net工地搬砖长工一名,一直致力于挖坑(Bug)填坑(Debug),但技术却不见长进.也曾热情于新技术的学习,憧憬过成为技术大拿.从前端到后端,从bootstrap到javascript,从py ...

  5. 消息队列——RabbitMQ学习笔记

    消息队列--RabbitMQ学习笔记 1. 写在前面 昨天简单学习了一个消息队列项目--RabbitMQ,今天趁热打铁,将学到的东西记录下来. 学习的资料主要是官网给出的6个基本的消息发送/接收模型, ...

  6. js学习笔记:webpack基础入门(一)

    之前听说过webpack,今天想正式的接触一下,先跟着webpack的官方用户指南走: 在这里有: 如何安装webpack 如何使用webpack 如何使用loader 如何使用webpack的开发者 ...

  7. Unity3d学习 制作地形

    这周学习了如何在unity中制作地形,就是在一个Terrain的对象上盖几座小山,在山底种几棵树,那就讲一下如何完成上述内容. 1.在新键得项目的游戏的Hierarchy目录中新键一个Terrain对 ...

  8. 《Django By Example》第四章 中文 翻译 (个人学习,渣翻)

    书籍出处:https://www.packtpub.com/web-development/django-example 原作者:Antonio Melé (译者注:祝大家新年快乐,这次带来<D ...

  9. 菜鸟Python学习笔记第一天:关于一些函数库的使用

    2017年1月3日 星期二 大一学习一门新的计算机语言真的很难,有时候连函数拼写出错查错都能查半天,没办法,谁让我英语太渣. 关于计算机语言的学习我想还是从C语言学习开始为好,Python有很多语言的 ...

随机推荐

  1. NGINX状态模块的使用

    nginx状态模块可以用来查看当前nginx服务器的并发量和总的请求数 启用nginx的状态模块 状态模块需要在编译安装的时候启用. 1.下载nginx源码包 2.安装nginx并启用模块 3.修改n ...

  2. 二级数组省市表(二维数组json)

    <一省份.城市二级联动+vue搭架> a. template部分 <section class="edit__place"> <select v-mo ...

  3. 【Django2.0】python manage.py makemigrations 和 python manage.py migrate的区别

    无论当我们第一次在models.py中创建类对象还是对类中的属性进行修改,我们都会使用python manage.py makemigrations 和 python manage.py migrat ...

  4. C++——STL(算法)

    以下对所有算法进行细致分类并标明功能:<一>查找算法(13个):判断容器中是否包含某个值adjacent_find:   在iterator对标识元素范围内,查找一对相邻重复元素,找到则返 ...

  5. Kotlin字节码生成机制详尽分析

    通过注解修改Kotlin的class文件名: 对于Kotlin文件在编译之后生成的class文件名默认是有一定规则的,比如: 而其实这个生成字节码的文件名称是可以被改的,之前https://www.c ...

  6. Vue 路由守卫解决页面退出和弹窗的显示冲突

    在使用UI框架提供的弹出层Popup时,如Vant UI的popup,在弹出层显示时,点击物理按键或者小程序自带的返回时,会直接退出页面,这明显不符合页面逻辑. 解决思路: 在弹出层显示时,点击了返回 ...

  7. Python2.7 报错:UnicodeEncodeError: 'ascii' codec can't encode characters in position 3-4: ordinal not in range(128)

    一. 错误原因(网上找的是这样说的,具体的我也不是很了解2.7版本的编码问题): 1.python默认使用ASCII处理字符流. 2.Unicode编码与ASCII编码的不兼容,Python脚本文件是 ...

  8. centos7.2(二)搭建lamp(Apache+PHP+Mysql环境)教程

    开始安装前,看说明. 说明0  查看服务器是否能被ssh登陆 http://tool.chinaz.com/port/ 如果显示关闭,说明被大陆封闭了,删除服务器重新建立一个. 说明1:Centos7 ...

  9. yolov1详细讲解

    前言 当我们谈起计算机视觉时,首先想到的就是图像分类,没错,图像分类是计算机视觉最基本的任务之一,但是在图像分类的基础上,还有更复杂和有意思的任务,如目标检测,物体定位,图像分割等,见图1所示.其中目 ...

  10. LOJ P10012 Best Cow Fences 题解

    每日一题 day48 打卡 Analysis 二分答案,判断序列的平均值是否大于等于mid 具体怎么实现呢? 将序列减去mid,再用前缀和来维护平均值就好了 #include<iostream& ...