Poco::Logger

後日スレッド関係の例を載せるつもりなので、それに備えて、まずはスレッドセーフなコンソールログ出力のクラスを紹介します。

class ScopedLogMessage

ScopedLogMessage.h

PImpl イディオム(pointer to implementation idiom)を使用し、ファイルの依存関係を削減。

#include <string>
#include <memory>
 
class ScopedLogMessage
{
public:
	ScopedLogMessage(	const std::string& commonMsg,
				const std::string& startMsg,
				const std::string& endMsg);
	~ScopedLogMessage();
	void Message(const std::string& msg) const;
 
private:
	ScopedLogMessage();
	ScopedLogMessage(const ScopedLogMessage&);
	ScopedLogMessage& operator = (const ScopedLogMessage&);
 
	class ScopedLogMessageImpl;
	std::auto_ptr<ScopedLogMessageImpl>	m_pImpl;
};

ScopedLogMessage.cpp

RAII イディオムを使い、コンストラクタで開始ログを、デストラクタで終了ログを出す。
・後に紹介する Poco::Util::ServerApplication 内で生成される Poco::Logger インスタンスの名称と同じ、
 Poco::Logger::ROOT を使う。
・マルチスレッドの時用に、スレッドIDも表示。

#include "ScopedLogMessage.h"
 
#include <Poco/Logger.h>
#include <Poco/Thread.h>
#include <Poco/Format.h>
 
class ScopedLogMessage::ScopedLogMessageImpl
{
public:
	ScopedLogMessageImpl(	const std::string& commonMsg,
				const std::string& startMsg,
				const std::string& endMsg) :
		m_endMsg	(commonMsg + endMsg)
	{
		Poco::Logger::get(Poco::Logger::ROOT).information(
				ThreadIDString() + commonMsg + startMsg );
	}
	~ScopedLogMessageImpl()
	{
		Poco::Logger::get(Poco::Logger::ROOT).information(
				ThreadIDString() + m_endMsg );
	}
	void Message(const std::string& msg) const
	{
		Poco::Logger::get(Poco::Logger::ROOT).information(
				ThreadIDString() + msg );
	}
private:
	ScopedLogMessageImpl();
	ScopedLogMessageImpl(const ScopedLogMessageImpl&);
	ScopedLogMessageImpl& operator = (const ScopedLogMessageImpl&);
 
	int GetThreadID(void) const
	{
		Poco::Thread* p_thread = Poco::Thread::current();
		return (0 == p_thread) ? 0:p_thread->id();
	}
	std::string ThreadIDString(void) const
	{
		return Poco::format("[%d] ", GetThreadID());
	}
 
	const std::string	m_endMsg;
};
 
ScopedLogMessage::ScopedLogMessage(	const std::string& commonMsg,
					const std::string& startMsg,
					const std::string& endMsg) :
	m_pImpl(new ScopedLogMessageImpl(commonMsg, startMsg, endMsg))
{
}
 
ScopedLogMessage::~ScopedLogMessage()
{
}
 
void ScopedLogMessage::Message(const std::string& msg) const
{
	m_pImpl->Message(msg);
}

class PrepareConsoleLogger

PrepareConsoleLogger.h

#include <string>
 
#include <Poco/AutoPtr.h>
#include <Poco/ConsoleChannel.h>
#include <Poco/PatternFormatter.h>
#include <Poco/FormattingChannel.h>
#include <Poco/Logger.h>
 
class PrepareConsoleLogger
{
public:
	PrepareConsoleLogger(const std::string& name, int level=Poco::Message::PRIO_INFORMATION);
	~PrepareConsoleLogger();
 
private:
	PrepareConsoleLogger();
	PrepareConsoleLogger(const PrepareConsoleLogger&);
	PrepareConsoleLogger& operator = (const PrepareConsoleLogger&);
 
	const std::string						m_name;
	Poco::AutoPtr<Poco::ConsoleChannel>		m_pConsoleChannel;
	Poco::AutoPtr<Poco::PatternFormatter>	m_pTextFormatter;
	Poco::AutoPtr<Poco::FormattingChannel>	m_pFCConsole;
};

PrepareConsoleLogger.cpp

RAII イディオムを使い、コンストラクタでPoco::Loggerを作成し、デストラクタで削除。

#include "PrepareConsoleLogger.h"
 
PrepareConsoleLogger::PrepareConsoleLogger(const std::string& name, int level) :
	m_name				(name)
,	m_pConsoleChannel	(new Poco::ConsoleChannel)
,	m_pTextFormatter	(new Poco::PatternFormatter("%t"))
,	m_pFCConsole		(new Poco::FormattingChannel(m_pTextFormatter))
{
	m_pFCConsole->setChannel(m_pConsoleChannel);
	m_pFCConsole->open();
 
	Poco::Logger::create(m_name, m_pFCConsole, level);
}
 
PrepareConsoleLogger::~PrepareConsoleLogger()
{
	Poco::Logger::destroy(m_name);
 
	m_pFCConsole->close();
}

ScopedLogMessageTest.cpp

Poco::Logger::ROOT という名称で Poco::ConsoleChannelPoco::Message::PRIO_INFORMATION 以上
 のログを出す Poco::Logger を生成し、ScopedLogMessage を呼ぶ。

#include "PrepareConsoleLogger.h"
#include "ScopedLogMessage.h"
 
int main(int /*argc*/, char** /*argv*/)
{
	PrepareConsoleLogger logger(Poco::Logger::ROOT, Poco::Message::PRIO_INFORMATION);
 
	ScopedLogMessage msg("ScopedLogMessage ", "start", "end");
 
	msg.Message("  doing something...");
 
	return 0;
}

Results of execution

・全てメインスレッドでログ出力。

[0] ScopedLogMessage start
[0]   doing something...
[0] ScopedLogMessage end

Downloads

ここをクリックすると、makefile や VC++ プロジェクトなど一式がダウンロードできます。
(2013.05.31 updated)
・2010年4月20日からのダウンロード数:1004

Subversion

・フリーの Subversion ホスティングサービス Assemblaで、ソースコードを管理しています。

Reference

5分で使えるLoggingフレームワーク – POCO::Foundation –
2. ロギングフレームワークの使い方
http://pocoproject.org にある Logging のプレセンテーション。(PDF)

Powered by POCO Copyright © 2010 Round Square Inc. All rights reserved.


Leave a Comment


NOTE - You can use these HTML tags and attributes:
<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>