7、Category
Log4cpp中有一个总是可用并实例化好的Category,即根Category。使用log4cpp::Category::getRoot()可以得到根Category。在大多数情况下,一个应用程序只需要一个日志种类(Category),但是有时也会用到多个Category,此时可以使用根Category的getInstance方法来得到子Category。不同的子Category用于不同的场合。一个简单的例子CategoryExam如下所示:
#include <log4cpp/Category.hh>
#include <log4cpp/OstreamAppender.hh>
#include <log4cpp/FileAppender.hh>
#include <log4cpp/BasicLayout.hh>
#include <log4cpp/Priority.hh>
using namespace std;
int main(int argc, char* argv[])
{
log4cpp::OstreamAppender* osAppender1 = new log4cpp::OstreamAppender("osAppender1", &cout);
osAppender1->setLayout(new log4cpp::BasicLayout());
log4cpp::OstreamAppender* osAppender2 = new log4cpp::OstreamAppender("osAppender2", &cout);
osAppender2->setLayout(new log4cpp::BasicLayout());
log4cpp::Category& root = log4cpp::Category::getRoot();
root.setPriority(log4cpp::Priority::DEBUG);
log4cpp::Category& sub1 = root.getInstance("sub1");
sub1.addAppender(osAppender1);
sub1.setPriority(log4cpp::Priority::DEBUG);
sub1.error("sub error");
log4cpp::Category& sub2 = root.getInstance("sub2");
sub2.addAppender(osAppender2);
sub2.setPriority(101);
sub2.warn("sub2 warning");
sub2.fatal("sub2 fatal");
sub2.alert("sub2 alert");
sub2.crit("sub2 crit");
log4cpp::Category::shutdown();
return 0;
}
运行结果如下:
1248869982 FATAL sub2 : sub2 fatal
1248869982 ALERT sub2 : sub2 alert
这个例子中共有三个Category,分别是根、sub1和sub2,其中sub1记录了一条日志,sub2记录了两条日志。Sub2另外两个日志由于优先级不够未能记录。
8、NDC
NDC是nested Diagnostic Context的缩写,意思是“嵌套的诊断上下文”。NDC是一种用来区分不同源代码中交替出现的日志的手段。当一个服务端程序同时记录好几个并行客户时,输出的日志会混杂在一起难以区分。但如果不同上下文的日志入口拥有一个特定的标识,则可以解决这个问题。NDC就是在这种情况下发挥作用。注意NDC是以线程为基础的,每个线程拥有一个NDC,每个NDC的操作仅对执行该操作的线程有效。
NDC的几个有用的方法是:push、pop、get和clear。注意它们都是静态函数:
Push可以让当前线程进入一个NDC,如果该NDC不存在,则根据push的参数创建一个NDC并进入;如果再调用一次push,则进入子NDC;
Pop可以让当前线程从上一级NDC中退出,但是一次只能退出一级。
Clear可以让当前线程从所有嵌套的NDC中退出。
Get可以得到当前NDC的名字,如果有嵌套,则不同级别之间的名字用空格隔开。
一个简单的例子NDCExam如下:
#include <log4cpp/NDC.hh>
using namespace log4cpp;
int main(int argc, char** argv) {
std::cout << "1. empty NDC: " << NDC::get() << std::endl;
NDC::push("context1");
std::cout << "2. push context1: " << NDC::get() << std::endl;
NDC::push("context2");
std::cout << "3. push context2: " << NDC::get() << std::endl;
NDC::push("context3");
std::cout << "4. push context3: " << NDC::get() << std::endl;
std::cout << "5. get depth: " << NDC::getDepth() << std::endl;
std::cout << "6. pop: " << NDC::pop() << std::endl;
std::cout << "7. after pop:"<<NDC::get()<<std::endl;
NDC::clear();
std::cout << "8. clear: " << NDC::get() << std::endl;
return 0;
}
该例子来自log4cpp的例子程序,我做了简单的修改。在记录日志的时候,可以从NDC中得知当前线程的嵌套关系。