一起学习log4cxx
目前成熟的日志系统有很多,比如log4cxx,log4cpp等,今天一起来学习log4cxx吧,之所以学习这个,首先,这个日志库比较成熟,一直由apach基金在维护,而log4cpp缺乏维护.再者,这个库的性能相对高一些,大约为10w行/s.
log4cxx依赖于apach的另外两个开源库apr和apr-util.
准备工作:
首先下载 apr-1.7.0.tar.gz, apr-util-1.6.1.tar.gz和log4cxx库
提取码: 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的更多相关文章
- ROS入门学习
ROS学习笔记 ROS入门网站; ROS入门书籍 ROS主要包含包括功能包.节点.话题.消息类型和服务; ROS功能包/软件包(Packages) ROS软件包是一组用于实现特定功能的相关文件的集合, ...
- 从直播编程到直播教育:LiveEdu.tv开启多元化的在线学习直播时代
2015年9月,一个叫Livecoding.tv的网站在互联网上引起了编程界的注意.缘于Pingwest品玩的一位编辑在上网时无意中发现了这个网站,并写了一篇文章<一个比直播睡觉更奇怪的网站:直 ...
- Angular2学习笔记(1)
Angular2学习笔记(1) 1. 写在前面 之前基于Electron写过一个Markdown编辑器.就其功能而言,主要功能已经实现,一些小的不影响使用的功能由于时间关系还没有完成:但就代码而言,之 ...
- ABP入门系列(1)——学习Abp框架之实操演练
作为.Net工地搬砖长工一名,一直致力于挖坑(Bug)填坑(Debug),但技术却不见长进.也曾热情于新技术的学习,憧憬过成为技术大拿.从前端到后端,从bootstrap到javascript,从py ...
- 消息队列——RabbitMQ学习笔记
消息队列--RabbitMQ学习笔记 1. 写在前面 昨天简单学习了一个消息队列项目--RabbitMQ,今天趁热打铁,将学到的东西记录下来. 学习的资料主要是官网给出的6个基本的消息发送/接收模型, ...
- js学习笔记:webpack基础入门(一)
之前听说过webpack,今天想正式的接触一下,先跟着webpack的官方用户指南走: 在这里有: 如何安装webpack 如何使用webpack 如何使用loader 如何使用webpack的开发者 ...
- Unity3d学习 制作地形
这周学习了如何在unity中制作地形,就是在一个Terrain的对象上盖几座小山,在山底种几棵树,那就讲一下如何完成上述内容. 1.在新键得项目的游戏的Hierarchy目录中新键一个Terrain对 ...
- 《Django By Example》第四章 中文 翻译 (个人学习,渣翻)
书籍出处:https://www.packtpub.com/web-development/django-example 原作者:Antonio Melé (译者注:祝大家新年快乐,这次带来<D ...
- 菜鸟Python学习笔记第一天:关于一些函数库的使用
2017年1月3日 星期二 大一学习一门新的计算机语言真的很难,有时候连函数拼写出错查错都能查半天,没办法,谁让我英语太渣. 关于计算机语言的学习我想还是从C语言学习开始为好,Python有很多语言的 ...
随机推荐
- python基础---python环境搭建windows版
Python3.7.1标准安装 1.官网下载 官网地址:https://www.python.org/downloads/ 下载3.7.1 下载64/32bitwindows安装文件,下图x86-64 ...
- RippleNet: Propagating User Preferences on the Knowledge Graph for Recommender Systems
一.摘要 为了解决协同过滤的稀疏性和冷启动问题,社交网络或项目属性等辅助信息被用来提高推荐性能. 考虑到知识图谱是边信息的来源,为了解决现有的基于嵌入和基于路径的知识图谱感知重构方法的局限性,本文提出 ...
- 项目Alpha冲刺——总结
作业描述 课程: 软件工程1916|W(福州大学) 作业要求: 项目Alpha冲刺(团队) 团队名称: 火鸡堂 作业目标: 完成项目Alpha冲刺 团队信息 队名:火鸡堂 队员学号 队员姓名 博客地址 ...
- 20199301《Linux内核原理与分析》第十一周作业
Linux Capability探索实验 一.实验描述 本实验中,将感受到linux capability功能在访问控制上的优势,掌握使用Capability达到遵守最小权限原则的目的,并分析linu ...
- postgres高可用学习篇二:通过pgbouncer连接池工具来管理postgres连接
安装pgbouncer yum install libevent -y yum install libevent-devel -y wget http://www.pgbouncer.org/down ...
- python - django 控制台输出 sql 语句
只需要在 settings.py 文件中加入以下配置即可. LOGGING = { 'version': 1, 'disable_existing_loggers': False, 'handlers ...
- Oracle 分区默认segment大小变化(64k—>8M)
原文链接:http://www.cnblogs.com/wcwen1990/p/6656545.html _partition_large_extents和_index_partition_large ...
- 检查cgroup v2 是否安装
cgroup 当前包含了v1, 以及v2 版本,v2 版本相比v1 在目录组织上更加清晰,管理更加方便,很多 时候我们可能需要检查我们安装的内核当前内核版本是否支持cgroup v2 文章内容来自 h ...
- Tomcat启动服务报错:Unknown version string [4.0]. Default version will be used.
Tomcat.jdk.web.xml 对应关系: 版本对应错误,更换便可.(版本往下兼容) web.xml——version2.2——JDK1.1——Tomcat3.3 web.xml——versio ...
- PDO和MySQLi区别和数度;到底用哪个?
当用PHP访问数据库时,除了PHP自带的数据库驱动,我们一般还有两种比较好的选择:PDO和MySQLi.在实际开发过程中要决定选择哪一种首先要对二者有一个比较全面的了解.本文就针对他们的不同点进行分析 ...