Boost宽字符日志
简 介
- 日志库支持含有与国家有关字符的字符串。如中文、日文
- 两种实现方法:多字节字符、宽字符
- Windows常用宽字符串来表示与国家有关的字符,大多数系统API都是面向宽字符的
- 这要求Windows专有的槽要支持宽字符串
- 通用槽(如文本文件槽)是面向字节的,这将强制日志库在槽需要时执行字符代码转换
- 要执行转换必须为输出槽设置一个具有适当编解码器构面(codecvt facet)的语言环境(locale)
- Boost.Locale 可用于生成这样的语言环境
示 例
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
);
std::locale loc = boost::locale::generator()("en_US.UTF-8");
sink->imbue(loc);
logging::add_common_attributes();
}
- message关键字同时支持宽窄字符
- 日志库将使用注入的语言环境将宽字符消息转换为多字节编码UTF-8
- 若日志属性值使用宽字符也会进行转换
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;
}
- 与严重等级相关联的<<重载函数要支持宽窄字符就必须是模板
示例
#include <iostream>
#include <boost/locale/generator.hpp>
#include <boost/date_time/posix_time/posix_time_types.hpp>
#include <boost/log/common.hpp>
#include <boost/log/expressions.hpp>
#include <boost/log/utility/setup/file.hpp>
#include <boost/log/utility/setup/console.hpp>
#include <boost/log/utility/setup/common_attributes.hpp>
#include <boost/log/sources/logger.hpp>
#include <boost/log/support/date_time.hpp>
namespace logging = boost::log;
namespace sinks = boost::log::sinks;
namespace attrs = boost::log::attributes;
namespace src = boost::log::sources;
namespace expr = boost::log::expressions;
namespace keywords = boost::log::keywords;
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;
}
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
);
std::locale loc = boost::locale::generator()("en_US.UTF-8");
sink->imbue(loc);
logging::add_common_attributes();
}
void test_narrow_char_logging()
{
src::logger lg;
BOOST_LOG(lg) << "Narrow character message";
}
void test_wide_char_logging()
{
src::wlogger lg;
BOOST_LOG(lg) << L"Wide character message";
const wchar_t chinese_chars[] = { 0x5BBD, 0x5B57, 0x7B26, 0 };
BOOST_LOG(lg) << chinese_chars;
src::wseverity_logger< severity_level > slg;
BOOST_LOG_SEV(slg, normal) << L"A normal severity message";
BOOST_LOG_SEV(slg, warning) << L"A warning severity message";
BOOST_LOG_SEV(slg, error) << L"An error severity message";
}
int main(int argc, char* argv[])
{
init_logging();
test_narrow_char_logging();
test_wide_char_logging();
return 0;
}