一、log4cpp概述
????? Log4cpp是一个开源的C++类库,它提供了C++程序中使用日志和跟踪调试的功能,它的优点如下: 1.1提供应用程序运行上下文,方便跟踪调试; 1.2可扩展的、多种方式记录日志,包括命令行、文件、回卷文件、内存、syslog服务器、Win事件日志等; 1.3 可以动态控制日志记录级别,在效率和功能中进行调整; 1.4 所有配置可以通过配置文件进行动态调整; 1.5多语言支持,包括Java(log4j),C++(log4cpp、log4cplus),C(log4c),python(log4p)等;
二、原理
????? Log4cpp有三个主要的组件:日志类别(Category)、输出源(Appender)和布局(Layout)。这三种类型的组件一起工作使得系统可以根据信息的类型和级别记录它们,并且在运行时控制这些信息的输出格式和位置。 三个组件的介绍: 1)日志类别(Category)含义是:如果配置文件中设置的级别是DEBUG,则任意的log都能打印出来;但如果配置的级别是ERROR,则只有高于ERROR优先级的日志才可以打印出来。 日志的常用优先级:DEBUG < INFO < WARN < ERROR < FATAL 2)输出源(Appender)用来输出日志(被layout格式化后)到一些设备上,比如文件、命令行、内存等。也可以定义自己的appender输出日志信息到别的设备上。log4cpp提供的appender如下: FileAppender? 输出到文件 RollingFileAppender 输出到回卷文件,即当文件到达某个大小后回卷 ConsoleAppender 输出到控制台。 3)布局(Layout):显示样式PatternLayout表示让用户根据类似于C语言printf函数的转换模式来指定输出格式。 三个组件之间的关系: ??? ?Category和Appender的关系是:多个Appender可以附加到一个Category上,这样一个日志消息可以同时输出到多个设备上。 ??? ?Appender和Layout的关系是:Layout附加在Appender上,appender调用layout处理完日志消息后,记录到某个设备上。
? 三、程序例子
参考:https://blog.csdn.net/lyt_dawang/article/details/115612542 https://blog.csdn.net/tanhuifang520/article/details/107666090 支持三种位置输出console终端 file文件 syslog系统log中 下载地址:
https://sourceforge.net/projects/log4cpp/files/latest/download? ? 下载的是:log4cpp-1.1.3.tar.gz 解压: tar zxf log4cpp-1.1.3.tar.gz 编译: ?
cd log4cpp
./configure --build=arm-linux --with-pthreads //arm 多线程
make
make check
sudo make install
sudo ldconfig
3.1 程序:
// FileName: 2-test_log4cpp.cpp
#include "log4cpp/Category.hh"
#include "log4cpp/FileAppender.hh"
#include "log4cpp/BasicLayout.hh"
#include <log4cpp/PatternLayout.hh>
int main(int argc, char *argv[])
{
// 1实例化一个layout 对象
auto getLayout =[]()
{
log4cpp::PatternLayout* layout =new log4cpp::PatternLayout();
layout->setConversionPattern("%d{%d %b %Y %H:%M:%S} [%p] %c %m%n"); // 可设置自己喜欢的日志格式
return layout;
};
// log4cpp::Layout *layout = new log4cpp::BasicLayout();
// 2. 初始化一个appender 对象
log4cpp::Appender *appender = new log4cpp::FileAppender("FileAppender", "/home/nvidia/logs/test_log4cpp1.log");
// 3. 把layout对象附着在appender对象上
appender->setLayout(getLayout());
// 4. 实例化一个category对象
log4cpp::Category &warn_log =
log4cpp::Category::getInstance("darren");
// 5. 设置additivity为false,替换已有的appender
warn_log.setAdditivity(false);
// 5. 把appender对象附到category上
warn_log.setAppender(appender);
// 6. 设置category的优先级,低于此优先级的日志不被记录
warn_log.setPriority(log4cpp::Priority::WARN);
// 记录一些日志
warn_log.info("Program info which cannot be wirten");
warn_log.debug("This debug message will fail to write");
warn_log.alert("Alert info");
// 其他记录日志方式
warn_log.log(log4cpp::Priority::WARN, "This will be a logged warning");
log4cpp::Priority::PriorityLevel priority;
bool this_is_critical = true;
if (this_is_critical)
priority = log4cpp::Priority::CRIT;
else
priority = log4cpp::Priority::DEBUG;
warn_log.log(priority, "Importance depends on context");
warn_log.critStream() << "This will show up << as "
<< 1 << " critical message";
// clean up and flush all appenders
log4cpp::Category::shutdown();
return 0;
}
编译:
g++ -o 2-test_log4cpp 2-test_log4cpp.cpp -llog4cpp -lpthread
3.2 类实现
//使用的头文件
#include <iostream>
#include <string>
#include <sstream>
#include <log4cpp/Category.hh>
#include <log4cpp/Appender.hh>
#include <log4cpp/FileAppender.hh>
#include <log4cpp/OstreamAppender.hh>
#include <log4cpp/RollingFileAppender.hh>
#include <log4cpp/Layout.hh>
#include <log4cpp/PatternLayout.hh>
using namespace log4cpp;
using namespace std;
//类结构的声明
class MLog{
public:
static MLog* logCntl(const bool flag,const string& FileName,
const size_t& fileSize = 10*1024*1024,const int& RollingFileNum = 10,
const int& PRIORITY = Priority::DEBUG);
int getPriority()const;
void setpriority(int PRIORITY);
void logInfo(const string& msg)const;
void logError(const string& msg)const;
void logWarn(const string& msg)const;
void logDebug(const string& msg)const;
private:
Category& root = Category::getRoot();
MLog(const string& FileName,const int& RollingFileNum,const size_t& fileSize,const int& PRIORITY);
~MLog();
};
//成员函数和构造函数的实现
MLog::MLog(const string& FileName,const int& RollingFileNum,const size_t& fileSize,const int& PRIORITY){
//1.设置输出器
RollingFileAppender* term1 = new RollingFileAppender("term1",FileName,fileSize,
RollingFileNum,true,00644);
OstreamAppender* term2 = new OstreamAppender("term2",&cout);//终端输出
//2.设置布局器
PatternLayout* layout1 = new PatternLayout();
PatternLayout* layout2 = new PatternLayout();
layout1->setConversionPattern("%d [%p] %m %n");
layout2->setConversionPattern("%d [%p] %m %n");
//3.添加布局
term1->setLayout(layout1);
term2->setLayout(layout2);
//4.将输出器添加到记录器中
root.addAppender(term1);
root.addAppender(term2);
//5.设置优先级
root.setPriority(PRIORITY);
printf("done setting root \n");
}
MLog:: ~MLog(){
Category::shutdown();
printf("destructor\n");
}
MLog* MLog:: logCntl(const bool flag,const string& FileName,
const size_t& fileSize ,const int& RollingFileNum ,
const int& PRIORITY){
static MLog* MLogInstance = nullptr;
if(1 == flag){
if(nullptr == MLogInstance){
MLogInstance = new MLog(FileName,RollingFileNum,fileSize,PRIORITY);
printf("done creating new Mlog\n");
}else{
printf("instance Already exist\n");
}
}else{
if(MLogInstance==nullptr){
printf("intance already deleted\n");
}else{
delete MLogInstance;
}
}
return MLogInstance;
}
void MLog:: logInfo(const string& msg)const{
ostringstream strstream;
strstream << __FILE__ <<" : "<<__LINE__<<" : "<<__FUNCTION__<<" : "<<msg<<endl;
root.info(strstream.str());
/* cout << strstream.str()<<endl; */
}
void MLog:: logError(const string& msg)const{
ostringstream strstream;
strstream << __FILE__ <<" : "<<__LINE__<<" : "<<__FUNCTION__<<" : "<<msg<<endl;
root.error(strstream.str());
/* cout << strstream.str()<<endl; */
}
void MLog:: logWarn(const string& msg)const{
ostringstream strstream;
strstream << __FILE__ <<" : "<<__LINE__<<" : "<<__FUNCTION__<<" : "<<msg<<endl;
root.warn(strstream.str());
/* cout << strstream.str()<<endl; */
}
void MLog:: logDebug(const string& msg)const{
ostringstream strstream;
strstream << __FILE__ <<" : "<<__LINE__<<" : "<<__FUNCTION__<<" : "<<msg<<endl;
root.debug(strstream.str());
/* cout << strstream.str()<<endl; */
}
int MLog::getPriority()const{
return root.getPriority();
}
void MLog::setpriority(int PRIORITY){
root.setPriority(PRIORITY);
}
//测试函数
int main()
{
//1.创建日志实例
MLog* mlog = MLog::logCntl(1,"/home/nvidia/logs/test_log.log",20*1024,1,Priority::DEBUG);
//2.循环打印日志
for(int index = 0;index<1;++index){
mlog->logDebug("this is a Debug msg");
mlog->logInfo("this is an Info msg");
mlog->logError("this is an Error msg");
mlog->logWarn("this is a Warn msg");
}
//3.关闭日志实例
MLog::logCntl(0," ");
return 0;
}
结果:
?3.3 文件实现
include/mlog.h
#ifndef __MLOG_H
#define __MLOG_H
//使用的头文件
#include <iostream>
#include <string>
#include <sstream>
#include <log4cpp/Category.hh>
#include <log4cpp/Appender.hh>
#include <log4cpp/FileAppender.hh>
#include <log4cpp/OstreamAppender.hh>
#include <log4cpp/RollingFileAppender.hh>
#include <log4cpp/Layout.hh>
#include <log4cpp/PatternLayout.hh>
using namespace log4cpp;
using namespace std;
//类结构的声明
class MLog{
public:
static MLog* logCntl(const bool flag,const string& FileName,
const size_t& fileSize = 10*1024*1024,const int& RollingFileNum = 10,
const int& PRIORITY = Priority::DEBUG);
int getPriority()const;
void setpriority(int PRIORITY);
void logInfo(const string& msg)const;
void logError(const string& msg)const;
void logWarn(const string& msg)const;
void logDebug(const string& msg)const;
private:
Category& root = Category::getRoot();
MLog(const string& FileName,const int& RollingFileNum,const size_t& fileSize,const int& PRIORITY);
~MLog();
};
#endif
src/mlog.cpp
#include "mlog.h"
//成员函数和构造函数的实现
MLog::MLog(const string& FileName,const int& RollingFileNum,const size_t& fileSize,const int& PRIORITY){
//1.设置输出器
RollingFileAppender* term1 = new RollingFileAppender("term1",FileName,fileSize,
RollingFileNum,true,00644);
OstreamAppender* term2 = new OstreamAppender("term2",&cout);//终端输出
//2.设置布局器
PatternLayout* layout1 = new PatternLayout();
PatternLayout* layout2 = new PatternLayout();
layout1->setConversionPattern("%d [%p] %m %n");
layout2->setConversionPattern("%d [%p] %m %n");
//3.添加布局
term1->setLayout(layout1);
term2->setLayout(layout2);
//4.将输出器添加到记录器中
root.addAppender(term1);
root.addAppender(term2);
//5.设置优先级
root.setPriority(PRIORITY);
printf("done setting root \n");
}
MLog:: ~MLog(){
Category::shutdown();
printf("destructor\n");
}
MLog* MLog:: logCntl(const bool flag,const string& FileName,
const size_t& fileSize ,const int& RollingFileNum ,
const int& PRIORITY){
static MLog* MLogInstance = nullptr;
if(1 == flag){
if(nullptr == MLogInstance){
MLogInstance = new MLog(FileName,RollingFileNum,fileSize,PRIORITY);
printf("done creating new Mlog\n");
}else{
printf("instance Already exist\n");
}
}else{
if(MLogInstance==nullptr){
printf("intance already deleted\n");
}else{
delete MLogInstance;
}
}
return MLogInstance;
}
void MLog:: logInfo(const string& msg)const{
ostringstream strstream;
strstream << __FILE__ <<" : "<<__LINE__<<" : "<<__FUNCTION__<<" : "<<msg<<endl;
root.info(strstream.str());
/* cout << strstream.str()<<endl; */
}
void MLog:: logError(const string& msg)const{
ostringstream strstream;
strstream << __FILE__ <<" : "<<__LINE__<<" : "<<__FUNCTION__<<" : "<<msg<<endl;
root.error(strstream.str());
/* cout << strstream.str()<<endl; */
}
void MLog:: logWarn(const string& msg)const{
ostringstream strstream;
strstream << __FILE__ <<" : "<<__LINE__<<" : "<<__FUNCTION__<<" : "<<msg<<endl;
root.warn(strstream.str());
/* cout << strstream.str()<<endl; */
}
void MLog:: logDebug(const string& msg)const{
ostringstream strstream;
strstream << __FILE__ <<" : "<<__LINE__<<" : "<<__FUNCTION__<<" : "<<msg<<endl;
root.debug(strstream.str());
/* cout << strstream.str()<<endl; */
}
int MLog::getPriority()const{
return root.getPriority();
}
void MLog::setpriority(int PRIORITY){
root.setPriority(PRIORITY);
}
main.cpp
#include "mlog.h"
//测试函数
int main()
{
//1.创建日志实例
MLog* mlog = MLog::logCntl(1,"/home/nvidia/logs/test_log.log",20*1024,1,Priority::DEBUG);
//2.循环打印日志
for(int index = 0;index<1;++index){
mlog->logDebug("this is a Debug msg");
mlog->logInfo("this is an Info msg");
mlog->logError("this is an Error msg");
mlog->logWarn("this is a Warn msg");
}
//3.关闭日志实例
MLog::logCntl(0," ");
return 0;
}
CMakeLists.txt
cmake_minimum_required(VERSION 3.0.2)
project(mLog)
SET(CMAKE_CXX_FLAGS " ${CMAKE_CXX_FLAGS} -std=c++11 -pthread")
include_directories("include")
add_library(libmlog src/mlog.cpp)
add_executable(mLog main.cpp)
target_link_libraries(mLog libmlog log4cpp)
?
|