C++: log4cpp日志管理系统的简单介绍

一、Layout,设置日志输出风格

有BasicLayout、SimpleLayout、PatternLayout,其中BasicLayout,SimpleLayout主要是提供的成型的简单日志风格,实际中基本不会使用,主要是使用PatternLayout对日志做格式输出,Layout是加载到Appender中去的。

涉及头文件:

#include<log4cpp/BasicLayout.hh>
#include<log4cpp/SimpleLayout.hh>
#include<log4cpp/PatternLayout.hh>

BasicLayout: "以时间戳 + 优先级 + 内容"
构造函数:

log4cpp::BasicLayout::BasicLayout()

输出例子格式:

1248337987 ERROR : Hello log4cppin a Error Message!
1248337987 WARN : Hello log4cppin a Warning Message!

SimpleLayout:"优先级 + 日志信息"

log4cpp::SimpleLayout::SimpleLayout()

PatterLayout: "使用类似 printf 的格式化模式"
构造函数:

log4cpp::PatternLayout::PatternLayout()

PatterLayout 设置日志格式函数:

void log4cpp::PatternLayout::setConversionPattern(const std::string &conversionPattern) throw(ConfigureFailure)

使用 PatterLayout 时的格式化参数:

%c category;
%d 日期;日期可以进一步的设置格式,用花括号包围,例如%d{%H:%M:%S,%l} 或者 %d{%d %m
%Y%H:%M:%S,%l}%m 消息;
%n 换行符,会根据平台的不同而不同,但对于用户透明;
%p 优先级;
%r 自从 layout 被创建后的毫秒数;
%R 从 1970110 时开始到目前为止的秒数;
%u 进程开始到目前为止的时钟周期数;
log4cpp::PatternLayout* pLayout = new log4cpp::PatternLayout();
pLayout->setConversionPattern("%d: [%p] %c %x: %m %n");
appender->setLayout(pLayout);
二、Appender,确定日志输出行为

例如输出到哪儿,如何输出。类Appender是由Category来加载的,一个Category可以加载多个Appender,输出到多个地方,一个Appender也可以被多个Category加载,但是有些Appender类没有设置互斥,日志的多线程支持主要是在Category里做的处理,因此不要使用一个Appender加载到多个Category中。

涉及头文件:

#include <log4cpp/Appender.hh>
#include <log4cpp/OstreamAppender.hh>
#include <log4cpp/StringQueueAppender.hh>
#include <log4cpp/FileAppender.hh>
#include <log4cpp/RollingFileAppender.hh>

OstreamAppender //输出到一个 ostream 类

构造函数:

log4cpp::OstreamAppender::OstreamAppender(const std::string &name, std::ostream stream)

参数:

name the name of the Appender. ===>名称
stream the name of the ostream.===>流名字

举例:

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

StringQueueAppender //内存队列

构造函数:

log4cpp::StringQueueAppender::StringQueueAppender(const std::string &name)

举例:

log4cpp::StringQueueAppender* strQAppender =
new log4cpp::StringQueueAppender("strQAppender");

最常用的两个 FileAppender,其功能是将日志写入文件中
FileAppender // 输出到文件

构造函数:

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

参数:

name        the name of the Appender. ===>名称
fileName    the name of the file to which the Appender has to log.===>日志文件名
append      whether the Appender has to truncate the file or just append to it if it
already exists. Defaults to 'true'.(===>是否在日志文件后继续记入日志,还是清空原
日志文件再记录)
mode        file mode to open the logfile with. Defaults to 00644.
===>文件的打开方式

举例:

log4cpp::FileAppender* fileAppender =
newlog4cpp::FileAppender("fileAppender","wxb.log");
fileAppender->setLayout(pLayout1);

构造函数:

log4cpp::FileAppender::FileAppender (const std::string &name, int fd)

参数:

name the name of the Appender.
fd the file descriptor to which the Appender has to log.

RollingFileAppender

构造函数:

log4cpp::RollingFileAppender::RollingFileAppender(const std::string &name,
const std::string &fileName,
size_t maxFileSize = 10 *1024 *1024,
unsigned int maxBackupIndex = 1,
bool append = true,
mode_t mode = 00644)

参数:

前两个参数与普通文件的类似
第三个参数    maxFileSize:指出了回滚文件的最大值
第四个参数    maxBackupIndex:指出了回滚文件所用的备份文件的最大个数。所谓备份文件,
是用来保存回滚文件中因为空间不足未能记录的日志,备份文件的大小仅比回滚文件的最大
值大 1kb。所以如果 maxBackupIndex 取值为 3,则回滚文件(假设其名称是 rollwxb.log,
大小为 100kb)会有三个备份文件,其名称分别是 rollwxb.log.1,rollwxb.log.2 和
rollwxb.log.3,大小为 101kb。另外要注意:如果 maxBackupIndex 取值为 0 或者小于 0,
则回滚文件功能会失效,其表现如同 FileAppender 一样,不会有大小的限制。这也许是一
个 bug。
第五第六参数同上。

举例:

