Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

Boost.Logとfluentdで始めるログ活用術

2,166 views

Published on

Boost.Logとfluentdで始めるログ活用術

Published in: Technology
  • Be the first to comment

Boost.Logとfluentdで始めるログ活用術

  1. 1. BOOST.LOGとFLUENTDで始めるログ活用術 Boost.勉強会#17@東京 Created by @termoshtt
  2. 2. 自己紹介 大学院生(D3) 専攻= 流体数理(物理+ 応用数学) シミュレーション= C++ データ解析= Python
  3. 3. CONTENTS fluentd : ログ収集のための共通基盤 Boost.Logの構成と使い方
  4. 4. WHY DO WE NEED LOG?
  5. 5. 一人で使う 時間のかかる処理の進捗 デバッグ
  6. 6. 人の書いたコードを使う FOR LIBRARIAN 問題が発生した事をユーザーに伝える 問題を解決するための情報を集める FOR USER 発生した状況の情報を得る 開発者に問題を解決してもらうために情報を提供する
  7. 7. つまり人が目視で確認する
  8. 8. FLUENTD ログを集約するための共通フォーマット リアルタイムにログを転送
  9. 9. FLUENTD 様々なログを収集するためのプラグイン apache syslog ... 様々なストレージに保存するためのプラグイン elasticsearch ...
  10. 10. FLUENTD 標準出力としてのfluentd UNIX的に解析ツールを組み合わせる事が可能
  11. 11. BOOST.LOGの使い方
  12. 12. BOOST.LOG フル機能のロギングライブラリ custom logger log filtering custom sink
  13. 13. ログの収集 名前空間/クラスにロガーを追加 namespace mod { namespace logging = boost::log; namespace log { namespace attrs = logging::attributes; namespace src = logging::sources; } using severity_level = logging::trivial::severity_level; BOOST_LOG_INLINE_GLOBAL_LOGGER_DEFAULT( logger, src::severity_logger_mt<severity_level>); void init(); } // namespace mod
  14. 14. ログの収集 ロガー毎に属性を付与 namespace mod { void init() { auto &lg = logger::get(); lg.add_attribute("Tag", log::attrs::make_constant("mod")); // lg.add_attribute("Tag", attrs::constant<std::string>("mod1")); lg.add_attribute("Scope", log::attrs::named_scope()); } } // namespace mod
  15. 15. ログの収集 属性のキーワードを登録 キーワードを用いて出力・フィルターを制御する BOOST_LOG_ATTRIBUTE_KEYWORD(line_id, "LineID", unsigned int) BOOST_LOG_ATTRIBUTE_KEYWORD(severity, "Severity", severity_level) BOOST_LOG_ATTRIBUTE_KEYWORD(tag_attr, "Tag", std::string) BOOST_LOG_ATTRIBUTE_KEYWORD(scope, "Scope", log::attrs::named_scope::value
  16. 16. ログの収集 出力時に情報を追加 namespace mod { void func() { BOOST_LOG_FUNCTION() // Scopeの値を設定(mod->func) auto &lg = logger::get(); if (flag) { BOOST_LOG_NAMED_SCOPE("true case"); // Scopeに入った事を記録する BOOST_LOG_SEV(lg, severity_level::info) << "flag is true"; } else { BOOST_LOG_NAMED_SCOPE("false case"); // Scopeに入った事を記録する BOOST_LOG_SEV(lg, severity_level::info) << "flag is false"; } BOOST_LOG_SEV(lg, severity_level::error) << "Some error occurs!!" } } // namespace mod
  17. 17. ログのフィルタリング placeholderを使用する logging::core::get()->set_filter( logging::trivial::severity >= logging::trivial::info // lambda-exp. );
  18. 18. ログのフィルタリング fluentd以降で解析する以上、C++側でフィルターする 意義はあまりない
  19. 19. ログの出力 様々な出力形式に対応 /* 文字列フォーマット */ logging::add_file_log( keywords::file_name = "client.log", keywords::format = "%Tag%: [%TimeStamp%] [%Scope%] %Message%" ); /* lambda-style */ logging::add_file_log( keywords::file_name = "stream_format.log", keywords::format = ( expr::stream << mod::tag_attr << mod::line_id << ": <" << mod::severity << "> [" << mod::scope << "] " << expr::smessage ) );
  20. 20. ログの出力 int main() { init(); // いろいろ初期化 mod1::func1(true); mod1::func1(false); return 0; } mod: [2015-Mar-04 01:38:57.711251] [void mod::func(bool)->true case mod: [2015-Mar-04 01:38:57.711620] [void mod::func(bool)] Some error occur mod: [2015-Mar-04 01:38:57.711667] [void mod::func(bool)->false case mod: [2015-Mar-04 01:38:57.711698] [void mod::func(bool)] Some error occur
  21. 21. ログの出力 どのようなフォーマットを使用するか? LTSV (Labeled Tab-Separated Values) damp/parseが簡単 属性を追加するのが簡単 型は無く、全て文字列 解析側で型を戻す必要がある JSON formatが少し面倒
  22. 22. ログの出力 typedef std::vector<std::pair<std::string, std::string> > Attrs; void add_file_log(std::string filename, const Attrs &attr, bool auto_flush std::stringstream ss; for (auto &&pair : attr) { const std::string &key = pair.first; const std::string &val = pair.second; if (!ss.str().empty()) ss << "t"; ss << key << ":%" << val << "%"; } logging::add_file_log( keywords::file_name = filename, keywords::format = ss.str(), keywords::auto_flush = auto_flush ); }
  23. 23. ログの出力 デバッグ時に属性を追加するのが簡単 BOOST_LOG_SEV(lg, KSE::info) << "update infost" << "new_max_index:" << max_index << "t" << "step:" << (t / interval) << "t" << "count:" << count;
  24. 24. COMPILE WITH CMAKE find_package(Boost COMPONENTS thread system log log_setup REQUIRED) find_package(Threads) add_definitions("-DBOOST_LOG_DYN_LINK") macro(logged_executable name) add_executable(${name} ${name}.cpp) target_link_libraries( ${name} ${Boost_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT} ${ARGN} ) endmacro(logged_executable)
  25. 25. 説明できなかった事 LTSVへの自動的なフォーマット channel fluentd側での解析例
  26. 26. BOOST.LOGを使いたい理由 Boostに入ってる 高機能 実行時のオーバーヘッドが小さい(未確認)
  27. 27. BOOST.LOGを使いたくない理由 placeholder難しい コンパイル遅い
  28. 28. THE END - Source codes (GitHub)

×