让我们从一个简单的例子开始, 该例子将两条日志信息写入字符串流, 该流会在标准控制台 cout 上输出, 项目的名称是 HelloLog4Cpp:
// 步凑:
//1. 创建一个 Appender,并指定其包含的 Layout;
//2. 从系统中得到 Category 的根,将 Appender 添加到该 Category 中;
//3. 设置 Category 的优先级;
//4. 记录日志;
//5. 关闭 Category。
#include <iostream>
#include <log4cpp/Category.hh> // 负责向日志中写入信息
#include <log4cpp/OstreamAppender.hh> // 负责指定日志的目的地
#include <log4cpp/BasicLayout.hh> // 负责设定日志的格式
#include <log4cpp/Priority.hh> // 指定 Category 的优先级和日志的优先级
using namespace std;
using namespace log4cpp;
int main(void)
{
// 指定日志输出目的地
OstreamAppender * pOstremAppender =
new OstreamAppender("osAppender", &cout);
// 设置格式化日志信息
pOstremAppender->setLayout(new BasicLayout());
// 负责输出日志
Category & root = Category::getRoot();
root.addAppender(pOstremAppender);
root.setPriority(Priority::ERROR);
// 写日志
root.error("hello log4cpp in a Error Message!");
root.warn("hello log4cpp in a warn Message!");
// 关闭 Category
Category::shutdown();
return 0;
}
| // 系统中可以有多个 Category,它们都继承自同一个跟 root,每个 Category 负责记录自己的日志;
// 每个 Category 可以添加多个 Appender(目的地,日志要输出到哪), 每个 Appender 制定了一个日志的目的地;
// 这个目的地可以是文件,字符流或者 windws 日志,当 Category 记录一条日志时,该日志被写入所有
// 附加到此 Category 的 Appender;
// 每个 Append 都包含一个 Layout, 该 Layout 定义了这个 Appender 上日志的格式。
//
#include<iostream>
#include<log4cpp/Category.hh>
#include<log4cpp/OstreamAppender.hh>
#include<log4cpp/BasicLayout.hh>
#include<log4cpp/Priority.hh>
using namespace std;
// 引入命名空间 log4cpp 就可以不用加作用名限定 log4cpp::
int main(int argc,char *argv[])
{
// 指定日志输出目的地; 附加目的地,cout,输出终端; 堆对象,防止超出作用域被释放
log4cpp::OstreamAppender* osAppender = new log4cpp::OstreamAppender("osAppender",&cout );
// 设置格式化日志信息; 设置 APPender 的布局
osAppender->setLayout(new log4cpp::BasicLayout());
// 负责输出日志;得到系统的根 root
log4cpp::Category& root = log4cpp::Category::getRoot();
// 把设置好的 Append 添加到系统 root 下
root.addAppender(osAppender);
root.setPriority(log4cpp::Priority::DEBUG);
// 写日志
root.error("Hello log4cpp in a Error Message!");
root.warn("Hello log4cpp in a Warning Message!");
// 关闭日志
log4cpp::Category::shutdown();
return 0;
}
//1514104975 ERROR : Hello log4cpp in a Error Message!
//1514104975 WARN : Hello log4cpp in a Warning Message!
|
编译:g++ helloworld.cpp -o helloworld -llog4cpp -lpthread
运行结果:1248337987 ERROR : Hello log4cpp in a Error Message!
1248337
注:以上两条日志格式很简陋,要设置合乎心意的日志格式,请参考后续的 PatternLayout 章节。
|
相关概念:
Log4cpp 中的概念继承自 log4j, 最重要的是 Category(种类),Appender(附加目的地) 和 Layout(布局) 三个概念, 此外还有 Priority(优先级) 和 NDC(嵌套的诊断上下文) 等.
简言之, Category 负责向日志中写入信息, Appender 负责指定日志的目的地, Layout 负责设定日志的格式, Priority 被用来指定 Category 的优先级和日志的优先级, NDC 则是一种用来区分不同场景中交替出现的日志的手段.
Log4cpp 记录日志的原理如下: 每个 Category 都有一个优先级, 该优先级可以由 setPriority 方法设置, 或者从其父 Category 中继承而来. 每条日志也有一个优先级, 当 Category 记录该条日志时, 若日志优先级高于 Category 的优先级时, 该日志被记录, 否则被忽略. 系统中默认的优先级等级如下:
typedef enum { EMERG = 0,
FATAL = 0,
ALERT = 100,
CRIT = 200,
ERROR = 300,
WARN = 400,
NOTICE = 500,
INFO = 600,
DEBUG = 700,
NOTSET = 800
} PriorityLevel;
|
注意: 取值越小, 优先级越高. 例如一个 Category 的优先级为 101, 则所有 EMERG,FATAL,ALERT 日志都可以记录下来, 而其他则不能.
Category,Appender 和 Layout 三者的关系如下: 系统中可以有多个 Category, 它们都是继承自同一个根, 每个 Category 负责记录自己的日志; 每个 Category 可以添加多个 Appender, 每个 Appender 指定了一个日志的目的地, 例如文件, 字符流或者 Windows 日志, 当 Category 记录一条日志时, 该日志被写入所有附加到此 Category 的 Appender; 每个 Append 都包含一个 Layout, 该 Layout 定义了这个 Appender 上日志的格式.
现在重温前面的 HelloWorld 程序, 可以发现其流程如下:
1. 创建一个 Appender, 并指定其包含的 Layout;
2. 从系统中得到 Category 的根, 将 Appender 添加到该 Category 中;
3. 设置 Category 的优先级;
4. 记录日志;
5. 关闭 Category.
下面, 我们按照 Layout,Appender,Category,NDC 的顺序来依次介绍这些概念并给出例子.
来源: http://www.bubuko.com/infodetail-2566314.html