公式ドキュメントの補足
BOOST_LOG_INLINE_GLOBAL_LOGGER(type_name, source_type)
BOOST_LOG_INLINE_GLOBAL_LOGGER_CTOR_ARGS(type_name, source_type, ctor-arguments)
これはtype_nameという名前のクラスを生成するマクロであるから名前空間を使えば下記のようなことができる.
BOOST_LOG_INLINE_GLOBAL_LOGGER_CTOR_ARGS(type_name, source_type, ctor-arguments)
BOOST_LOG_INLINE_GLOBAL_LOGGER(global_logger, boost::log::sources::logger)
BOOST_LOG_INLINE_GLOBAL_LOGGER_CTOR_ARGS(global_channel_logger, boost::log::sources::channel_logger<>, (boost::log::keywords = "channel"))
void func()
{
BOOST_LOG(global_logger::get()) << "Logging by using global_logger";
BOOST_LOG(global_channel_logger::get()) << "Logging by using global_channel_logger";
}
これはtype_nameという名前のクラスを生成するマクロであるから名前空間を使えば下記のようなことができる.
namespace A {
BOOST_LOG_INLINE_GLOBAL_LOGGER_CTOR_ARGS(logger, boost::log::channel_logger<>, (boost::log::keywords = "namespace A"));
void func() {
BOOST_LOG(logger::get()) << "Message from namespace A";
}
}
namespace B {
BOOST_LOG_INLINE_GLOBAL_LOGGER_CTOR_ARGS(logger, boost::log::channel_logger<>, (boost::log::keywords = "namespace B"));
void func() {
BOOST_LOG(logger::get()) << "Message from namespace B";
}
}
MSVCでNamed Scope属性を使うときに,BOOST_LOG_FUNCTIONは機能しない(boost/current_function.hppがなぜか実装していない)ため,下記のように書けばよい.
BOOST_NAMED_SCOPE(__FUNCTION__)
予め定義してある属性は概ね下記の通り.
| attribute_name | type | description |
|---|---|---|
| "Severity" | enum | |
| "Channel" | string | |
| "Scope" | named_scope_list | named_scope_entryの階層リスト.frontが浅層,backが深層. |
| named_scope_entry | スコープ名,ファイル名,行番号を保有する構造体. BOOST_LOG_FUNCTION, BOOST_NAMED_SCOPEで記録される. | |
| "Message" | string wstring | logger系はstringを,wlogger系はwstringでデータをセットする. |
record_viewから各属性値を取り出す.
| type | description |
|---|---|
| attribute_value_set | 属性の文字列リテラルとattribute_valueのmap |
| attribute_value | 属性値の入れ物.extract<type>()で取り出しを試みる.戻り値はoptional. |
class attribute_extraction_sink_backend : public sinks::basic_sink_backend<sinks::synchronized_feeding>
{
public:
void consume(logging::record_view const& rec);
}
void attribute_extraction_sink_backend::consume(logging::record_view const& rec)
{
int sev;
std::string ch;
std::string deepest_scope_name; // extract the deepest scope
std::string file_name;
unsigned int line_number;
std::string message;
auto& attr_val_set = rec.attribute_values();
{
auto& mapped_value = attr_val_set["Severity"];
if (mapped_value) sev = mapped_value.extract<severity_level>().get();
}
{
auto& mapped_value = attr_val_set["Channel"];
if (mapped_value) ch = mapped_value.extract<string>().get();
}
{
auto& mapped_value = attr_val_set["Scope"];
if (mapped_value)
{
auto scope_list = mapped_value.extract<named_scope_list>();
if (scope_list && scope_list.size())
{
auto deepest_scope = scope_list.back();
deepest_scope_name = deepest_scope.scope_name;
file_name = deepest_scope.file_name;
line_number = deepest_scope.line;
}
}
}
{
auto& mapped_value = attr_val_set["Message"];
if (mapped_value)
{
if(auto try_string = mapped_value.extract<string>())
{
message = try_string.get();
}
else if(auto try_wstring = mapped_value.extract<wstring>())
{
auto wessage = try_wstring.get();
// 環境に適合した方法でwstringからstringに変換する
}
}
}
}
例えばReleaseビルドではストリームでの処理が無駄なのでsinkで見えないようにするだけでなくdebugログをそもそも行わないように設定したい.
通常のBOOST_LOG_SEVでロギングすればよい.
enum severity_level { Debug, Info, Warning, Error, Fatal }
class severity_filtering_logger : public basic_composite_logger<char, severity_logger<severity_level>, single_thread_model, features<severity<severity_level>>>
{
typedef basic_composite_logger<char, severity_logger<severity_level>, single_thread_model, features<severity<severity_level>>> base;
public:
BOOST_LOG_FORWARD_LOGGER_MEMBERS_TEMPLATE(severity_filtering_logger);
template< typename ArgsT >
boost::log::record open_record(ArgsT const& args)
{
if (args[boost::log::keywords::severity | base::default_severity()] < filtering_level) return boost::log::record();
return base::open_record(args);
}
inline severity_level get_filtering_level() const { return filtering_level; }
inline void set_filtering_level(severity_level val) { filtering_level = val; }
private:
severity_level filtering_level = severity_level::Info;
};
// sample
severity_filtering_logger logger;
BOOST_LOG_SEV(logger, severity_level::info) << "Info"; // 表示される
BOOST_LOG_SEV(logger, severity_level::debug) << "Debug"; // 表示されない
通常のBOOST_LOG_SEVでロギングすればよい.
#大きな勘違いをしていたため修正
下記が必要.これはboost.logに関係なくcout, wcoutでも必要.
sink->imbueは必要ない.
補足
は同一ではない.
なお,C++11から導入されたUnicode String Literalはvs2013(c120), 2013 Nov CTP共に未実装である.
下記が必要.これはboost.logに関係なくcout, wcoutでも必要.
sink->imbueは必要ない.
std::locale::global("japanese_japan.932");
補足
- テキストファイルとしてのソースの文字コード
- プログラムとしてchar文字列リテラルの文字コード
は同一ではない.
なお,C++11から導入されたUnicode String Literalはvs2013(c120), 2013 Nov CTP共に未実装である.

コメントをかく