1<html> 2<head> 3<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> 4<title>Wide character logging</title> 5<link rel="stylesheet" href="../../../../../../doc/src/boostbook.css" type="text/css"> 6<meta name="generator" content="DocBook XSL Stylesheets V1.79.1"> 7<link rel="home" href="../../index.html" title="Chapter 1. Boost.Log v2"> 8<link rel="up" href="../tutorial.html" title="Tutorial"> 9<link rel="prev" href="advanced_filtering.html" title="Filtering revisited"> 10<link rel="next" href="../detailed.html" title="Detailed features description"> 11</head> 12<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"> 13<table cellpadding="2" width="100%"><tr><td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../../../../boost.png"></td></tr></table> 14<hr> 15<div class="spirit-nav"> 16<a accesskey="p" href="advanced_filtering.html"><img src="../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../tutorial.html"><img src="../../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../../index.html"><img src="../../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="../detailed.html"><img src="../../../../../../doc/src/images/next.png" alt="Next"></a> 17</div> 18<div class="section"> 19<div class="titlepage"><div><div><h3 class="title"> 20<a name="log.tutorial.wide_char"></a><a class="link" href="wide_char.html" title="Wide character logging">Wide character logging</a> 21</h3></div></div></div> 22<p> 23 The library supports logging strings containing national characters. There 24 are basically two ways of doing this. On UNIX-like systems typically some 25 multibyte character encoding (e.g. UTF-8) is used to represent national characters. 26 In this case the library can be used just the way it is used for plain ASCII 27 logging, no additional setup is required. 28 </p> 29<p> 30 On Windows the common practice is to use wide strings to represent national 31 characters. Also, most of the system API is wide character oriented, which 32 requires Windows-specific sinks to also support wide strings. On the other 33 hand, generic sinks, like the <a class="link" href="../detailed/sink_backends.html#log.detailed.sink_backends.text_file" title="Text file backend">text 34 file sink</a>, are byte-oriented (because, well, you store bytes in files, 35 not characters). This forces the library to perform character code conversion 36 when needed by the sink. To set up the library for this one has to imbue 37 the sink with a locale with the appropriate <code class="computeroutput"><span class="identifier">codecvt</span></code> 38 facet. <a href="http://www.boost.org/doc/libs/release/libs/locale/doc/html/index.html" target="_top">Boost.Locale</a> 39 can be used to generate such a locale. Let's see an example: 40 </p> 41<p> 42</p> 43<pre class="programlisting"><span class="comment">// Declare attribute keywords</span> 44<span class="identifier">BOOST_LOG_ATTRIBUTE_KEYWORD</span><span class="special">(</span><span class="identifier">severity</span><span class="special">,</span> <span class="string">"Severity"</span><span class="special">,</span> <span class="identifier">severity_level</span><span class="special">)</span> 45<span class="identifier">BOOST_LOG_ATTRIBUTE_KEYWORD</span><span class="special">(</span><span class="identifier">timestamp</span><span class="special">,</span> <span class="string">"TimeStamp"</span><span class="special">,</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">posix_time</span><span class="special">::</span><span class="identifier">ptime</span><span class="special">)</span> 46 47<span class="keyword">void</span> <span class="identifier">init_logging</span><span class="special">()</span> 48<span class="special">{</span> 49 <span class="identifier">boost</span><span class="special">::</span><span class="identifier">shared_ptr</span><span class="special"><</span> <span class="identifier">sinks</span><span class="special">::</span><span class="identifier">synchronous_sink</span><span class="special"><</span> <span class="identifier">sinks</span><span class="special">::</span><span class="identifier">text_file_backend</span> <span class="special">></span> <span class="special">></span> <span class="identifier">sink</span> <span class="special">=</span> <span class="identifier">logging</span><span class="special">::</span><span class="identifier">add_file_log</span> 50 <span class="special">(</span> 51 <span class="string">"sample.log"</span><span class="special">,</span> 52 <span class="identifier">keywords</span><span class="special">::</span><span class="identifier">format</span> <span class="special">=</span> <span class="identifier">expr</span><span class="special">::</span><span class="identifier">stream</span> 53 <span class="special"><<</span> <span class="identifier">expr</span><span class="special">::</span><span class="identifier">format_date_time</span><span class="special">(</span><span class="identifier">timestamp</span><span class="special">,</span> <span class="string">"%Y-%m-%d, %H:%M:%S.%f"</span><span class="special">)</span> 54 <span class="special"><<</span> <span class="string">" <"</span> <span class="special"><<</span> <span class="identifier">severity</span><span class="special">.</span><span class="identifier">or_default</span><span class="special">(</span><span class="identifier">normal</span><span class="special">)</span> 55 <span class="special"><<</span> <span class="string">"> "</span> <span class="special"><<</span> <span class="identifier">expr</span><span class="special">::</span><span class="identifier">message</span> 56 <span class="special">);</span> 57 58 <span class="comment">// The sink will perform character code conversion as needed, according to the locale set with imbue()</span> 59 <span class="identifier">std</span><span class="special">::</span><span class="identifier">locale</span> <span class="identifier">loc</span> <span class="special">=</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">locale</span><span class="special">::</span><span class="identifier">generator</span><span class="special">()(</span><span class="string">"en_US.UTF-8"</span><span class="special">);</span> 60 <span class="identifier">sink</span><span class="special">-></span><span class="identifier">imbue</span><span class="special">(</span><span class="identifier">loc</span><span class="special">);</span> 61 62 <span class="comment">// Let's add some commonly used attributes, like timestamp and record counter.</span> 63 <span class="identifier">logging</span><span class="special">::</span><span class="identifier">add_common_attributes</span><span class="special">();</span> 64<span class="special">}</span> 65</pre> 66<p> 67 </p> 68<p> 69 First let's take a look at the formatter we pass in the <code class="computeroutput"><span class="identifier">format</span></code> 70 parameter. We initialize the sink with a narrow-character formatter because 71 the text file sink processes bytes. It is possible to use wide strings in 72 the formatter, but not in format strings, like the one we used with the 73 <code class="computeroutput"><a class="link" href="../../boost/log/expressions/format_d_idm46079578535872.html" title="Function template format_date_time">format_date_time</a></code> function. 74 Also note that we used <code class="computeroutput"><span class="identifier">message</span></code> 75 keyword to denote the log record messages. This <a class="link" href="../detailed/expressions.html#log.detailed.expressions.message" title="Message text placeholders">placeholder</a> 76 supports both narrow and wide character messages, so the formatter will work 77 with both. As part of the formatting process, the library will convert wide 78 character messages to multibyte encoding using the imbued locale, which we 79 set to UTF-8. 80 </p> 81<div class="tip"><table border="0" summary="Tip"> 82<tr> 83<td rowspan="2" align="center" valign="top" width="25"><img alt="[Tip]" src="../../../../../../doc/src/images/tip.png"></td> 84<th align="left">Tip</th> 85</tr> 86<tr><td align="left" valign="top"><p> 87 Attribute values can also contain wide strings. Like log record messages, 88 these strings will be converted with the imbued locale to the target character 89 encoding. 90 </p></td></tr> 91</table></div> 92<p> 93 One thing missing here is our <code class="computeroutput"><span class="identifier">severity_level</span></code> 94 type definition. The type is just an enumeration, but if we want to support 95 its formatting for both narrow and wide character sinks, its streaming operator 96 has to be a template. This may be useful if we create multiple sinks with 97 different character types. 98 </p> 99<p> 100</p> 101<pre class="programlisting"><span class="keyword">enum</span> <span class="identifier">severity_level</span> 102<span class="special">{</span> 103 <span class="identifier">normal</span><span class="special">,</span> 104 <span class="identifier">notification</span><span class="special">,</span> 105 <span class="identifier">warning</span><span class="special">,</span> 106 <span class="identifier">error</span><span class="special">,</span> 107 <span class="identifier">critical</span> 108<span class="special">};</span> 109 110<span class="keyword">template</span><span class="special"><</span> <span class="keyword">typename</span> <span class="identifier">CharT</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">TraitsT</span> <span class="special">></span> 111<span class="keyword">inline</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">basic_ostream</span><span class="special"><</span> <span class="identifier">CharT</span><span class="special">,</span> <span class="identifier">TraitsT</span> <span class="special">>&</span> <span class="keyword">operator</span><span class="special"><<</span> <span class="special">(</span> 112 <span class="identifier">std</span><span class="special">::</span><span class="identifier">basic_ostream</span><span class="special"><</span> <span class="identifier">CharT</span><span class="special">,</span> <span class="identifier">TraitsT</span> <span class="special">>&</span> <span class="identifier">strm</span><span class="special">,</span> <span class="identifier">severity_level</span> <span class="identifier">lvl</span><span class="special">)</span> 113<span class="special">{</span> 114 <span class="keyword">static</span> <span class="keyword">const</span> <span class="keyword">char</span><span class="special">*</span> <span class="keyword">const</span> <span class="identifier">str</span><span class="special">[]</span> <span class="special">=</span> 115 <span class="special">{</span> 116 <span class="string">"normal"</span><span class="special">,</span> 117 <span class="string">"notification"</span><span class="special">,</span> 118 <span class="string">"warning"</span><span class="special">,</span> 119 <span class="string">"error"</span><span class="special">,</span> 120 <span class="string">"critical"</span> 121 <span class="special">};</span> 122 <span class="keyword">if</span> <span class="special">(</span><span class="keyword">static_cast</span><span class="special"><</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">size_t</span> <span class="special">>(</span><span class="identifier">lvl</span><span class="special">)</span> <span class="special"><</span> <span class="special">(</span><span class="keyword">sizeof</span><span class="special">(</span><span class="identifier">str</span><span class="special">)</span> <span class="special">/</span> <span class="keyword">sizeof</span><span class="special">(*</span><span class="identifier">str</span><span class="special">)))</span> 123 <span class="identifier">strm</span> <span class="special"><<</span> <span class="identifier">str</span><span class="special">[</span><span class="identifier">lvl</span><span class="special">];</span> 124 <span class="keyword">else</span> 125 <span class="identifier">strm</span> <span class="special"><<</span> <span class="keyword">static_cast</span><span class="special"><</span> <span class="keyword">int</span> <span class="special">>(</span><span class="identifier">lvl</span><span class="special">);</span> 126 <span class="keyword">return</span> <span class="identifier">strm</span><span class="special">;</span> 127<span class="special">}</span> 128</pre> 129<p> 130 </p> 131<p> 132 Now we can emit log records. We can use loggers with <code class="computeroutput"><span class="identifier">w</span></code> 133 prefix in their names to compose wide character messages. 134 </p> 135<p> 136</p> 137<pre class="programlisting"><span class="keyword">void</span> <span class="identifier">test_narrow_char_logging</span><span class="special">()</span> 138<span class="special">{</span> 139 <span class="comment">// Narrow character logging still works</span> 140 <span class="identifier">src</span><span class="special">::</span><span class="identifier">logger</span> <span class="identifier">lg</span><span class="special">;</span> 141 <span class="identifier">BOOST_LOG</span><span class="special">(</span><span class="identifier">lg</span><span class="special">)</span> <span class="special"><<</span> <span class="string">"Hello, World! This is a narrow character message."</span><span class="special">;</span> 142<span class="special">}</span> 143 144<span class="keyword">void</span> <span class="identifier">test_wide_char_logging</span><span class="special">()</span> 145<span class="special">{</span> 146 <span class="identifier">src</span><span class="special">::</span><span class="identifier">wlogger</span> <span class="identifier">lg</span><span class="special">;</span> 147 <span class="identifier">BOOST_LOG</span><span class="special">(</span><span class="identifier">lg</span><span class="special">)</span> <span class="special"><<</span> <span class="identifier">L</span><span class="string">"Hello, World! This is a wide character message."</span><span class="special">;</span> 148 149 <span class="comment">// National characters are also supported</span> 150 <span class="keyword">const</span> <span class="keyword">wchar_t</span> <span class="identifier">national_chars</span><span class="special">[]</span> <span class="special">=</span> <span class="special">{</span> <span class="number">0x041f</span><span class="special">,</span> <span class="number">0x0440</span><span class="special">,</span> <span class="number">0x0438</span><span class="special">,</span> <span class="number">0x0432</span><span class="special">,</span> <span class="number">0x0435</span><span class="special">,</span> <span class="number">0x0442</span><span class="special">,</span> <span class="identifier">L</span><span class="char">','</span><span class="special">,</span> <span class="identifier">L</span><span class="char">' '</span><span class="special">,</span> <span class="number">0x043c</span><span class="special">,</span> <span class="number">0x0438</span><span class="special">,</span> <span class="number">0x0440</span><span class="special">,</span> <span class="identifier">L</span><span class="char">'!'</span><span class="special">,</span> <span class="number">0</span> <span class="special">};</span> 151 <span class="identifier">BOOST_LOG</span><span class="special">(</span><span class="identifier">lg</span><span class="special">)</span> <span class="special"><<</span> <span class="identifier">national_chars</span><span class="special">;</span> 152 153 <span class="comment">// Now, let's try logging with severity</span> 154 <span class="identifier">src</span><span class="special">::</span><span class="identifier">wseverity_logger</span><span class="special"><</span> <span class="identifier">severity_level</span> <span class="special">></span> <span class="identifier">slg</span><span class="special">;</span> 155 <span class="identifier">BOOST_LOG_SEV</span><span class="special">(</span><span class="identifier">slg</span><span class="special">,</span> <span class="identifier">normal</span><span class="special">)</span> <span class="special"><<</span> <span class="identifier">L</span><span class="string">"A normal severity message, will not pass to the file"</span><span class="special">;</span> 156 <span class="identifier">BOOST_LOG_SEV</span><span class="special">(</span><span class="identifier">slg</span><span class="special">,</span> <span class="identifier">warning</span><span class="special">)</span> <span class="special"><<</span> <span class="identifier">L</span><span class="string">"A warning severity message, will pass to the file"</span><span class="special">;</span> 157 <span class="identifier">BOOST_LOG_SEV</span><span class="special">(</span><span class="identifier">slg</span><span class="special">,</span> <span class="identifier">error</span><span class="special">)</span> <span class="special"><<</span> <span class="identifier">L</span><span class="string">"An error severity message, will pass to the file"</span><span class="special">;</span> 158<span class="special">}</span> 159</pre> 160<p> 161 </p> 162<p> 163 As you can see, wide character message composition is similar to narrow logging. 164 Note that you can use both narrow and wide character logging at the same 165 time; all records will be processed by our file sink. The complete code of 166 this example can be found <a href="../../../../../../libs/log/example/wide_char/main.cpp" target="_top">here</a>. 167 </p> 168<p> 169 It must be noted that some sinks (mostly, Windows-specific ones) allow to 170 specify the target character type. When national characters are expected 171 in log records, one should always use <code class="computeroutput"><span class="keyword">wchar_t</span></code> 172 as the target character type in these cases because the sink will use wide 173 character OS API to process log records. In this case all narrow character 174 strings will be widened using the locale imbued into the sink when formatting 175 is performed. 176 </p> 177</div> 178<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr> 179<td align="left"></td> 180<td align="right"><div class="copyright-footer">Copyright © 2007-2019 Andrey Semashev<p> 181 Distributed under the Boost Software License, Version 1.0. (See accompanying 182 file LICENSE_1_0.txt or copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">http://www.boost.org/LICENSE_1_0.txt</a>). 183 </p> 184</div></td> 185</tr></table> 186<hr> 187<div class="spirit-nav"> 188<a accesskey="p" href="advanced_filtering.html"><img src="../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../tutorial.html"><img src="../../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../../index.html"><img src="../../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="../detailed.html"><img src="../../../../../../doc/src/images/next.png" alt="Next"></a> 189</div> 190</body> 191</html> 192