百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 技术资源 > 正文

开源框架log4cpp实战 pig开源框架

lipiwang 2024-10-27 13:32 7 浏览 0 评论

1.Log4cpp使?

Log4cpp中主要包含Category(种类),Appender(附加器),Layout(布局),Priorty(优先级),NDC(嵌套的诊断上下?)。

Category、Appender与Layout三者的关系如下图:


2.安装

官网地址:https://sourceforge.net/projects/log4cpp/files/latest/downloa

解压:

tar zxf log4cpp-1.1.3.tar.gz

编译:

cd log4cpp

./configure

make

make check

sudo make install

sudo ldconfig

默认安装路径:

头?件:/usr/local/include/log4cpp

库?件:/usr/local/lib/liblog4cpp

测试范例

使?log4cpp的基本步骤如下:

1.实例化一个layout对象

2.初始化一个appender对象

3.把layout对象附着在appender对象

4.调用log4cpp::Category::getInstance("name")。实例化一个category对象;

5.把appender对象附加到category上,根据additivity的值取代其它appender或附加在其它appender后。

6.设置category的优先级

简单来说,上面存在这样一种关系:

layout-->appender-->category

#include "log4cpp/Category.hh"
#include "log4cpp/FileAppender.hh"
#include "log4cpp/BasicLayout.h

