首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 其他教程 > 开源软件 >

开源日记系统log4cplus(五)

2013-08-04 
开源日志系统log4cplus(五)? ? LOG4CPLUS_FATAL(root, root: llm.toString(root.getChainedLogLevel

开源日志系统log4cplus(五)

? ? LOG4CPLUS_FATAL(root, "root: " << llm.toString(root.getChainedLogLevel()))

? ? LOG4CPLUS_FATAL(root, "test: " << llm.toString(test.getChainedLogLevel()))

? ? LOG4CPLUS_FATAL(root, "test.subtest: " << llm.toString(subTest.getChainedLogLevel()))

? ? cout << endl << "Setting test.subtest to WARN" << endl;

? ? subTest.setLogLevel(WARN_LOG_LEVEL);

? ? LOG4CPLUS_FATAL(root, "root: " << llm.toString(root.getChainedLogLevel()))

? ? LOG4CPLUS_FATAL(root, "test: " << llm.toString(test.getChainedLogLevel()))

? ? LOG4CPLUS_FATAL(root, "test.subtest: " << llm.toString(subTest.getChainedLogLevel()))

? ? cout << endl << "Setting test.subtest to TRACE" << endl;

? ? test.setLogLevel(TRACE_LOG_LEVEL);

? ? LOG4CPLUS_FATAL(root, "root: " << llm.toString(root.getChainedLogLevel()))

? ? LOG4CPLUS_FATAL(root, "test: " << llm.toString(test.getChainedLogLevel()))

? ? LOG4CPLUS_FATAL(root, "test.subtest: " << llm.toString(subTest.getChainedLogLevel()))

? ? cout << endl << "Setting test.subtest to NO_LEVEL" << endl;

? ? subTest.setLogLevel(NOT_SET_LOG_LEVEL);

? ? LOG4CPLUS_FATAL(root, "root: " << llm.toString(root.getChainedLogLevel()))

? ? LOG4CPLUS_FATAL(root, "test: " << llm.toString(test.getChainedLogLevel()))

? ? LOG4CPLUS_FATAL(root, "test.subtest: " << llm.toString(subTest.getChainedLogLevel()) << '\n')

? ? cout << "create a logger test_bak, named "test_", too. " << endl;

? ? Logger test_bak = Logger::getInstance("test");

? ? cout << "Setting test to INFO, so test_bak also be set to INFO" << endl;

? ? test.setLogLevel(INFO_LOG_LEVEL);

? ? LOG4CPLUS_FATAL(root, "test: " << llm.toString(test.getChainedLogLevel()))

? ? LOG4CPLUS_FATAL(root, "test_bak: " << llm.toString(test_bak.getChainedLogLevel()))

? ? return 0;

}

输出结果:

Before Setting, Default LogLevel

FATAL - root: DEBUG

FATAL - test: DEBUG

FATAL - test.subtest: DEBUG

Setting test.subtest to WARN

FATAL - root: DEBUG

FATAL - test: DEBUG

FATAL - test.subtest: WARN

Setting test.subtest to TRACE

FATAL - root: DEBUG

FATAL - test: TRACE

FATAL - test.subtest: WARN

Setting test.subtest to NO_LEVEL

FATAL - root: DEBUG

FATAL - test: TRACE

FATAL - test.subtest: TRACE

create a logger test_bak, named "test_", too.

Setting test to INFO, so test_bak also be set to INFO

FATAL - test: INFO

FATAL - test_bak: INFO

?

下面的例子演示了如何通过设置LogLevel来控制用户的log信息输出:

〖例7〗

#include "log4cplus/logger.h"

#include "log4cplus/consoleappender.h"

#include "log4cplus/loglevel.h"

#include <iostream>

using namespace std;

using namespace log4cplus;

void ShowMsg(void)

{

? ? LOG4CPLUS_TRACE(Logger::getRoot(),"info")

? ? LOG4CPLUS_DEBUG(Logger::getRoot(),"info")

? ? LOG4CPLUS_INFO(Logger::getRoot(),"info")

? ? LOG4CPLUS_WARN(Logger::getRoot(),"info")

? ? LOG4CPLUS_ERROR(Logger::getRoot(),"info")

? ? LOG4CPLUS_FATAL(Logger::getRoot(),"info")

}

int main()

{

? ? SharedAppenderPtr _append(new ConsoleAppender());

? ? _append->setName("test");

? ? _append->setLayout(std::auto_ptr(new TTCCLayout()));

? ? Logger root = Logger::getRoot();

? ? root.addAppender(_append);

? ? cout << endl << "all-log allowed" << endl;

? ? root.setLogLevel(ALL_LOG_LEVEL);

? ? ShowMsg();

? ? cout << endl << "trace-log and above allowed" << endl;

? ? root.setLogLevel(TRACE_LOG_LEVEL);

? ? ShowMsg();

? ? cout << endl << "debug-log and above allowed" << endl;

? ? root.setLogLevel(DEBUG_LOG_LEVEL);

? ? ShowMsg();

? ? cout << endl << "info-log and above allowed" << endl;

? ? root.setLogLevel(INFO_LOG_LEVEL);

? ? ShowMsg();

? ? cout << endl << "warn-log and above allowed" << endl;

? ? root.setLogLevel(WARN_LOG_LEVEL);

? ? ShowMsg();

? ? cout << endl << "error-log and above allowed" << endl;

? ? root.setLogLevel(ERROR_LOG_LEVEL);

? ? ShowMsg();

? ? cout << endl << "fatal-log and above allowed" << endl;

? ? root.setLogLevel(FATAL_LOG_LEVEL);

? ? ShowMsg();

? ? cout << endl << "log disabled" << endl;

? ? root.setLogLevel(OFF_LOG_LEVEL);

? ? ShowMsg();

? ? return 0;

}

输出结果:

all-log allowed

10-17-04 10:11:40,587 [1075298944] TRACE root <> - info

10-17-04 10:11:40,590 [1075298944] DEBUG root <> - info

10-17-04 10:11:40,591 [1075298944] INFO root <> - info

10-17-04 10:11:40,591 [1075298944] WARN root <> - info

10-17-04 10:11:40,592 [1075298944] ERROR root <> - info

10-17-04 10:11:40,592 [1075298944] FATAL root <> - info

trace-log and above allowed

10-17-04 10:11:40,593 [1075298944] TRACE root <> - info

10-17-04 10:11:40,593 [1075298944] DEBUG root <> - info

10-17-04 10:11:40,594 [1075298944] INFO root <> - info

10-17-04 10:11:40,594 [1075298944] WARN root <> - info

10-17-04 10:11:40,594 [1075298944] ERROR root <> - info

10-17-04 10:11:40,594 [1075298944] FATAL root <> - info

debug-log and above allowed

10-17-04 10:11:40,595 [1075298944] DEBUG root <> - info

10-17-04 10:11:40,595 [1075298944] INFO root <> - info

10-17-04 10:11:40,596 [1075298944] WARN root <> - info

10-17-04 10:11:40,596 [1075298944] ERROR root <> - info

10-17-04 10:11:40,596 [1075298944] FATAL root <> - info

info-log and above allowed

10-17-04 10:11:40,597 [1075298944] INFO root <> - info

10-17-04 10:11:40,597 [1075298944] WARN root <> - info

10-17-04 10:11:40,597 [1075298944] ERROR root <> - info

10-17-04 10:11:40,598 [1075298944] FATAL root <> - info

warn-log and above allowed

10-17-04 10:11:40,598 [1075298944] WARN root <> - info

10-17-04 10:11:40,598 [1075298944] ERROR root <> - info

10-17-04 10:11:40,599 [1075298944] FATAL root <> - info

error-log and above allowed

10-17-04 10:11:40,599 [1075298944] ERROR root <> - info

10-17-04 10:11:40,600 [1075298944] FATAL root <> - info

fatal-log and above allowed

10-17-04 10:11:40,600 [1075298944] FATAL root <> - info

log disabled

?

用户也可以自行定义LogLevel,操作比较简单,首先要定义LEVEL值,比如HELLO_LOG_LEVEL定义如下:

/* DEBUG_LOG_LEVEL ?< HELLO_LOG_LEVEL < INFO_LOG_LEVEL */

const LogLevel HELLO_LOG_LEVEL = 15000;

然后定义以下宏即可:

/* define MACRO LOG4CPLUS_HELLO */

#define LOG4CPLUS_HELLO(logger, logEvent) \

? ? if(logger.isEnabledFor(HELLO_LOG_LEVEL)) { \

? ? ? ? log4cplus::tostringstream _log4cplus_buf; \

? ? ? ? _log4cplus_buf << logEvent; \

?logger.forcedLog(HELLO_LOG_LEVEL, _log4cplus_buf.str(), __FILE__, __LINE__); \

? ? }

不过log4cplus没有提供给用户一个接口来实现LEVEL值与字符串的转换,所以当带格式输出LogLevel字符

串时候会显示"UNKNOWN", 不够理想。比如用TTCCLayout控制输出的结果可能会如下所示:

10-17-04 11:17:51,124 [1075298944] UNKNOWN root <> - info

而不是期望的以下结果:

10-17-04 11:17:51,124 [1075298944] HELLO root <> - info

要想实现第二种结果,按照log4cplus现有的接口机制,只能改其源代码后重新编译,方法是在loglevel.cxx

中加入:

#define _HELLO_STRING LOG4CPLUS_TEXT("HELLO")

然后修改log4cplus::tstring ?defaultLogLevelToStringMethod(LogLevel ll)函数,增加一个判断:

case HELLO_LOG_LEVEL: ? ?return _HELLO_STRING;

重新编译log4cplus源代码后生成库文件,再使用时即可实现满意效果。

?

### 调试模式 ###

即通过loglog来控制输出调试、警告或错误信息,见例4,这里不再赘述。

?

### 基于脚本配置来过滤log信息 ###

除了通过程序实现对log环境的配置之外,log4cplus通过PropertyConfigurator类实现了基于脚本配置的功能。

通过脚本可以完成对logger、appender和layout的配置,因此可以解决怎样输出,输出到哪里的问题,我将在

全文的最后一部分中提到多线程环境中如何利用脚本配置来配合实现性能测试,本节将重点介绍基脚本实现过

滤log信息的功能。

首先简单介绍一下脚本的语法规则:

包括Appender的配置语法和logger的配置语法,其中:

1.Appender的配置语法:

(1)设置名称:

/*设置方法*/

log4cplus.appender.appenderName=fully.qualified.name.of.appender.class

例如(列举了所有可能的Appender,其中SocketAppender后面会讲到):

log4cplus.appender.append_1=log4cplus::ConsoleAppender

log4cplus.appender.append_2=log4cplus::FileAppender

log4cplus.appender.append_3=log4cplus::RollingFileAppender

log4cplus.appender.append_4=log4cplus::DailyRollingFileAppender

log4cplus.appender.append_4=log4cplus::SocketAppender

(2)设置Filter:

包括选择过滤器和设置过滤条件,可选择的过滤器包括:LogLevelMatchFilter、LogLevelRangeFilter、

和StringMatchFilter:

对LogLevelMatchFilter来说,过滤条件包括LogLevelToMatch和AcceptOnMatch(true|false), 只有

当log信息的LogLevel值与LogLevelToMatch相同,且AcceptOnMatch为true时才会匹配。

LogLevelRangeFilter来说,过滤条件包括LogLevelMin、LogLevelMax和AcceptOnMatch,只有当log信息

的LogLevel在LogLevelMin、LogLevelMax之间同时AcceptOnMatch为true时才会匹配。

对StringMatchFilter来说,过滤条件包括StringToMatch和AcceptOnMatch,只有当log信息的LogLevel值

与StringToMatch对应的LogLevel值与相同, 且AcceptOnMatch为true时会匹配。

?

过滤条件处理机制类似于IPTABLE的Responsibility chain,(即先deny、再allow)不过执行顺序刚好相反,

后写的条件会被先执行,比如:

log4cplus.appender.append_1.filters.1=log4cplus::spi::LogLevelMatchFilter

log4cplus.appender.append_1.filters.1.LogLevelToMatch=TRACE

log4cplus.appender.append_1.filters.1.AcceptOnMatch=true

#log4cplus.appender.append_1.filters.2=log4cplus::spi::DenyAllFilter

会首先执行filters.2的过滤条件,关闭所有过滤器,然后执行filters.1,仅匹配TRACE信息。

(3)设置Layout

可以选择不设置、TTCCLayout、或PatternLayout

如果不设置,会输出简单格式的log信息。

设置TTCCLayout如下所示:

log4cplus.appender.ALL_MSGS.layout=log4cplus::TTCCLayout

设置PatternLayout如下所示:

log4cplus.appender.append_1.layout=log4cplus::PatternLayout

log4cplus.appender.append_1.layout.ConversionPattern=%d{%m/%d/%y %H:%M:%S,%Q} [%t] %-5p - %m%n

?

2.logger的配置语法

包括rootLogger和non-root logger。

对于rootLogger来说:

log4cplus.rootLogger=[LogLevel], appenderName, appenderName, ...

对于non-root logger来说:

log4cplus.logger.logger_name=[LogLevel|INHERITED], appenderName, appenderName, ...

?

脚本方式使用起来非常简单,只要首先加载配置即可(urconfig.properties是自行定义的配置文件):

PropertyConfigurator::doConfigure("urconfig.properties");

?

下面我们通过例子体会一下log4cplus强大的基于脚本过滤log信息的功能。

?

〖例8〗

/*

?* ? ?urconfig.properties

?*/

log4cplus.rootLogger=TRACE, ALL_MSGS, TRACE_MSGS, DEBUG_INFO_MSGS, FATAL_MSGS

log4cplus.appender.ALL_MSGS=log4cplus::RollingFileAppender

log4cplus.appender.ALL_MSGS.File=all_msgs.log

log4cplus.appender.ALL_MSGS.layout=log4cplus::TTCCLayout

log4cplus.appender.TRACE_MSGS=log4cplus::RollingFileAppender

log4cplus.appender.TRACE_MSGS.File=trace_msgs.log

log4cplus.appender.TRACE_MSGS.layout=log4cplus::TTCCLayout

log4cplus.appender.TRACE_MSGS.filters.1=log4cplus::spi::LogLevelMatchFilter

log4cplus.appender.TRACE_MSGS.filters.1.LogLevelToMatch=TRACE

log4cplus.appender.TRACE_MSGS.filters.1.AcceptOnMatch=true

log4cplus.appender.TRACE_MSGS.filters.2=log4cplus::spi::DenyAllFilter

log4cplus.appender.DEBUG_INFO_MSGS=log4cplus::RollingFileAppender

log4cplus.appender.DEBUG_INFO_MSGS.File=debug_info_msgs.log

log4cplus.appender.DEBUG_INFO_MSGS.layout=log4cplus::TTCCLayout

log4cplus.appender.DEBUG_INFO_MSGS.filters.1=log4cplus::spi::LogLevelRangeFilter

log4cplus.appender.DEBUG_INFO_MSGS.filters.1.LogLevelMin=DEBUG

log4cplus.appender.DEBUG_INFO_MSGS.filters.1.LogLevelMax=INFO

log4cplus.appender.DEBUG_INFO_MSGS.filters.1.AcceptOnMatch=true

log4cplus.appender.DEBUG_INFO_MSGS.filters.2=log4cplus::spi::DenyAllFilter

log4cplus.appender.FATAL_MSGS=log4cplus::RollingFileAppender

log4cplus.appender.FATAL_MSGS.File=fatal_msgs.log

log4cplus.appender.FATAL_MSGS.layout=log4cplus::TTCCLayout

log4cplus.appender.FATAL_MSGS.filters.1=log4cplus::spi::StringMatchFilter

log4cplus.appender.FATAL_MSGS.filters.1.StringToMatch=FATAL

log4cplus.appender.FATAL_MSGS.filters.1.AcceptOnMatch=true

log4cplus.appender.FATAL_MSGS.filters.2=log4cplus::spi::DenyAllFilter

?

/*

?* ? ?main.cpp

?*/

#include <log4cplus/logger.h>

#include <log4cplus/configurator.h>

#include <log4cplus/helpers/stringhelper.h>

using namespace log4cplus;

static Logger logger = Logger::getInstance("log");

void printDebug()

{

? ? LOG4CPLUS_TRACE_METHOD(logger, "::printDebug()");

? ? LOG4CPLUS_DEBUG(logger, "This is a DEBUG message");

? ? LOG4CPLUS_INFO(logger, "This is a INFO message");

? ? LOG4CPLUS_WARN(logger, "This is a WARN message");

? ? LOG4CPLUS_ERROR(logger, "This is a ERROR message");

? ? LOG4CPLUS_FATAL(logger, "This is a FATAL message");

}

int main()

{

? ? Logger root = Logger::getRoot();

? ? PropertyConfigurator::doConfigure("urconfig.properties");

? ? printDebug();

? ? return 0;

}

运行结果:

1. all_msgs.log

10-17-04 14:55:25,858 [1075298944] TRACE log <> - ENTER: ::printDebug()

10-17-04 14:55:25,871 [1075298944] DEBUG log <> - This is a DEBUG message

10-17-04 14:55:25,873 [1075298944] INFO log <> - This is a INFO message

10-17-04 14:55:25,873 [1075298944] WARN log <> - This is a WARN message

10-17-04 14:55:25,874 [1075298944] ERROR log <> - This is a ERROR message

10-17-04 14:55:25,874 [1075298944] FATAL log <> - This is a FATAL message

10-17-04 14:55:25,875 [1075298944] TRACE log <> - EXIT: ?::printDebug()

2. trace_msgs.log

10-17-04 14:55:25,858 [1075298944] TRACE log <> - ENTER: ::printDebug()

10-17-04 14:55:25,875 [1075298944] TRACE log <> - EXIT: ?::printDebug()

3. debug_info_msgs.log

10-17-04 14:55:25,871 [1075298944] DEBUG log <> - This is a DEBUG message

10-17-04 14:55:25,873 [1075298944] INFO log <> - This is a INFO message

4. fatal_msgs.log

10-17-04 14:55:25,874 [1075298944] FATAL log <> - This is a FATAL message

?

本部分详细介绍了如何有选择地控制log信息的输出,最后一部分我们将介绍一下多线程、

和C/S模式下该如何操作,顺便提一下NDC的概念。

热点排行