标签:过程 time函数 操作符 strong 示例 有用 rds 函数 hello
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进行加宽。
Boost Log : Wide character logging
标签:过程 time函数 操作符 strong 示例 有用 rds 函数 hello
原文地址:https://www.cnblogs.com/kohlrabi/p/9160494.html