目前成熟的日志系统有很多,比如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. JAVA设计模式之工厂模式—Factory Pattern

    1.工厂模式简介 工厂模式用于对象的创建,使得客户从具体的产品对象中被解耦. 2.工厂模式分类 这里以制造coffee的例子开始工厂模式设计之旅. 我们知道coffee只是一种泛举,在点购咖啡时需要指 ...

  2. ThinkPHP模型中的HAS_ONE,BELONG_TO,HAS_MANY实践

    因为很熟悉DJANGO,所以对TP,要慢慢适应. 1,SQL文件 /* Navicat MySQL Data Transfer Source Server : localhost_3306 Sourc ...

  3. el-table 多列显示隐藏造成内容错乱

  4. IntelliJ IDEA 2019.2破解

    IntelliJ IDEA 2019.2破解 我是参考这个激活的,使用的激活码的方式,需要在百度云盘下载压缩包 https://zhile.io/2018/08/25/jetbrains-licens ...

  5. LeetCode(数据库):分数排名

    ,)); Truncate table Scores; ', '3.5'); ', '3.65'); ', '4.0'); ', '3.85'); ', '4.0'); ', '3.65'); 编写一 ...

  6. [Flutter + Firebase] Enable Firebase for Flutter

    Anroid Firebase Project setup: 1. In firebase console, cerate a Android app setup you can find in co ...

  7. C++编译器和连接器原理

    本文转载自新浪永远即等待的博客 几个概念:  1.编译:编译器对源文件进行编译,就是把源文件中的文本形式存在的源代码翻译成机器语言形式的目标文件的过程,在这个过程中,编译器会进行一系列的语法检查.如果 ...

  8. 过滤器的API

    1.API a.生命周期(和servletcontext相似): (1)创建:服务器启动的时候创建(执行init方法). (2)销毁:服务器关闭的时候销毁(执行destory方法). b.filter ...

  9. ssh:no matching host key type found. Their offer: ssh-dss

    最近突然ssh 服务连接出现 no matching host key type found. Their offer: ssh-dss 以前一直没有问题 可能的原因 openssh 服务升级,加密算 ...

  10. Ubuntu下设置 nginx php-fpm 自动启动 rc.local

    编辑 root@ubuntu:/usr/sbin# vim /etc/init.d/rc.local /usr/sbin/php-fpm /usr/sbin/nginx 保存!