log4cpp::RollingFileAppender* rollfileAppender =
newlog4cpp::RollingFileAppender( "rollfileAppender","rollwxb.log",5*1024,1);
rollfileAppender->setLayout(pLayout2)
Appender 有个成员函数(方法):
virtual void log4cpp::Appender::setLayout(Layout *layout)
函数用作:设置 appender 格式
参数:layout The layout to use.
三、Category,日志输出主体类

提供了输出各种日志级别的方法,并且能够设置类别优先级,低于此优先级的类都不再输出,可以有多个分类,但每个应用程序都有一个root分类,其他分类都是root分类的子分类,有点类似于java的单继承结构,子分类的输出同时会输出到父分类中。

涉及头文件:

#include<log4cpp/Category.hh>

Log4cpp 中有一个总是可用并实例化好的 Category,即根 Category。
使用log4cpp::Category::getRoot()可以得到根 Category。
在大多数情况下,一个应用程序只需要一个日志种类(Category),但是有时也会用到多个Category,此时可以使用根 Category 的 getInstance 方法来得到子 Category。不同的子Category 用于不同的场合。

构造函数:

log4cpp::Category& root =log4cpp::Category::getRoot();
log4cpp::Category& infoCategory =root.getInstance("infoCategory");
infoCategory.addAppender(osAppender);
infoCategory.setPriority(log4cpp::Priority::INFO);

主要的成员函数:

1、设置 category 的级别

void log4cpp::Category::setPriority (Priority::Value priority) throw
(std::invalid_argument)

Set the priority of this Category.Parameters:
priority The priority to set. Use Priority::NOTSET to let the category use its
parents priority as effective priority.

2、设置或添加 appender

void log4cpp::Category::addAppender (Appender *appender ) throw
(std::invalid_argument) [virtual]

Adds an Appender to this Category.
This method passes ownership from the caller to the Category.

void log4cpp::Category::setAppender (Appender *appender ) [inline]

Adds an Appender to this Category.
This method passes ownership from the caller to the Category.

3、相应日志级别的记录

void log4cpp::Category::warn(const std::string &message) throw ()
Log a message with warn priority.
Parameters:
message string to write in the log file

void log4cpp::Category::warn(const char * stringFormat,... ) throw ()
Log a message with warn priority.
Parameters:
stringFormat Format specifier for the string to write in the log file.

void log4cpp::Category::error(const std::string &message) throw ()
Log a message with error priority.
Parameters:
message string to write in the log file

void log4cpp::Category::error(const char *stringFormat,... ) throw ()
Log a message with error priority.
Parameters:
stringFormat Format specifier for the string to write in the log file.
四、Priority:优先级

用来指定 Category 优先级和日志优先级

涉及头文件:

#include<log4cpp/Priority.hh>

Log4cpp记录日志的原理

每个Category都有一个优先级,该优先级可以由setPriority方法设置,或者从其父 Category 中继承而来。
每条日志也有一个优先级,当 Category 记录该条日志时,若日志优先级高于 Category 的优先级时,该日志被记录,否则被忽略。系统中默认的优先级等级如下:

typedef enum
{
    EMERG  = 0,     // emergency
    FATAL  = 0,     // fatal
    ALERT  = 100,   // alert
    CRIT   = 200,   // critical
    ERROR  = 300,   // error
    WARN   = 400,   // wanning
    NOTICE = 500,   // notice
    INFO   = 600,   // infomation
    DEBUG  = 700,   // debug
    NOTSET = 800   
} PriorityLevel;

注意:取值越小,优先级越高。例如一个 Category 的优先级为 101,则所有 EMERG、FATAL、ALERT 日志都可以记录下来,而其他则不能。

Log4cpp 的自动内存管理
Log4cpp 的内存对象管理

Log4cpp 中 new 出来的 Category、Appender 和 Layout 都不需要手动释放,因为 Log4cpp 使
用了一个内部类来管理这些对象。此类的名称是 HierarchyMaintainer,它负责管理 Category 的继承
关系,在程序结束时,HierarchyMaintainer 会依次释放所有 Category,而 Category 则会依次释放拥
有的有效 Appender,Appender 则会释放所有附属的 Layout。如果程序员手动释放这些对象,则会造
成内存报错。从下面的代码可以看出这个特征:

appender->setLayout(new log4cpp::BasicLayout());

这个 new 出来的 BasicLayout 根本就没有保存其指针,所以它只能被 log4cpp 的内存管理类
HierarchyMaintainer 释放。了解到 HierarchyMaintainer 的内存管理方法后,程序员在使用 log4cpp
时应该遵循以下几个使用原则:

  1. 不要手动释放 Category、Appender 和 Layout;
  2. 同一个 Appender 不要加入多个 Category,否则它会被释放多次从而导致程序崩溃;
  3. 同一个 Layout 不要附着到多个 Appender 上,否则也会被释放多次导致程序崩溃;
log4cpp::Category::shutdown()

在不使用 log4cpp 时可调用 log4cpp::Category::shutdown(),其功能如同HierarchyMaintainer 的内存清理。但如果不手动调用,在程序结束时 HierarchyMaintainer 会调用 Category 的析构函数来释放所有 Appender。

部分参考:https://www.cnblogs.com/cthon/p/9192787.html

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值