码迷,mamicode.com
首页 > 其他好文 > 详细

boost.log(八)宽字符记录

时间:2015-05-08 12:46:54      阅读:866      评论:0      收藏:0      [点我收藏+]

标签:

宽字符记录

    Boost.Log支持包含本地字符集字符串的日志记录。基本上有两种方式做这件事。在 UNIX 系统上通常使用一些多字节字符编码 (例如 UTF-8) 用来表示本地字符。在这种情况下,Boost.Log库可以直接以纯 ASCII 的方式记录而不需要其它额外的设置。

    在Windows 上常见的做法是使用宽字符串来表示本地字符串。此外大多数系统 API 也是使用的宽字符,这需要特定于 Windows 的接收器也支持宽字符。另一方面,通用的接收器,例如 TextFile,是面向字节的,你写入文件的是字节,而不是字符。这迫使Boost.Log库进行字符编码转换时需要通过接收器。在接收器上指定合适的区域设置,Boost.Locale 可以用于生成这种区域设置。让我们看看一个例子:
  1. // Declare attribute keywords
  2. BOOST_LOG_ATTRIBUTE_KEYWORD(severity, "Severity", severity_level)
  3. BOOST_LOG_ATTRIBUTE_KEYWORD(timestamp, "TimeStamp", boost::posix_time::ptime)
  4. void init_logging()
  5. {
  6. boost::shared_ptr< sinks::synchronous_sink< sinks::text_file_backend > > sink = logging::add_file_log
  7. national characters (
  8. "sample.log",
  9. keywords::format = expr::stream
  10. << expr::format_date_time(timestamp, "%Y-%m-%d, %H:%M:%S.%f")
  11. << " <" << severity.or_default(normal)
  12. << "> " << expr::message
  13. );
  14. // The sink will perform character code conversion as needed, according to the locale set with imbue()
  15. std::locale loc = boost::locale::generator()("en_US.UTF-8");
  16. sink->imbue(loc);
  17. // Let‘s add some commonly used attributes, like timestamp and record counter.
  18. logging::add_common_attributes();
  19. }
    首先让我们看看传入格式化器中的格式参数,我们初始化一个非宽字符格式化器的接收器,因为文本文件接收处理的是字节。可以在格式化器中使用宽字符串,但不是在格式字符串,就像我们使用的format_date_time函数"%Y-%m-%d, %H:%M:%S.%f"不能是宽字符。另外请注意,我们使用的 message 关键字来表示日志记录信息。此占位符支持非宽字符和宽字符的信息,所以格式化器将使用两者。作为格式的过程的一部分Boost.Log库将转换为宽字符消息使用了多字节的区域编码我们设置为UTF-8。

[提示]属性值也可以包含宽字符串。像日志记录的消息,这些字符串将被转换以imbued locale为目标的字符编码。

在这里我们缺少severity_level类型定义。类型仅仅是一个枚举,但如果我们想要其格式支持宽和非宽字符的接收器,就需要对它<<运算符重载模板函数进行特化了
  1. enum severity_level
  2. {
  3. normal,
  4. notification,
  5. warning,
  6. error,
  7. critical
  8. };
  9. template< typename CharT, typename TraitsT >
  10. inline std::basic_ostream< CharT, TraitsT >& operator<< (
  11. std::basic_ostream< CharT, TraitsT >& strm, severity_level lvl)
  12. {
  13. static const char* const str[] =
  14. {
  15. "normal",
  16. "notification",
  17. "warning",
  18. "error",
  19. "critical"
  20. };
  21. if (static_cast< std::size_t >(lvl) < (sizeof(str) / sizeof(*str)))
  22. strm << str[lvl];
  23. else
  24. strm << static_cast< int >(lvl);
  25. return strm;
  26. }

现在我们可以发出消息了,但是必须要用 "w" 为前缀的记录器来撰写消息记录。
  1. void test_narrow_char_logging()
  2. {
  3. // Narrow character logging still works
  4. src::logger lg;
  5. BOOST_LOG(lg) << "Hello, World! This is a narrow character message.";
  6. }
  7. void test_wide_char_logging()
  8. {
  9. src::wlogger lg;
  10. BOOST_LOG(lg) << L"Hello, World! This is a wide character message.";
  11. // National characters are also supported
  12. const wchar_t national_chars[] = { 0x041f, 0x0440, 0x0438, 0x0432, 0x0435, 0x0442, L‘,‘, L‘ ‘, 0x043c, 0x0438, 0x0440, L‘!‘, 0 };
  13. BOOST_LOG(lg) << national_chars;
  14. // Now, let‘s try logging with severity
  15. src::wseverity_logger< severity_level > slg;
  16. BOOST_LOG_SEV(slg, normal) << L"A normal severity message, will not pass to the file";
  17. BOOST_LOG_SEV(slg, warning) << L"A warning severity message, will pass to the file";
  18. BOOST_LOG_SEV(slg, error) << L"An error severity message, will pass to the file";
  19. }
    正如你所看到的,宽字符消息组成类似于非宽字符消息。请注意,您可以在同一时间同时使用宽和非字符记录,所有记录都将通过我们文件接收器进行处理。这个例子的完整代码可以在这里找到。

    必须指出的是一些接收器(主要是Windows特定的)允许指定目标的字符类型。如果期望使用本地字符写日志记录,应始终使用 wchar_t 作为目标字符类型。因为接收器将采用宽字符的操作系统API来处理日志记录。

boost.log(八)宽字符记录

标签:

原文地址:http://www.cnblogs.com/zhangpanyi/p/4487269.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!