现在的位置: 首页 > 综合 > 正文

POCO库的Logging framework

2018年05月08日 ⁄ 综合 ⁄ 共 2248字 ⁄ 字号 评论关闭

纪念下我曾经的一句名言:需求是软件开发的根本准则。

Logging architecture

 

需求一:记录需要包含的内容?消息的内容、消息生成的时间和地点、消息的重要性。

这些东西都有Message对象来描述。一条记录就是一个Message对象。Message对象非常像一个装饰模式,TextMessage的内容,Message中的其它属性是对Text的装饰(或者用描述更确切点):

Priority——消息的优先级

Source——生成消息的地方

Timestamp——生成消息的时间

Process&threadidentifier——生成消息的进程ID和线程ID

OptionalParameter (name value pair )——附加参数,主要用于格式化消息

 

需求二:当拥有了大量的消息之后,如何高效的管理这些消息?比如,根据消息的优先级过滤掉某些较低优先级的消息,或者快速地找到生成消息的地方等。

Logger类负责记录消息,并且根据自身的level,可以忽略一些不是很重要的消息。一个Logger只记录一个地点上生成的消息,比如,一个Logger记录一个类上生成的消息。我们都知道类是有继承结构的,为了更好地配合这种结构,Poco给我们提供了一个Logger工厂方法get()来创建Logger。由它创建的Logger,可以很容易地生成另外一个继承层次,如下图

创建这个继承结构,Logger::get()方法为用户做了大部分工作。使用者只需要制定合理的Logger名字,Logger::get()方法就能为我们生成这个结构。通过一个句点(.),来分离父亲和孩子,左边是父亲右边是孩子。比如,HTTPServerHTTPServer.Listener。这样,HTTPServer.Listener就具有了与其父亲HTTPServer相同的配置。这个配置主要是后面会讲到的Channel

 

需求三:由Logger记录的消息该输出到什么地方?标准输出?文件?还是应用程序的某个窗口上?或者是。。。

        这部分工作是由Channel来完成的。Channel的接口非常简单,只有一个log()Log方法负责将消息输出到消息该去的地方。Poco提供了很多现成的Channel,比如ConsoleChannel(默认将消息输出到std::clog,也可以将其输出到std::out),FileChannel将消息输出到一个文件中。

 

需求四:如何格式化输出消息?比如,仅仅输出消息的内容,还是需要输出消息的其它附加内容,比如timestampprocess
id
等。

        原理就是在由Channel输出消息之前,让消息先通过Formater格式化后再通过Channel输出。FormattingChannel类的作用有点类似proxy模式,它一方面调用了Channel的方法,不过在调用Channel的方法之前,先让消息流过Formatter了。

#include "Poco/AutoPtr.h"
#include "Poco/Logger.h"
#include "Poco/ConsoleChannel.h"
#include "Poco/LogStream.h"
#include "Poco/PatternFormatter.h"
#include "Poco/FileChannel.h"
#include "Poco/FormattingChannel.h"

int main()
{

	Poco::AutoPtr<Poco::Channel> channel;
	{
		Poco::AutoPtr<Poco::Channel> fileChannel(new Poco::FileChannel());
		fileChannel->setProperty("path", "sample.log");
		fileChannel->setProperty("archive", "timestamp");
		fileChannel->setProperty("compress", "true");

		Poco::AutoPtr<Poco::PatternFormatter> patternFormatter(new Poco::PatternFormatter());
		patternFormatter->setProperty("pattern", "%H:%M:%S:%i %s(%l): %t");
		channel = new Poco::FormattingChannel(patternFormatter, fileChannel);
	}
	

	Poco::Logger::root().setChannel(channel.get());
	Poco::Logger& logger = Poco::Logger::get("LoggerTest");
	Poco::LogStream ls(logger);
	ls.trace() << "This is a trace." << std::endl;
	ls.warning() << "This is a warning." << std::endl;
	ls.error() << "This is a error" << std::endl;
	return 0;
}

上面程序的输出结果:在文件sample.log中的内容为:

00:19:52:359 LoggerTest(4): This is a warning.
00:19:52:390 LoggerTest(3): This is a error

抱歉!评论已关闭.