log4cpp有3个主要的组件:categories(类别)、appenders(附加目的地)、和 layouts(布局),layout类控制输出日志消息的显示样式(看起来像什么)。log4cpp当前提供以下layout格式:
log4cpp::BasicLayout // 以“时间戳 优先级(priority,下文介绍)
// 类别(category,下文介绍)
// NDC标签
log4cpp::PatternLayout // 让用户根据类似于 C 语言 printf 函数的转换模式来指定输出格式。
log4cpp::SimpleLayout // 以“优先级(priority) - 日志信息”格式显示。
appender类用来输出日志(被layout格式化后的)到一些设备上。比如文件、syslog服务、
某个socket等。可以定义自己的appender类输出日志信息到别的设备上,比如应用自身的
日子处理进程、数据库等。appender和layout的关系是layout附在appender上,
appender类调用layout处理完日志消息后,记录到某个设备上。log4cpp当前
提供以下appender:
log4cpp::IdsaAppender // 发送到IDS或者logger,
log4cpp::FileAppender // 输出到文件
log4cpp::RollingFileAppender // 输出到回卷文件,即当文件到达某个大小后回卷
log4cpp::OstreamAppender // 输出到一个ostream类
log4cpp::RemoteSyslogAppender // 输出到远程syslog服务器
log4cpp::StringQueueAppender // 内存队列
log4cpp::SyslogAppender // 本地syslog
log4cpp::Win32DebugAppender // 发送到缺省系统调试器
log4cpp::NTEventLogAppender // 发送到win 事件日志
category 类真正完成记录日志功能,两个主要组成部分是appenders和priority(优先级)。优先级控制哪类日志信息可以被这个category记录,当前优先级分为:NOTSET, DEBUG, INFO, NOTICE, WARN, ERROR, CRIT, ALERT 或 FATAL/EMERG 。每个日志信息有个优先级,每个category有个优先级,当消息的优先级大于等于category的优先级时,这个消息才会被category记录,否则被忽略。优先级的关系如下。category类和appender的关系是,多个appender附在category上,这样一个日志消息可以同时输出到多个设备上。
NOTSET < DEBUG < INFO < NOTICE < WARN < ERROR < CRIT < ALERT < FATAL = EMERG
category被组织成一个树,子category创建时优先级缺省NOTSET,category缺省会继承父category的appender。而如果不希望这种appender的继承关系,log4cpp允许使用additivity 标签,为false时新的appender取代category的appender列表。
log4cpp可以用手动方式使用,也可以使用配置文件使用,用配置文件的方式简单,便捷。所有,现在都用配置文件的方式。
log 的优先级别解读,参阅源码 log4cpp-0.3.5rc3\include\log4cpp\Priority.hh
由高到低
EMERG
FATAL
ALERT
CRIT
ERROR
WARN
NOTICE
INFO
DEBUG
NOTSET
对应到 Category 相应函数,参阅源码 log4cpp-0.3.5rc3\include\log4cpp\Category.hh
Category::emerg()
Category::fatal()
Category::alert()
Category::crit()
Category::error()
Category::warn()
Category::notice()
Category::info()
Category::debug()
以上函数都有 2 个重载函数,可分别接受格式化字串或 std::string,例如 debug(),有
void debug(const char* stringFormat, ...) throw();
void debug(const std::string& message) throw();
关于优先级别使用的建议
开发运行时,设为 DEBUG 级,而正式运营时,则设为 NOTICE ;
一定要显示出来的信息则可以用 NOTICE 或以上级别;
跟踪函数运行痕迹的信息用 INFO 级别;
运行时调试的信息用 DEBUG 级别;
举例说明
void initialize(int argc, char* argv[])
{
log.info("initialize() : argc=%d", argc);
for (int i=0; i < argc; ++i)
{
log.debug("initialize() : argv[%d]=%s", i, argv[i]);
}
log.notice("initialize() : done");
}
log4cpp 的 category 分为 rootCategory 和其它自定义的 category。
而每个 category 都可以输出到多个 appender。并且 category 也是有包含关系的。
例如 rootCategory 就是所有 category 的根。而自定义的 category 也可以在配置文件中定义其包含关系。
先看一个 rootCategory 的配置
log4cpp.rootCategory=DEBUG, console, sample
这个定义里,指定了 rootCategory 的 log 优先级是 DEBUG,其 appender 有 2 个,分别是 console 和 sample。
即是说,等号右边内容以逗号分隔,第一项是优先级别,接下来的都是 appender 名字,可以有一个或多个。
现在来看看自定义的 category
log4cpp.category.demo=DEBUG, sample
这里定义了一个名字为 demo 的 category,其优先级为 DEBUG,appender 为 sample。
注意, category 和 appender 名字可以完全相同。
再来看看有包含关系的 category 的定义
log4cpp.category.demo.son=DEBUG, son
log4cpp.category.demo.daughter=DEBUG, daughter
以上定义了 2 个 category,名字分别为 son 和 daughter,其父 category 为 demo。
son 产生的 log 会写到 son 和 demo 的 appender 中。同理,daughter 的 log 会写到 daughter 和 demo 的 appender 中。
现在来看看 appender 的定义。appender 有很多种,我这里只介绍几种,分别是
ConsoleAppender : 控制台输出,即 std::cout
Win32DebugAppender : VC IDE 的输出,即 ::OutputDebugString
FileAppender : 文件输出
RollingFileAppender : 有待研究
现在看一个 ConsoleAppender 的例子
log4cpp.appender.console=ConsoleAppender
log4cpp.appender.console.layout=PatternLayout
log4cpp.appender.console.layout.ConversionPattern=%d [%p] - %m%n
以上信息解释为:一个名为 console 的 appender,其类型为 ConsoleAppender,即 控制台输出 log 输出的布局是 指定的样式
输出的格式 是 "%d [%p] - %m%n" (稍后再解释)
再看一个 FileAppender 的例子
log4cpp.appender.sample=FileAppender
log4cpp.appender.sample.fileName=sample.log
log4cpp.appender.sample.layout=PatternLayout
log4cpp.appender.sample.layout.ConversionPattern=%d [%p] - %m%n
以上信息解释为:一个名为 sample 的 appender,其类型为 FileAppender,即 文件输出指定的 log 文件名为 sample.log,输出的布局是 指定的样式,输出的格式 是 "%d [%p] - %m%n"
对应 category 和 appender 的配置方式,可以发现
category 是 "log4cpp.category." + "category name"
category 名字可以用 "." 分隔,以标识包含关系
appender 是 "log4cpp.appender." + "appender name"
appender 名字 不能 用 "." 分隔,即是说 appender 是没有包含关系的
现在看一个完整的配置文件例子
#定义 root category 的属性
log4cpp.rootCategory=DEBUG, console
#定义 console 属性
log4cpp.appender.console=ConsoleAppender
log4cpp.appender.console.layout=PatternLayout
log4cpp.appender.console.layout.ConversionPattern=%d [%p] - %m%n
#定义 sample category 的属性
l
og4cpp.category.sample=DEBUG, sample
#定义 sample appender 的属性
log4cpp.appender.sample=FileAppender
log4cpp.appender.sample.fileName=sample.log
log4cpp.appender.sample.layout=PatternLayout
log4cpp.appender.sample.layout.ConversionPattern=%d [%p] - %m%n
#定义 sample.son category 的属性
log4cpp.category.sample.son=DEBUG, son
#定义 son appender 的属性
log4cpp.appender.son=FileAppender
log4cpp.appender.son.fileName=son.log
log4cpp.appender.son.layout=PatternLayout
log4cpp.appender.son.layout.ConversionPattern=%d [%p] - %m%n
#定义 sample.daughter category 的属性
log4cpp.category.sample.daughter=DEBUG, daughter
#定义 daughter appender 的属性
log4cpp.appender.daughter=FileAppender
log4cpp.appender.daughter.fileName=daughter.log
log4cpp.appender.daughter.layout=PatternLayout
log4cpp.appender.daughter.layout.ConversionPattern=%d [%p] - %m%n
ConversionPattern 参数解读,参阅源码 log4cpp-0.3.5rc3\src\PatternLayout.cpp
%m log message 内容, 即 用户写 log 的具体信息
%n 回车换行
%c category 名字
%d 时间戳
%p 优先级
%r 距离上一次写 log 的间隔, 单位毫秒
%R 距离上一次写 log 的间隔, 单位秒
%t 线程名
%u 处理器时间
%x NDC ?
窃以为,以下格式就足够了,即输出 "时间 [线程名] 优先级 - log内容 回车换行"
%d [%t] %p - %m%n
配置的知识就差不多了,现在看看实际代码应用
首先是初始化 log4cpp 的配置,例如我的配置文件名是 log4cpp.properties
try
{
log4cpp::PropertyConfigurator::configure("log4cpp.properties");
}
catch (log4cpp::ConfigureFailure & f)
{
std::cerr << "configure problem " << f.what() << std::endl;
}
初始化完成后,就可以这样用了(具体的应用技巧,你自己摸索吧)
log4cpp::Category & log = log4cpp::Category::getInstance(std::string("sample"));
log.debug("test debug log");
log.info("test info log");
// 用 sample.son
log4cpp::Category & log = log4cpp::Category::getInstance(std::string("sample.son"));
log.debug("test debug log of son");
log.info("test info log of son");
// 用 sample.daughter
log4cpp::Category & log = log4cpp::Category::getInstance(std::string("sample.daughter"));
log.debug("test debug log of daughter");
log.info("test info log of daughter");
再举一个在自定义类中的使用
#include <log4cpp/Category.hh>
namespace demo
{
class Sample
{
public:
Sample();
~Sample();
public:
Testing(int i);
private:
static log4cpp::Category & log;
};
}
#include "Sample.h"
namespace demo
{
log4cpp::Category & Sample::log = log4cpp::Category::getInstance(std::string("sample"));
Sample::Sample()
{
log.debug("Sample::Sample()");
}
Sample::~Sample()
{
log.debug("Sample::~Sample()");
}
Sample::Testing(int i)
{
log.debug("Sample::Testing() : i=%d", i);
}
}
转载文章:
1. 便利的开发工具-log4cpp快速使用指南(http://www.ibm.com/developerworks/cn/linux/l-log4cpp/index.html)
2. example of log4cpp properties configuration(http://blog.chinaunix.net/u1/50766/showart_400018.html)
分享到:
相关推荐
Log4cpp 支持通过 XML 或者 properties 格式的配置文件进行更复杂的设置,如日志级别、输出格式、过滤规则等。例如,在 `log4cpp.properties` 文件中: ``` log4cpp.category.MyLogger=DEBUG, myAppender log4cpp....
// 加载配置文件 log4cpp::Category& root = log4cpp::Category::getRoot(); root.debug("This is a debug message."); root.notice("This is a notice message."); // 更多日志记录... } ``` 通过这种方式,...
在提供的压缩包文件中,"MFC使用log4cpp"和"MFC╩╣╙├log4cpp"可能包含更具体的示例代码或者项目的实现,读者可以通过查看这些文件进一步了解如何在实际项目中整合和使用log4cpp。 总之,log4cpp为C++开发者提供...
在实际应用中,你可能需要在应用程序启动时加载外部配置文件(如log4cpp.properties),这样可以在不修改代码的情况下调整日志设置。配置文件可以包含多个Appender,不同级别的日志可以输出到不同的文件,或者通过...
LOG4CPP的核心思想是层次化的日志记录,通过定义不同的日志级别(如DEBUG、INFO、WARN、ERROR和FATAL)来控制日志信息的输出,以及通过配置文件来指定日志输出的目的地(如控制台、文件、网络等)。 首先,我们要...
总之,交叉编译log4cpp涉及到选择正确的交叉编译工具链,正确配置编译选项,以及在目标平台上安装生成的库。这个过程对于在ARM设备上运行log4cpp并利用其强大的日志管理能力至关重要。正确执行这些步骤后,开发者...
5. **配置文件**:log4cpp支持通过XML或文本配置文件来设定日志行为,方便调整而无需修改代码。 **三、使用步骤** 1. **安装库文件**:首先,你需要将log4cpp-1.1.1_lib解压并链接到你的项目中,这通常涉及设置...
在这里,"log4cpp.properties"是一个配置文件,用于设置Appender的属性。这个文件可以包含如下的配置: ``` log4cpp.appender.FILE=log4cpp::OstreamAppender log4cpp.appender.FILE.stream=std::cout log4cpp....
log4cpp有很多优点,包括提供了可扩展的多种日志记录方式、提供了NDC(嵌套诊断上下文)、提供了完整的日志动态优先级控制、可通过配置文件完成所有配置并动态加载、性能优秀、内存占用小、代码级的平台无关性、概念...
2. **配置**:使用log4cpp的配置文件(通常是XML或文本格式),或者通过代码动态配置日志级别、Appender等。 3. **创建日志对象**:创建一个`Category`对象,代表你要记录的日志类别。 4. **写入日志**:通过调用`...
1. **配置文件解析**:log4cpp支持通过配置文件设置日志属性,如日志级别、输出目的地等。解析配置文件的过程是通过`PropertyConfigurator`类完成的。 2. **日志级别管理**:log4cpp提供了`Priority`枚举类型,包含...
2. `log4cpp.properties`:配置文件,定义了日志输出的方式和位置。 3. `Makefile`:用于编译和链接程序的Makefile文件,包含了编译Log4cpp库和应用的指令。 4. `include`和`lib`目录:可能包含Log4cpp库的头文件和...
通常,这样的包会包含头文件、实现文件、示例代码、配置文件、README文档等,可以帮助我们了解如何集成和使用这个按日期生成日志的特性。 **详细知识点:** 1. **日志框架:**Log4cpp是一个广泛使用的C++日志库,...
封装了一个使用类,从本地读取配置log级别等信息,可输出多个种类的日志文件,输出示例如下 [2017-02-20 16:09:51.910](NOTICE)Sys : 进入了CPfy_log4cppDlg::OnBnClickedButton1函数 [2017-02-20 16:09:51.911]...
此外,log4cpp支持配置文件,使得用户可以根据需要动态调整日志行为,无需修改代码。 二、在VS2010中编译log4cpp 1. 获取源码:首先,你需要从官方网站或者GitHub等平台下载log4cpp的源代码。 2. 创建项目:在VS...
Log4cpp是C++编程语言中的一个开源日志框架,灵感来源于Java的log4j库。这个库的主要目的是提供一种灵活、高效且可扩展的日志记录解决方案,使得开发者能够方便地在不同级别(如DEBUG、INFO、WARN、ERROR、FATAL)上...
3. **初始化与使用**:在程序开始时,加载配置文件并初始化`log4cpp`。然后,通过类别名和日志级别进行日志记录: ```cpp #include <log4cpp/PropertyConfigurator.hh> #include <log4cpp/Category.hh> int ...
`log4cpp`利用了C++的模板和面向对象特性,如工厂模式(用于生成Appender和Layout实例)、策略模式(通过配置文件改变日志行为)等,实现了高度模块化和可扩展性。 **7. 性能与可移植性** `log4cpp`被设计为高效且...
5. **配置文件**:`log4cpp`通常通过XML或文本配置文件来定义日志行为,包括设置日志级别、选择Appender和配置Layout。配置文件的灵活性使得在不修改代码的情况下可以调整日志策略。 6. **API接口**:在源码中,你...
通过XML或文本配置文件,用户可以定制日志输出的位置(如控制台、文件、网络等)、格式以及过滤规则。例如,可以设置只在ERROR及以上级别时才将日志写入文件。 3. **日志Appender**: Appender是log4cpp的核心组件...