int main(int argc,char *argv[])
{
	// 1实例化?个layout 对象
  log4cpp::Layout *layout = new log4cpp::BasicLayout();
  //2. 初始化?个appender 对象
log4cpp::Appender *appender = new log4cpp::FileAppender("FileAppender", "./test_log4cpp1.log");
  // 3. 把layout对象附着在appender对象上
  appender->setLayout(layout);
  //4. 实例化?个category对象
  log4cpp::Category  &warn_log = log4cpp::Category::getInstance("qaa");
  //5. 设置additivity为false,替换已有的appender
  warn_log.setAdditivity(false);
  //6 把appender对象附到category上
  warn_log.setAppender(appender);
  //设置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 war
ning");
   
   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 test_log4cpp1 test_log4cpp1.cpp -llog4cpp -lpthread


配置?件使用步骤

基本步骤:

1.读取解析配置文件。

2.实例化category对象。

3.正常使用这些category对象进行日志处理。

# ?件名: test_log4cpp2.conf
# a simple test config
#定义了3个category sub1, sub2, sub1.sub2
log4j.rootCategory=DEBUG, rootAppender
log4j.category.sub1=A1
log4j.category.sub2=INFO
log4j.category.sub1.sub2=ERROR, A2
# 设置sub1.sub2 的additivity属性
log4j.additivity.sub1.sub2=false
#定义rootAppender类型和layout属性
log4j.appender.rootAppender=org.apache.log4j.ConsoleAppender
log4j.appender.rootAppender.layout=org.apache.log4j.BasicLayout
#定义A1的属性
log4j.appender.A1=org.apache.log4j.FileAppender
log4j.appender.A1.fileName=A1.log
log4j.appender.A1.layout=org.apache.log4j.SimpleLayout
#定义A2的属性
log4j.appender.A2=org.apache.log4j.ConsoleAppender
log4j.appender.A2.layout=org.apache.log4j.PatternLayout
#log4j.appender.A2.layout.ConversionPattern=The message '%m' at time%d%n
log4j.appender.A2.layout.ConversionPattern=%d %m %n
// FileName: test_log4cpp2.cpp
 // Test log4cpp by config file.
 #include "log4cpp/Category.hh"
 #include "log4cpp/PropertyConfigurator.hh"

 int main(int argc, char *argv[])
 {
 	   //1 读取解析配置?件
       // 读取出错, 完全可以忽略,可以定义?个缺省策略或者使?系统缺省策略
   // BasicLayout输出所有优先级?志到ConsoleAppender
   try{
   			log4cpp::PropertyConfigurator::configure(("./test_log4cpp2.conf");
   }catch(log4cpp::ConfigureFailure&  f){
        std::cout << "Configure Problem " <<f.what()<<std::endl;
        return -1;
        }
   
   // 2 实例化category对象
   // 这些对象即使配置?件没有定义也可以使?,不过其属性继承其?category
// 通常使?引?可能不太?便,可以使?指针,以后做指针使?
   // log4cpp::Category* root = &log4cpp::Category::getRoot();
   log4cpp::Category&  root = log4cpp::Category::getRoot() ;
   log4cpp::Category& sub1  = log4cpp::Category::getInstance(std::string("sub1"));
  log4cpp::Category& sub3 = log4cpp::Category::getInstance(std::string("sub1.sub2"));
   
   // 3 正常使?这些category对象进??志处理。
   // sub1 has appender A1 and rootappender.
   sub1.info("This is some info");
   sub1.alert("A warning");
   
   // sub3 only have A2 appender.
   sub3.debug("This debug message will fail to write");
  sub3.alert("All hands abandon ship");
   sub3.critStream() << "This will show up << as " << 1 << " critical message";
  sub3 << log4cpp::Priority::ERROR
              << "And this will be an error";
sub3.log(log4cpp::Priority::WARN, "This will be a logged warning");
   
   return 0;
 }

编译:g++ -o test_log4cpp2 test_log4cpp2.cpp -llog4cpp -lpthread

Category类

这个是归类的意思,具有树型结构,将日志按"区域"划分。Log4cpp有且只?个根Category,可以有多个子Category组成树型结构。Category具有Priority、additivity属性与若干方法。下面列出所有的属性与常用方法。

属性:Name

Category的名称。不可重复。

相关?法

virtual const std::string& getName() const throw();

属性:Priority

?志的优先级

对于根Category,必须指定Priority。(priority < Priority::NOTSET)

对于?根Category,可以不指定Priority,此时优先级继承??Category。

对于?根Category,也可以指定Priority,此时优先级覆盖?Category的优先级。

//设置当前Category的优先级
virtual void setPriority(Priority::Value priority);
//获取当前对象的优先级
virtual Priority::Value getPriority() const throw();
// 设置root Category的优先级
static void setRootPriority(Priority::Value priority);
// 获取root Category的优先级
static Priority::Value getRootPriority() throw();
//获取当前category继承表中的优先级,如果当前的优先值没有设置的话,则找他的父亲。
//如果父亲没有找到的话,他会继续向上找,因为root Category的优先值默认为Priority::INFO
//所以肯定能找到

virtual Priority::Value getChainedPriority()  const throw();
// 返回当前拥有priority优先级
virtual bool isPriorityEnabled(Priority::Value priority) const throw();

属性:additivity

每个Category都有一个additivity属性,该属性默认值为true。

如果值为true,则该Category的Appender包含了父Category的Appender。

如果值为false,则该Category的Appender取代了父Category的Appender。

相关?法

virtual void setAdditivity(bool additivity);

virtual bool getAdditivity() const throw();

属性:parent

上级Category。根Category的parent为空。

相关?法

virtual Category* getParent() throw();

virtual const Category* getParent() const throw();

?法:getRoot

静态?法。取得根Category。

static Category& getRoot();

?法:getInstance

静态?法。取得指定名称(参数name)的Category,如果不存在,则?动创建?个以name命名,parent为rootCategory,Priority为INFO的Category(说?了就是?个???法,不要和单例模式混了)。

static Category& getInstance(const std::string& name);

?法:exists

静态?法。判断是否存在指定名称(参数name)的Category。如果存在,则返回相应的Category(指针),否则返回空指针。

static Category* exists(const std::string& name);

?法:shutdownForced

静态?法。从所有的Category中移除所有的Appender,并且删除所有的Appender。(shutdown?法只是不使用Appender,并没有彻底从内存中销毁Appender)。

static void shutdownForced();

?法:Appender相关

//添加?个Appender到Category中。
// 该?法将把Appender的所有权交给Category管理
virtual void addAppender(Appender* appender);
// 添加?个Appender到Category中。
// 但是该?法并不把Appender的所有权交给Category管理
virtual void addAppender(Appender& appender);
// 获取指定名字的Appender(指针)。如果不存在则返回空指针
virtual Appender* getAppender(const std::string& name) const;
// 获取所有的Appender,以指针的?式存储在set中
virtual AppenderSet getAllAppenders() const;
// 删除所有的Appender
virtual void removeAllAppenders();
// 删除指定的Appender
virtual void removeAppender(Appender* appender);
// 判断指定Appender是否被当前Category拥有所有权。如果是的话,在删除该Appender时,将同时销毁它。
virtual bool ownsAppender(Appender* appender) const throw();

使?virtual void addAppender(Appender* appender);?法时,Category会接管appender的所有权,并确保会在合适的时机销毁它,所以不要再在外?调?delete?法去销毁它。所以不要轻易删除。

如下面代码:

log4cpp::Appender*appender = new log4cpp::OstreamAppender("default", &std::cout);
root.addAppender(appender);
delete appender; // Error! Don't delete it

?法:?志相关

Category的?志输出?式有两种,?种是简单的传递std::string类型的字符串,?种是采?类似c api中的printf,可以格式化?成字符串。

// 以指定的优先级?成?志
virtual void log(Priority::Value priority,const std::string& message) throw();
//以指定的优先级与格式化?成?志,类似c api中的printf?法
virtual void log(Priority::Value priority, const char* stringFormat,...) throw();
// 格式化?成?志的?种变体,直接传递va_list参数
virtual void logva(Priority::Value priority, const char* stringFormat,va_list va) throw();
//除了以上三种通??志三种?法外,Log4cpp还指供了多种预定义Priority的?法,如:
void debug(const char* stringFormat, ...) throw();
void info(const char* stringFormat, ...) throw();
.....

例?:

log4cpp::Category& rootCategory = log4cpp::Category::getRoot();

rootCategory.error("This is error message\n");

rootCategory.log(log4cpp::Priority::DEBUG, "This is %d message\n", 8);

?法: CategoryStream

每个CategoryStream对象封装?种优先级的?志输出,并提供了对“<<”符号的重载函数。CategoryStream对象内部借由std::ostringstream来实现流式格式化输出?成?志消息(std::string)。

// 获取(?成)指定优先级的CategoryStream
virtual CategoryStream getStream(Priority::Value priority);
// 对运算符“<<”的重载。也是获取(?成)指定优先级的CategoryStream
virtual CategoryStream operator<<(Priority::Value priority);
// 快捷?法。还有infoStram()等预定义优先级的快捷?法。
inline CategoryStream debugStream();
.....

CategoryStream只是作为临时对象,总在对象销毁时才会正真将日志输出(flush)。可以强制调用CategoryStream的flush方法,这样会不利于阅读,日志代码应该跟实际业务无关,代码行尽可能少,随时可以屏蔽日志功能。

例?:

log4cpp::Category& root = log4cpp::Category::getRoot();

root << log4cpp::Priority::ERROR << "This is error message";

root.debugStream() << "This is " << 8 << " message";

Appender类

Appender负责把日志写入相应设备,如控制台,文件,调试器,windows日志,syslog等。


比如下面输出到文件系统中。

FileAppender

作?:输出到?件系统。

构造函数:

FileAppender(const std::string& name, const std::string& fileName,bool append = true, mode_t mode = 00644);


DailyRollingFileAppender

功能:

一种特例化的FileApppender,?件系统以天为单位进?管理,当?成?志时的?期发?变化时,将会?成新的?志?件。

构造函数:

DailyRollingFileAppender(const std::string& name,const std::string& fileName,unsigned int maxDaysToKeep = maxDaysToKeepDefault,bool append = true,mode_t mode = 00644);


OstreamAppender

作用:输出到指定流,需要指定std:ostream对象,可以是std::cout或std::cerr或其它派生自std::ostream的流对象。

构造函数:OstreamAppender(const std::string& name, std::ostream* stream);


例子:

log4cpp::OstreamAppender * osAppender = new log4cpp::OstreamAppender("osAppender",&std::cout);

RemoteSyslogAppender

作?:输出到远程syslog系统。

构造函数:

RemoteSyslogAppender(const std::string& name,

const std::string& syslogName,

const std::string& relayer,

int facility = LOG_USER,

int portNumber = 514);

相关参数:


SmptAppender

作?:通过smtp协议发送到指定邮箱。

构造函数:

SmptAppender(const std::string& name, const std::string& host, const std::string& from,const std::string& to, const std::string& subject);

相关参数:



StringQueueAppender

作?:输出到内存/字符串队列。

构造函数:StringQueueAppender(const std::string& name);

相关参数:


SyslogAppender

作?:输出到本地syslog系统。

相关参数:

SyslogAppender(const std::string& name, const std::string& syslogName,int facility = LOG_USER);


BufferingAppender

作?:输出到缓存队列

Win32DebugAppender

作?:输出到Windows缺省调试器。


IdsaAppender

作?:输出到Idsa服务。


NTEventLogAppender

输出到Windows?志系统


Layout类

Layout控制输出?志的显示样式。Log4cpp内置了4种Layout。

PassThroughLayout

没有布局的“布局”,你让它写什么它就写什么,它不会为你添加任何东?,连换?符都懒得为你加。

SimpleLayout

简单布局。只有简单优先级输出,相当于PatternLayout格式化为:“%p: %m%n”。

BasicLayout

基本布局。添加“时间”、“优先级”、“种类”、“NDC”。相当于PatternLayout格式化“%R %p %c %x: %m%n”

PatternLayout

格式化布局。它的使??式类似C语?中的printf,使?格式化它符串来描述输出格式。?前?持的转义定义如下:

%% - 转义字符'%'

%c - Category

%d - ?期,如%d{%H:%M:%S,%l}。?期的格式符号与ANSI C函数strftime中的?致。但增加了?个格式符号%l,表示毫秒,占三个?进制位。

%m - 消息

%n - 换?符;会根据平台的不同?不同,但对?户透明。

%p - 优先级

%r - ?从layout被创建后的毫秒数

%R - 从1970年1?1?开始到?前为?的秒数

%u - 进程开始到?前为?的时钟周期数

%x - NDC

%t - 线程id

Priority优先级

?志的优先级。Log4cpp内置了10种优先级。

typedef enum {
EMERG = 0,
FATAL = 0,
ALERT = 100,
CRIT = 200,
ERROR = 300,
WARN = 400,
NOTICE = 500,
INFO = 600,
DEBUG = 700,
NOTSET = 800
} PriorityLevel;

取值越?,优先级越?。如?个Category的优先级为INFO(600),则包括EMEGR、FATAL、ALERT、CRIT、ERROR、WARN、INFO等?于或等于600的?志都会被输出,?DEBUG等?于600的?志则不会被输出。

注意:优先级是?个整数,不?定要只取上?的预定义值,?如说101也是可以。对于根Category,优先级不能?于或等于NOTSET(800)。

NDC

NDC是以线程为基础的,每个线程拥有且只有?个NDC。NDC的?个常??法是push、pop、get、clear。

Push:把?个字符串压?NDC栈。

Pop:从NDC栈中退出上?次压?的字符串。

Get:取得当前NDC栈中的字符串,每次压?的字符串?空格隔开。

Clear:清空NDC栈中的字符串。

NDC?法可以在每个函数??处调?NDC::push(__FUNCTION__); 在函数出?处调?NDC::pop(); 在PatternLayout中指定%x参数。这样就可以在?志中清晰的知道函数的调?情况。

这篇文章就分析到这里,欢迎关注,转发,点赞,收藏

相关推荐

《每日电讯报》研发数字工具,教你更有效率地报道新闻

为鼓励新闻编辑部持续创新,《每日电讯报》正在尝试有战略地研发数字工具。网站的数字媒体主任马尔科姆o科尔斯(MalcolmColes)表示,《每日电讯报》正试图去“创建一些可持续资产”,以便于让记者们...

html5学得好不好,看掌握多少标签

html5你了解了多少?如果你还是入门阶段的话,或者还是一知半解的话,那么我们专门为你们收集的html5常用的标签大全对你就很有帮助了,你需要了解了html5有哪些标签你才能够更好的。驾驭html5...

前端分享-少年了解过iframe么(我想了解少年)

iframe就像是HTML的「内嵌画布」,允许在页面中加载独立网页,如同在画布上叠加另一幅动态画卷。核心特性包括:独立上下文:每个iframe都拥有独立的DOM/CSS/JS环境(类似浏...

做SEO要知道什么是AJAX(人能看到但搜索引擎看不到的内容)

一个明显的,人能看到但搜索引擎不能看到的内容是AJAX。那么什么是AJAX呢?其实,了解过的基本上也都清楚,AJAX不是新的编程语言,而是一种使用现有标准的新方法。AJAX最大的优点是在不重新加...

介绍最前沿的人工智能创新,‘无反向传播’神经网络训练方法?

图像由GoogleImageFX生成前言:本文整理自NoProp原始论文与实践代码,并结合多个公开实现细节进行了全流程复现。对神经网络训练机制的探索仍在不断演进,如果你也在研究反向传播之...

说说我们对HTML6的期许(对html的看法)

HTML5概述HTML5是HTML语言最受欢迎的版本之一,它支持音频和视频、离线存储、移动端、和标签属性等等。还提供了article,section,header这样的标签来帮助开发者更好...

浏览器中在线预览pdf文件,pdf.mjs插件实现web预览pdf

背景:本来只是淘宝上卖卖袜子,想着扩展一下业务,准备做同名“来家居”海外袜子馆外贸项目,碰到pdf在线预览的需求,就找了pdf.js插件进行实践后把此方法记录下来,可以通过多种方法来实现,每种方法都有...

SVG 在前端的7种使用方法,你还知道哪几种?

本文简介点赞+关注+收藏=学会了技术一直在演变,在网页中使用SVG的方法也层出不穷。每个时期都有对应的最优解。所以我打算把我知道的7种SVG的使用方法列举出来,有备无患~如果你还...

HTML5常用标签大全(html5em标签)

HTML前端开发最终取决于掌握标签的多少HTML大概有七八百个标签楼主这里给大家总结了下HTML常用标签标签描述<!--...-->定义注释。<!DOCTYPE>定义文档类型...

&quot;伪君子Snoop Dogg!&quot;... WHAT?| MetroDaily 24/7

TUE.01-新作品-虽说年纪大了会有点糊涂,但是最近SnoopDogg的这波操作实在是让粉丝们有点迷,甚至有人表示没想到他是这样的"伪君子"......而这一切都源于他近日在IG上Po出的一...

史努比snoopy卡通手机壁纸屏保(史努比壁纸无水印)

...

莎夏·班克斯盼望表哥Snoop Dogg为其作出场曲

NXT女子冠军莎夏·班克斯(SashaBanks)近日接受了迈阿密先驱报采访,访谈纪要如下:关于她出众的形象:“我一向喜欢与众不同。为了能让人眼前一亮,我的装束总是非常前卫、非常抢眼,这样才能让观众...

喜欢Snoop!全球第一间「史努比博物馆」海外分馆在东京!

1950年起,由美國漫畫家CharlesM.Schulz創作的作品《Snoopy》史努比,其鮮明的可愛角色與幽默的劇情內容,至今仍成為許多大朋友與小朋友心中的最愛。為了紀念作者所設立的全球首...

Vetements 推出 Snoop Dogg 肖像「天价」T-Shirt

Vetements的CEOGuramGvasalia早前才透露品牌经营策略的秘密–Vetements如何成为人人热议的话题品牌。但似乎他仍有更多需要解释的东西–这个法国奢侈品牌最新...

狗爷Snoop Dogg的《I Wanna Thank Me》巡回演唱会旧金山站

西海岸匪帮说唱歌手SnoopDogg在《IWannaThankMe》巡回演唱会旧金山站表演(图片来自ICphoto)西海岸匪帮说唱歌手SnoopDogg(图片来自ICphoto)西海...

取消回复欢迎 发表评论: