Poco::NestedDiagnosticContext を紹介します。
“Pattern Languages of Program Design 3” (Addison-Wesley) の Neil Harrison の “Patterns for Logging Diagnostic Messages” で述べられている Nested Diagnostic Context (NDC) の実装です。
NDC は、method 名とソースコード行番号、ファイル名で構成されるコンテキスト情報を保持します。
全ての thread は、自分自身の NDC を持ち、必要とされる時生成され、thread 終了時に破棄されます。
スコープ開始時に情報を push し、スコープ終了時に pop するように、Poco::NDCScope を使うことができます。マクロ poco_ndc(info) で登録すると、ソースコード行番号、ファイル名も共に記録されます。
NestedDiagnosticContextTest.cpp
・スレッドを3つ作り、再帰的に呼ぶ回数を変えつつ、それぞれのスレッドで TestFunction() を呼び、
NDC の内容を表示。
・比較用に main スレッドでも poco_ndc(main) をコールし、内容を表示。
・今回は Debug/Release 両ビルドで同じ出力にしたかったので poco_ndc() を呼んだが、本来の使い方
としては poco_ndc_dbg() を呼んで、Relase ビルドでは出さないようにするべき。
#include <Poco/NestedDiagnosticContext.h> #include <Poco/Runnable.h> #include <Poco/Thread.h> #include <Poco/Format.h> #include <sstream> #include "ScopedLogMessage.h" #include "PrepareConsoleLogger.h" const std::size_t kNumThreads = 3; void DumpNDCMessage(ScopedLogMessage& msg) { std::ostringstream sstr; Poco::NDC::current().dump(sstr); msg.Message(Poco::format( "\n- Poco::NDC::current().depth() : %d" "\n- Poco::NDC::current().toString() :\n%s" "\n- Poco::NDC::current().dump() :\n%s" , Poco::NDC::current().depth() , Poco::NDC::current().toString() , sstr.str())); } void TestFunction(ScopedLogMessage& msg, std::size_t i) { poco_ndc(TestFunction); if(0 == i) { DumpNDCMessage(msg); } else { TestFunction(msg, --i); } } class MyRunnable: public Poco::Runnable { public: MyRunnable() : m_pMsg(NULL) , m_funcDepth(0) { } void setDepth(ScopedLogMessage* pMsg, std::size_t depth) { m_pMsg = pMsg; m_funcDepth = depth; } void run() { poco_ndc(run); if(NULL != m_pMsg) { TestFunction(*m_pMsg, m_funcDepth); } } private: ScopedLogMessage* m_pMsg; std::size_t m_funcDepth; }; int main(int /*argc*/, char** /*argv*/) { PrepareConsoleLogger logger(Poco::Logger::ROOT, Poco::Message::PRIO_INFORMATION); ScopedLogMessage msg("NestedDiagnosticContextTest ", "start", "end"); poco_ndc(main); Poco::Thread thread[kNumThreads]; MyRunnable r[kNumThreads]; for(std::size_t i=0; i<kNumThreads; ++i) { r[i].setDepth(&msg, i); thread[i].start(r[i]); } Poco::Thread::sleep(200); for(std::size_t i=0; i<kNumThreads; ++i) { thread[i].join(); } DumpNDCMessage(msg); return 0; } |
Results of execution
[0] NestedDiagnosticContextTest start [1] - Poco::NDC::current().depth() : 2 - Poco::NDC::current().toString() : run:TestFunction - Poco::NDC::current().dump() : run (in "NestedDiagnosticContextTest.cpp", line 98) TestFunction (in "NestedDiagnosticContextTest.cpp", line 66) [2] - Poco::NDC::current().depth() : 3 - Poco::NDC::current().toString() : run:TestFunction:TestFunction - Poco::NDC::current().dump() : run (in "NestedDiagnosticContextTest.cpp", line 98) TestFunction (in "NestedDiagnosticContextTest.cpp", line 66) TestFunction (in "NestedDiagnosticContextTest.cpp", line 66) [3] - Poco::NDC::current().depth() : 4 - Poco::NDC::current().toString() : run:TestFunction:TestFunction:TestFunction - Poco::NDC::current().dump() : run (in "NestedDiagnosticContextTest.cpp", line 98) TestFunction (in "NestedDiagnosticContextTest.cpp", line 66) TestFunction (in "NestedDiagnosticContextTest.cpp", line 66) TestFunction (in "NestedDiagnosticContextTest.cpp", line 66) [0] - Poco::NDC::current().depth() : 1 - Poco::NDC::current().toString() : main - Poco::NDC::current().dump() : main (in "NestedDiagnosticContextTest.cpp", line 132) [0] NestedDiagnosticContextTest end |
Downloads
・ここをクリックすると、makefile や VC++ プロジェクトなど一式がダウンロードできます。
(2013.05.31 updated)
・2010年6月23日からのダウンロード数:1117
Subversion
・フリーの Subversion ホスティングサービス Assemblaで、ソースコードを管理しています。
![]() |
Copyright © 2010 Round Square Inc. All rights reserved. |
---|
0 Comments.