zoukankan      html  css  js  c++  java
  • Boost Log : Wide character logging

    Wide character logging

    Log库支持记录包含不同national characters的字符串。基本上有两种方法可以做到这一点。在类unix系统中,通常使用多字节字符编码(例如UTF-8)来表示national characters。在这种情况下,Log库可以像普通ASCII日志记录那样使用,不需要任何额外设置。

    在Windows上,常见的做法是使用宽字符串表示national characters。而且,大多数系统API都是面向宽字符的,这就要求特定于windows的sink也支持宽字符串。另一方面,通用sinks,比如文本文件sink,是面向字节的(因为,你将在文件中存储字节,而不是字符)。这将强制Log库在sink需要时执行字符代码转换。要为Log做这样的设置,必须使用带有适当codecvt方面的语言环境来设置sink。Boost.Locale可以用于生成这样的语言环境。让我们看一个例子:

    // Declare attribute keywords
    BOOST_LOG_ATTRIBUTE_KEYWORD(severity, "Severity", severity_level)
    BOOST_LOG_ATTRIBUTE_KEYWORD(timestamp, "TimeStamp", boost::posix_time::ptime)
    
    void init_logging()
    {
        boost::shared_ptr< sinks::synchronous_sink< sinks::text_file_backend > > sink = logging::add_file_log
        (
            "sample.log",
            keywords::format = expr::stream
                << expr::format_date_time(timestamp, "%Y-%m-%d, %H:%M:%S.%f")
                << " <" << severity.or_default(normal)
                << "> " << expr::message
        );
    
        // The sink will perform character code conversion as needed, according to the locale set with imbue()
        std::locale loc = boost::locale::generator()("en_US.UTF-8");
        sink->imbue(loc);
    
        // Let's add some commonly used attributes, like timestamp and record counter.
        logging::add_common_attributes();
    }
    

    首先,让我们看一下传入format参数的formatter。我们使用窄字符formatter初始化sink,因为文本文件sink处理字节。可以在formatter中使用宽字符串,但不能在格式字符串中使用,就像我们在format_date_time函数中使用的一样。还要注意,我们使用message关键字来表示log record消息。这个占位符支持窄字符和宽字符消息,所以formatter可以同时使用这两种消息。作为格式化过程的一部分,Log库将使用输入的语言环境(我们将其设置为UTF-8)将宽字符消息转换为多字节编码。

    Tip
    Attribute values也可以包含宽字符串。Log record消息一样,这些字符串将使用设置的语言环境转换为目标字符编码。

    这里缺少的一点是我们的severity_level类型定义。该类型只是一个枚举,但如果我们想要支持其窄格式和宽字符格式的sink,其stream操作符必须是模板。如果我们使用不同的字符类型创建多个sinks,这可能会很有用。

    enum severity_level
    {
        normal,
        notification,
        warning,
        error,
        critical
    };
    
    template< typename CharT, typename TraitsT >
    inline std::basic_ostream< CharT, TraitsT >& operator<< (
        std::basic_ostream< CharT, TraitsT >& strm, severity_level lvl)
    {
        static const char* const str[] =
        {
            "normal",
            "notification",
            "warning",
            "error",
            "critical"
        };
        if (static_cast< std::size_t >(lvl) < (sizeof(str) / sizeof(*str)))
            strm << str[lvl];
        else
            strm << static_cast< int >(lvl);
        return strm;
    }
    

    现在我们可以发出log records。我们可以使用带有w前缀的loggers来组成宽字符消息。

    void test_narrow_char_logging()
    {
        // Narrow character logging still works
        src::logger lg;
        BOOST_LOG(lg) << "Hello, World! This is a narrow character message.";
    }
    
    void test_wide_char_logging()
    {
        src::wlogger lg;
        BOOST_LOG(lg) << L"Hello, World! This is a wide character message.";
    
        // National characters are also supported
        const wchar_t national_chars[] = { 0x041f, 0x0440, 0x0438, 0x0432, 0x0435, 0x0442, L',', L' ', 0x043c, 0x0438, 0x0440, L'!', 0 };
        BOOST_LOG(lg) << national_chars;
    
        // Now, let's try logging with severity
        src::wseverity_logger< severity_level > slg;
        BOOST_LOG_SEV(slg, normal) << L"A normal severity message, will not pass to the file";
        BOOST_LOG_SEV(slg, warning) << L"A warning severity message, will pass to the file";
        BOOST_LOG_SEV(slg, error) << L"An error severity message, will pass to the file";
    }
    

    如您所见,宽字符消息组合类似于窄日志记录。注意,您可以同时使用窄字符和宽字符日志;所有记录将由我们的文件sink处理。这个示例的完整代码可以在这里找到。

    必须注意的是,有些sinks(大部分是特定于windows的)允许指定目标字符类型。当日志记录中需要使用national characters时,应该始终使用wchar_t作为目标字符类型,因为sink将使用宽字符OS API来处理log records。在这种情况下,当执行格式化时,所有窄字符字符串都将使用嵌入到sink中的locale进行加宽。

  • 相关阅读:
    JavaScript 各种遍历方式详解
    使用TortoiseGit操作分支的创建与合并
    前端实现图片压缩上传
    改变input的value值,同时在HTML中将value进行改变
    HTML中字体单位px pt em之间的转换
    解决PHP无法接收post超过1000个字段的问题
    解决微信不能扫描下载的问题
    实现类似于百度实时搜索将结果在下拉框中显示的功能
    Python导入路径含特殊字符的包
    大二秋学期记录
  • 原文地址:https://www.cnblogs.com/kohlrabi/p/9160494.html
Copyright © 2011-2022 走看看