• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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">&lt;</span> <span class="identifier">sinks</span><span class="special">::</span><span class="identifier">synchronous_sink</span><span class="special">&lt;</span> <span class="identifier">sinks</span><span class="special">::</span><span class="identifier">text_file_backend</span> <span class="special">&gt;</span> <span class="special">&gt;</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">&lt;&lt;</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">&lt;&lt;</span> <span class="string">" &lt;"</span> <span class="special">&lt;&lt;</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">&lt;&lt;</span> <span class="string">"&gt; "</span> <span class="special">&lt;&lt;</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">-&gt;</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">&lt;</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">&gt;</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">&lt;</span> <span class="identifier">CharT</span><span class="special">,</span> <span class="identifier">TraitsT</span> <span class="special">&gt;&amp;</span> <span class="keyword">operator</span><span class="special">&lt;&lt;</span> <span class="special">(</span>
112    <span class="identifier">std</span><span class="special">::</span><span class="identifier">basic_ostream</span><span class="special">&lt;</span> <span class="identifier">CharT</span><span class="special">,</span> <span class="identifier">TraitsT</span> <span class="special">&gt;&amp;</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">&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">size_t</span> <span class="special">&gt;(</span><span class="identifier">lvl</span><span class="special">)</span> <span class="special">&lt;</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">&lt;&lt;</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">&lt;&lt;</span> <span class="keyword">static_cast</span><span class="special">&lt;</span> <span class="keyword">int</span> <span class="special">&gt;(</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">&lt;&lt;</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">&lt;&lt;</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">&lt;&lt;</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">&lt;</span> <span class="identifier">severity_level</span> <span class="special">&gt;</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">&lt;&lt;</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">&lt;&lt;</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">&lt;&lt;</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