3 <meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
4 <title>Lambda expressions</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="../detailed.html" title="Detailed features description">
9 <link rel="prev" href="sink_backends.html" title="Sink backends">
10 <link rel="next" href="attributes.html" title="Attributes">
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>
15 <div class="spirit-nav">
16 <a accesskey="p" href="sink_backends.html"><img src="../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../detailed.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="attributes.html"><img src="../../../../../../doc/src/images/next.png" alt="Next"></a>
19 <div class="titlepage"><div><div><h3 class="title">
20 <a name="log.detailed.expressions"></a><a class="link" href="expressions.html" title="Lambda expressions">Lambda expressions</a>
21 </h3></div></div></div>
22 <div class="toc"><dl class="toc">
23 <dt><span class="section"><a href="expressions.html#log.detailed.expressions.attr">Generic attribute placeholder</a></span></dt>
24 <dt><span class="section"><a href="expressions.html#log.detailed.expressions.attr_keywords">Defining attribute
25 keywords</a></span></dt>
26 <dt><span class="section"><a href="expressions.html#log.detailed.expressions.record">Record placeholder</a></span></dt>
27 <dt><span class="section"><a href="expressions.html#log.detailed.expressions.message">Message text placeholders</a></span></dt>
28 <dt><span class="section"><a href="expressions.html#log.detailed.expressions.predicates">Predicate expressions</a></span></dt>
29 <dt><span class="section"><a href="expressions.html#log.detailed.expressions.formatters">Formatting expressions</a></span></dt>
32 As it was pointed out in <a class="link" href="../tutorial.html" title="Tutorial">tutorial</a>, filters
33 and formatters can be specified as Lambda expressions with placeholders for
34 attribute values. This section will describe the placeholders that can be
35 used to build more complex Lambda expressions.
38 There is also a way to specify the filter in the form of a string template.
39 This can be useful for initialization from the application settings. This
40 part of the library is described <a class="link" href="utilities.html#log.detailed.utilities.setup.filter_formatter" title="Filter and formatter parsers">here</a>.
43 <div class="titlepage"><div><div><h4 class="title">
44 <a name="log.detailed.expressions.attr"></a><a class="link" href="expressions.html#log.detailed.expressions.attr" title="Generic attribute placeholder">Generic attribute placeholder</a>
45 </h4></div></div></div>
46 <div class="toc"><dl class="toc">
47 <dt><span class="section"><a href="expressions.html#log.detailed.expressions.attr.fallback_policies">Customizing
48 fallback policy</a></span></dt>
49 <dt><span class="section"><a href="expressions.html#log.detailed.expressions.attr.tags">Attribute tags
50 and custom formatting operators</a></span></dt>
52 <pre class="programlisting"><span class="preprocessor">#include</span> <span class="special"><</span><code class="computeroutput"><a class="link" href="../../expressions.html#header.boost.log.expressions.attr_fwd_hpp" title="Header <boost/log/expressions/attr_fwd.hpp>">boost/log/expressions/attr_fwd.hpp</a></code><span class="special">></span>
53 <span class="preprocessor">#include</span> <span class="special"><</span><code class="computeroutput"><a class="link" href="../../expressions.html#header.boost.log.expressions.attr_hpp" title="Header <boost/log/expressions/attr.hpp>">boost/log/expressions/attr.hpp</a></code><span class="special">></span>
56 The <code class="computeroutput"><a class="link" href="../../boost/log/expressions/attr_idm45711349917408.html" title="Function template attr">attr</a></code>
57 placeholder represents an attribute value in template expressions. Given
58 the record view or a set of attribute values, the placeholder will attempt
59 to extract the specified attribute value from the argument upon invocation.
60 This can be roughly described with the following pseudo-code:
62 <pre class="programlisting"><span class="identifier">logging</span><span class="special">::</span><span class="identifier">value_ref</span><span class="special"><</span> <span class="identifier">T</span><span class="special">,</span> <span class="identifier">TagT</span> <span class="special">></span> <span class="identifier">val</span> <span class="special">=</span> <span class="identifier">expr</span><span class="special">::</span><span class="identifier">attr</span><span class="special"><</span> <span class="identifier">T</span><span class="special">,</span> <span class="identifier">TagT</span> <span class="special">>(</span><span class="identifier">name</span><span class="special">)(</span><span class="identifier">rec</span><span class="special">);</span>
65 where <code class="computeroutput"><span class="identifier">val</span></code> is the <a class="link" href="utilities.html#log.detailed.utilities.value_ref" title="Value reference wrapper">reference</a> to the extracted
66 value, <code class="computeroutput"><span class="identifier">name</span></code> and <code class="computeroutput"><span class="identifier">T</span></code> are the attribute value <a class="link" href="attributes.html#log.detailed.attributes.related_components.attribute_name" title="Attribute names">name</a>
67 and type, <code class="computeroutput"><span class="identifier">TagT</span></code> is an optional
68 tag (we'll return to it in a moment) and <code class="computeroutput"><span class="identifier">rec</span></code>
69 is the log <a class="link" href="../detailed.html#log.detailed.core.record" title="Logging records">record view</a>
70 or <a class="link" href="attributes.html#log.detailed.attributes.related_components.attribute_value_set" title="Attribute value set">attribute
71 value set</a>. <code class="computeroutput"><span class="identifier">T</span></code> can
72 be a <a href="http://www.boost.org/doc/libs/release/libs/mpl/doc/index.html" target="_top">Boost.MPL</a>
73 type sequence with possible expected types of the value; the extraction
74 will succeed if the type of the value matches one of the types in the sequence.
77 The <code class="computeroutput"><span class="identifier">attr</span></code> placeholder can
78 be used in <a href="http://www.boost.org/doc/libs/release/libs/phoenix/doc/html/index.html" target="_top">Boost.Phoenix</a>
79 expressions, including the <code class="computeroutput"><span class="identifier">bind</span></code>
84 <pre class="programlisting"><span class="keyword">bool</span> <span class="identifier">my_filter</span><span class="special">(</span><span class="identifier">logging</span><span class="special">::</span><span class="identifier">value_ref</span><span class="special"><</span> <span class="identifier">severity_level</span><span class="special">,</span> <span class="identifier">tag</span><span class="special">::</span><span class="identifier">severity</span> <span class="special">></span> <span class="keyword">const</span><span class="special">&</span> <span class="identifier">level</span><span class="special">,</span>
85 <span class="identifier">logging</span><span class="special">::</span><span class="identifier">value_ref</span><span class="special"><</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span><span class="special">,</span> <span class="identifier">tag</span><span class="special">::</span><span class="identifier">tag_attr</span> <span class="special">></span> <span class="keyword">const</span><span class="special">&</span> <span class="identifier">tag</span><span class="special">)</span>
86 <span class="special">{</span>
87 <span class="keyword">return</span> <span class="identifier">level</span> <span class="special">>=</span> <span class="identifier">warning</span> <span class="special">||</span> <span class="identifier">tag</span> <span class="special">==</span> <span class="string">"IMPORTANT_MESSAGE"</span><span class="special">;</span>
88 <span class="special">}</span>
90 <span class="keyword">void</span> <span class="identifier">init</span><span class="special">()</span>
91 <span class="special">{</span>
92 <span class="comment">// ...</span>
94 <span class="keyword">namespace</span> <span class="identifier">phoenix</span> <span class="special">=</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">phoenix</span><span class="special">;</span>
95 <span class="identifier">sink</span><span class="special">-></span><span class="identifier">set_filter</span><span class="special">(</span><span class="identifier">phoenix</span><span class="special">::</span><span class="identifier">bind</span><span class="special">(&</span><span class="identifier">my_filter</span><span class="special">,</span> <span class="identifier">severity</span><span class="special">.</span><span class="identifier">or_none</span><span class="special">(),</span> <span class="identifier">tag_attr</span><span class="special">.</span><span class="identifier">or_none</span><span class="special">()));</span>
97 <span class="comment">// ...</span>
98 <span class="special">}</span>
103 The placeholder can be used both in filters and formatters:
105 <pre class="programlisting"><span class="identifier">sink</span><span class="special">-></span><span class="identifier">set_filter</span>
106 <span class="special">(</span>
107 <span class="identifier">expr</span><span class="special">::</span><span class="identifier">attr</span><span class="special"><</span> <span class="keyword">int</span> <span class="special">>(</span><span class="string">"Severity"</span><span class="special">)</span> <span class="special">>=</span> <span class="number">5</span> <span class="special">&&</span>
108 <span class="identifier">expr</span><span class="special">::</span><span class="identifier">attr</span><span class="special"><</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="special">>(</span><span class="string">"Channel"</span><span class="special">)</span> <span class="special">==</span> <span class="string">"net"</span>
109 <span class="special">);</span>
111 <span class="identifier">sink</span><span class="special">-></span><span class="identifier">set_formatter</span>
112 <span class="special">(</span>
113 <span class="identifier">expr</span><span class="special">::</span><span class="identifier">stream</span>
114 <span class="special"><<</span> <span class="identifier">expr</span><span class="special">::</span><span class="identifier">attr</span><span class="special"><</span> <span class="keyword">int</span> <span class="special">>(</span><span class="string">"Severity"</span><span class="special">)</span>
115 <span class="special"><<</span> <span class="string">" ["</span> <span class="special"><<</span> <span class="identifier">expr</span><span class="special">::</span><span class="identifier">attr</span><span class="special"><</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="special">>(</span><span class="string">"Channel"</span><span class="special">)</span> <span class="special"><<</span> <span class="string">"] "</span>
116 <span class="special"><<</span> <span class="identifier">expr</span><span class="special">::</span><span class="identifier">smessage</span>
117 <span class="special">);</span>
120 The call to <code class="computeroutput"><span class="identifier">set_filter</span></code>
121 registers a composite filter that consists of two elementary subfilters:
122 the first one checks the severity level, and the second checks the channel
123 name. The call to <code class="computeroutput"><span class="identifier">set_formatter</span></code>
124 installs a formatter that composes a string containing the severity level
125 and the channel name along with the message text.
127 <div class="section">
128 <div class="titlepage"><div><div><h5 class="title">
129 <a name="log.detailed.expressions.attr.fallback_policies"></a><a class="link" href="expressions.html#log.detailed.expressions.attr.fallback_policies" title="Customizing fallback policy">Customizing
131 </h5></div></div></div>
133 By default, when the requested attribute value is not found in the record,
134 <code class="computeroutput"><span class="identifier">attr</span></code> will return an empty
135 reference. In case of filters, this will result in <code class="computeroutput"><span class="keyword">false</span></code>
136 in any ordering expressions, and in case of formatters the output from
137 the placeholder will be empty. This behavior can be changed:
139 <div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem">
140 To throw an exception (<code class="computeroutput"><a class="link" href="../../boost/log/missing_value.html" title="Class missing_value">missing_value</a></code>
141 or <code class="computeroutput"><a class="link" href="../../boost/log/invalid_type.html" title="Class invalid_type">invalid_type</a></code>,
142 depending on the reason of the failure). Add the <code class="computeroutput"><span class="identifier">or_throw</span></code>
145 <pre class="programlisting"><span class="identifier">sink</span><span class="special">-></span><span class="identifier">set_filter</span>
146 <span class="special">(</span>
147 <span class="identifier">expr</span><span class="special">::</span><span class="identifier">attr</span><span class="special"><</span> <span class="keyword">int</span> <span class="special">>(</span><span class="string">"Severity"</span><span class="special">).</span><span class="identifier">or_throw</span><span class="special">()</span> <span class="special">>=</span> <span class="number">5</span> <span class="special">&&</span>
148 <span class="identifier">expr</span><span class="special">::</span><span class="identifier">attr</span><span class="special"><</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="special">>(</span><span class="string">"Channel"</span><span class="special">).</span><span class="identifier">or_throw</span><span class="special">()</span> <span class="special">==</span> <span class="string">"net"</span>
149 <span class="special">);</span>
151 <div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem">
152 To use a default value instead. Add the <code class="computeroutput"><span class="identifier">or_default</span></code>
153 modifier with the desired default value:
155 <pre class="programlisting"><span class="identifier">sink</span><span class="special">-></span><span class="identifier">set_filter</span>
156 <span class="special">(</span>
157 <span class="identifier">expr</span><span class="special">::</span><span class="identifier">attr</span><span class="special"><</span> <span class="keyword">int</span> <span class="special">>(</span><span class="string">"Severity"</span><span class="special">).</span><span class="identifier">or_default</span><span class="special">(</span><span class="number">0</span><span class="special">)</span> <span class="special">>=</span> <span class="number">5</span> <span class="special">&&</span>
158 <span class="identifier">expr</span><span class="special">::</span><span class="identifier">attr</span><span class="special"><</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="special">>(</span><span class="string">"Channel"</span><span class="special">).</span><span class="identifier">or_default</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span><span class="special">(</span><span class="string">"general"</span><span class="special">))</span> <span class="special">==</span> <span class="string">"net"</span>
159 <span class="special">);</span>
161 <div class="tip"><table border="0" summary="Tip">
163 <td rowspan="2" align="center" valign="top" width="25"><img alt="[Tip]" src="../../../../../../doc/src/images/tip.png"></td>
164 <th align="left">Tip</th>
166 <tr><td align="left" valign="top"><p>
167 You can also use the <a class="link" href="expressions.html#log.detailed.expressions.predicates.has_attr" title="Attribute presence filter"><code class="computeroutput"><span class="identifier">has_attr</span></code></a> predicate to implement
168 filters and formatters conditional on the attribute value presence.
172 The default behavior is also accessible through the <code class="computeroutput"><span class="identifier">or_none</span></code>
173 modifier. The modified placeholders can be used in filters and formatters
174 just the same way as the unmodified ones.
177 In <code class="computeroutput"><span class="identifier">bind</span></code> expressions,
178 the bound function object will still receive the <a class="link" href="utilities.html#log.detailed.utilities.value_ref" title="Value reference wrapper"><code class="computeroutput"><span class="identifier">value_ref</span></code></a>-wrapped values in
179 place of the modified <code class="computeroutput"><span class="identifier">attr</span></code>
180 placeholder. Even though both <code class="computeroutput"><span class="identifier">or_throw</span></code>
181 and <code class="computeroutput"><span class="identifier">or_default</span></code> modifiers
182 guarantee that the bound function will receive a filled reference, <a class="link" href="utilities.html#log.detailed.utilities.value_ref" title="Value reference wrapper"><code class="computeroutput"><span class="identifier">value_ref</span></code></a>
183 is still needed if the value type is specified as a type sequence. Also,
184 the reference wrapper may contain a tag type which may be useful for
185 formatting customization.
188 <div class="section">
189 <div class="titlepage"><div><div><h5 class="title">
190 <a name="log.detailed.expressions.attr.tags"></a><a class="link" href="expressions.html#log.detailed.expressions.attr.tags" title="Attribute tags and custom formatting operators">Attribute tags
191 and custom formatting operators</a>
192 </h5></div></div></div>
194 The <code class="computeroutput"><span class="identifier">TagT</span></code> type in the
195 <a class="link" href="expressions.html#log.detailed.expressions.attr" title="Generic attribute placeholder">abstract description</a>
196 of <code class="computeroutput"><span class="identifier">attr</span></code> above is optional
197 and by default is <code class="computeroutput"><span class="keyword">void</span></code>.
198 This is an attribute tag which can be used to customize the output formatters
199 produce for different attributes. This tag is forwarded to the <a class="link" href="utilities.html#log.detailed.utilities.manipulators.to_log" title="Customized logging manipulator"><code class="computeroutput"><span class="identifier">to_log</span></code></a>
200 manipulator when the extracted attribute value is put to a stream (this
201 behavior is warranted by <a class="link" href="utilities.html#log.detailed.utilities.value_ref" title="Value reference wrapper"><code class="computeroutput"><span class="identifier">value_ref</span></code></a> implementation). Here's
206 <pre class="programlisting"><span class="comment">// We define our own severity levels</span>
207 <span class="keyword">enum</span> <span class="identifier">severity_level</span>
208 <span class="special">{</span>
209 <span class="identifier">normal</span><span class="special">,</span>
210 <span class="identifier">notification</span><span class="special">,</span>
211 <span class="identifier">warning</span><span class="special">,</span>
212 <span class="identifier">error</span><span class="special">,</span>
213 <span class="identifier">critical</span>
214 <span class="special">};</span>
216 <span class="comment">// The operator is used for regular stream formatting</span>
217 <span class="identifier">std</span><span class="special">::</span><span class="identifier">ostream</span><span class="special">&</span> <span class="keyword">operator</span><span class="special"><<</span> <span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">ostream</span><span class="special">&</span> <span class="identifier">strm</span><span class="special">,</span> <span class="identifier">severity_level</span> <span class="identifier">level</span><span class="special">)</span>
218 <span class="special">{</span>
219 <span class="keyword">static</span> <span class="keyword">const</span> <span class="keyword">char</span><span class="special">*</span> <span class="identifier">strings</span><span class="special">[]</span> <span class="special">=</span>
220 <span class="special">{</span>
221 <span class="string">"normal"</span><span class="special">,</span>
222 <span class="string">"notification"</span><span class="special">,</span>
223 <span class="string">"warning"</span><span class="special">,</span>
224 <span class="string">"error"</span><span class="special">,</span>
225 <span class="string">"critical"</span>
226 <span class="special">};</span>
228 <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">level</span><span class="special">)</span> <span class="special"><</span> <span class="keyword">sizeof</span><span class="special">(</span><span class="identifier">strings</span><span class="special">)</span> <span class="special">/</span> <span class="keyword">sizeof</span><span class="special">(*</span><span class="identifier">strings</span><span class="special">))</span>
229 <span class="identifier">strm</span> <span class="special"><<</span> <span class="identifier">strings</span><span class="special">[</span><span class="identifier">level</span><span class="special">];</span>
230 <span class="keyword">else</span>
231 <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">level</span><span class="special">);</span>
233 <span class="keyword">return</span> <span class="identifier">strm</span><span class="special">;</span>
234 <span class="special">}</span>
236 <span class="comment">// Attribute value tag type</span>
237 <span class="keyword">struct</span> <span class="identifier">severity_tag</span><span class="special">;</span>
239 <span class="comment">// The operator is used when putting the severity level to log</span>
240 <span class="identifier">logging</span><span class="special">::</span><span class="identifier">formatting_ostream</span><span class="special">&</span> <span class="keyword">operator</span><span class="special"><<</span>
241 <span class="special">(</span>
242 <span class="identifier">logging</span><span class="special">::</span><span class="identifier">formatting_ostream</span><span class="special">&</span> <span class="identifier">strm</span><span class="special">,</span>
243 <span class="identifier">logging</span><span class="special">::</span><span class="identifier">to_log_manip</span><span class="special"><</span> <span class="identifier">severity_level</span><span class="special">,</span> <span class="identifier">severity_tag</span> <span class="special">></span> <span class="keyword">const</span><span class="special">&</span> <span class="identifier">manip</span>
244 <span class="special">)</span>
245 <span class="special">{</span>
246 <span class="keyword">static</span> <span class="keyword">const</span> <span class="keyword">char</span><span class="special">*</span> <span class="identifier">strings</span><span class="special">[]</span> <span class="special">=</span>
247 <span class="special">{</span>
248 <span class="string">"NORM"</span><span class="special">,</span>
249 <span class="string">"NTFY"</span><span class="special">,</span>
250 <span class="string">"WARN"</span><span class="special">,</span>
251 <span class="string">"ERRR"</span><span class="special">,</span>
252 <span class="string">"CRIT"</span>
253 <span class="special">};</span>
255 <span class="identifier">severity_level</span> <span class="identifier">level</span> <span class="special">=</span> <span class="identifier">manip</span><span class="special">.</span><span class="identifier">get</span><span class="special">();</span>
256 <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">level</span><span class="special">)</span> <span class="special"><</span> <span class="keyword">sizeof</span><span class="special">(</span><span class="identifier">strings</span><span class="special">)</span> <span class="special">/</span> <span class="keyword">sizeof</span><span class="special">(*</span><span class="identifier">strings</span><span class="special">))</span>
257 <span class="identifier">strm</span> <span class="special"><<</span> <span class="identifier">strings</span><span class="special">[</span><span class="identifier">level</span><span class="special">];</span>
258 <span class="keyword">else</span>
259 <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">level</span><span class="special">);</span>
261 <span class="keyword">return</span> <span class="identifier">strm</span><span class="special">;</span>
262 <span class="special">}</span>
264 <span class="keyword">void</span> <span class="identifier">init</span><span class="special">()</span>
265 <span class="special">{</span>
266 <span class="identifier">logging</span><span class="special">::</span><span class="identifier">add_console_log</span>
267 <span class="special">(</span>
268 <span class="identifier">std</span><span class="special">::</span><span class="identifier">clog</span><span class="special">,</span>
269 <span class="comment">// This makes the sink to write log records that look like this:</span>
270 <span class="comment">// 1: <NORM> A normal severity message</span>
271 <span class="comment">// 2: <ERRR> An error severity message</span>
272 <span class="identifier">keywords</span><span class="special">::</span><span class="identifier">format</span> <span class="special">=</span>
273 <span class="special">(</span>
274 <span class="identifier">expr</span><span class="special">::</span><span class="identifier">stream</span>
275 <span class="special"><<</span> <span class="identifier">expr</span><span class="special">::</span><span class="identifier">attr</span><span class="special"><</span> <span class="keyword">unsigned</span> <span class="keyword">int</span> <span class="special">>(</span><span class="string">"LineID"</span><span class="special">)</span>
276 <span class="special"><<</span> <span class="string">": <"</span> <span class="special"><<</span> <span class="identifier">expr</span><span class="special">::</span><span class="identifier">attr</span><span class="special"><</span> <span class="identifier">severity_level</span><span class="special">,</span> <span class="identifier">severity_tag</span> <span class="special">>(</span><span class="string">"Severity"</span><span class="special">)</span>
277 <span class="special"><<</span> <span class="string">"> "</span> <span class="special"><<</span> <span class="identifier">expr</span><span class="special">::</span><span class="identifier">smessage</span>
278 <span class="special">)</span>
279 <span class="special">);</span>
280 <span class="special">}</span>
285 <a href="../../../../../../libs/log/example/doc/expressions_attr_fmt_tag.cpp" target="_top">See
286 the complete code</a>.
289 Here we specify a different formatting operator for the severity level
290 wrapped in the <a class="link" href="utilities.html#log.detailed.utilities.manipulators.to_log" title="Customized logging manipulator"><code class="computeroutput"><span class="identifier">to_log_manip</span></code></a> manipulator marked
291 with the tag <code class="computeroutput"><span class="identifier">severity_tag</span></code>.
292 This operator will be called when log records are formatted while the
293 regular <code class="computeroutput"><span class="keyword">operator</span><span class="special"><<</span></code>
294 will be used in other contexts.
298 <div class="section">
299 <div class="titlepage"><div><div><h4 class="title">
300 <a name="log.detailed.expressions.attr_keywords"></a><a class="link" href="expressions.html#log.detailed.expressions.attr_keywords" title="Defining attribute keywords">Defining attribute
302 </h4></div></div></div>
303 <pre class="programlisting"><span class="preprocessor">#include</span> <span class="special"><</span><code class="computeroutput"><a class="link" href="../../expressions.html#header.boost.log.expressions.keyword_fwd_hpp" title="Header <boost/log/expressions/keyword_fwd.hpp>">boost/log/expressions/keyword_fwd.hpp</a></code><span class="special">></span>
304 <span class="preprocessor">#include</span> <span class="special"><</span><code class="computeroutput"><a class="link" href="../../expressions.html#header.boost.log.expressions.keyword_hpp" title="Header <boost/log/expressions/keyword.hpp>">boost/log/expressions/keyword.hpp</a></code><span class="special">></span>
307 Attribute keywords can be used as replacements for the <a class="link" href="expressions.html#log.detailed.expressions.attr" title="Generic attribute placeholder"><code class="computeroutput"><span class="identifier">attr</span></code></a> placeholders in filters and
308 formatters while providing a more concise and less error prone syntax.
309 An attribute keyword can be declared with the <code class="computeroutput"><a class="link" href="../../BOOST_LO_idm45711347575568.html" title="Macro BOOST_LOG_ATTRIBUTE_KEYWORD">BOOST_LOG_ATTRIBUTE_KEYWORD</a></code>
312 <pre class="programlisting"><span class="identifier">BOOST_LOG_ATTRIBUTE_KEYWORD</span><span class="special">(</span><span class="identifier">keyword</span><span class="special">,</span> <span class="string">"Keyword"</span><span class="special">,</span> <span class="identifier">type</span><span class="special">)</span>
315 Here the macro declares a keyword <code class="computeroutput"><span class="identifier">keyword</span></code>
316 for an attribute named "Keyword" with the value type of <code class="computeroutput"><span class="identifier">type</span></code>. Additionally, the macro defines
317 an attribute tag type <code class="computeroutput"><span class="identifier">keyword</span></code>
318 within the <code class="computeroutput"><span class="identifier">tag</span></code> namespace.
319 We can rewrite the previous example in the following way:
323 <pre class="programlisting"><span class="comment">// We define our own severity levels</span>
324 <span class="keyword">enum</span> <span class="identifier">severity_level</span>
325 <span class="special">{</span>
326 <span class="identifier">normal</span><span class="special">,</span>
327 <span class="identifier">notification</span><span class="special">,</span>
328 <span class="identifier">warning</span><span class="special">,</span>
329 <span class="identifier">error</span><span class="special">,</span>
330 <span class="identifier">critical</span>
331 <span class="special">};</span>
333 <span class="comment">// Define the attribute keywords</span>
334 <span class="identifier">BOOST_LOG_ATTRIBUTE_KEYWORD</span><span class="special">(</span><span class="identifier">line_id</span><span class="special">,</span> <span class="string">"LineID"</span><span class="special">,</span> <span class="keyword">unsigned</span> <span class="keyword">int</span><span class="special">)</span>
335 <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>
337 <span class="comment">// The operator is used for regular stream formatting</span>
338 <span class="identifier">std</span><span class="special">::</span><span class="identifier">ostream</span><span class="special">&</span> <span class="keyword">operator</span><span class="special"><<</span> <span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">ostream</span><span class="special">&</span> <span class="identifier">strm</span><span class="special">,</span> <span class="identifier">severity_level</span> <span class="identifier">level</span><span class="special">)</span>
339 <span class="special">{</span>
340 <span class="keyword">static</span> <span class="keyword">const</span> <span class="keyword">char</span><span class="special">*</span> <span class="identifier">strings</span><span class="special">[]</span> <span class="special">=</span>
341 <span class="special">{</span>
342 <span class="string">"normal"</span><span class="special">,</span>
343 <span class="string">"notification"</span><span class="special">,</span>
344 <span class="string">"warning"</span><span class="special">,</span>
345 <span class="string">"error"</span><span class="special">,</span>
346 <span class="string">"critical"</span>
347 <span class="special">};</span>
349 <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">level</span><span class="special">)</span> <span class="special"><</span> <span class="keyword">sizeof</span><span class="special">(</span><span class="identifier">strings</span><span class="special">)</span> <span class="special">/</span> <span class="keyword">sizeof</span><span class="special">(*</span><span class="identifier">strings</span><span class="special">))</span>
350 <span class="identifier">strm</span> <span class="special"><<</span> <span class="identifier">strings</span><span class="special">[</span><span class="identifier">level</span><span class="special">];</span>
351 <span class="keyword">else</span>
352 <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">level</span><span class="special">);</span>
354 <span class="keyword">return</span> <span class="identifier">strm</span><span class="special">;</span>
355 <span class="special">}</span>
357 <span class="comment">// The operator is used when putting the severity level to log</span>
358 <span class="identifier">logging</span><span class="special">::</span><span class="identifier">formatting_ostream</span><span class="special">&</span> <span class="keyword">operator</span><span class="special"><<</span>
359 <span class="special">(</span>
360 <span class="identifier">logging</span><span class="special">::</span><span class="identifier">formatting_ostream</span><span class="special">&</span> <span class="identifier">strm</span><span class="special">,</span>
361 <span class="identifier">logging</span><span class="special">::</span><span class="identifier">to_log_manip</span><span class="special"><</span> <span class="identifier">severity_level</span><span class="special">,</span> <span class="identifier">tag</span><span class="special">::</span><span class="identifier">severity</span> <span class="special">></span> <span class="keyword">const</span><span class="special">&</span> <span class="identifier">manip</span>
362 <span class="special">)</span>
363 <span class="special">{</span>
364 <span class="keyword">static</span> <span class="keyword">const</span> <span class="keyword">char</span><span class="special">*</span> <span class="identifier">strings</span><span class="special">[]</span> <span class="special">=</span>
365 <span class="special">{</span>
366 <span class="string">"NORM"</span><span class="special">,</span>
367 <span class="string">"NTFY"</span><span class="special">,</span>
368 <span class="string">"WARN"</span><span class="special">,</span>
369 <span class="string">"ERRR"</span><span class="special">,</span>
370 <span class="string">"CRIT"</span>
371 <span class="special">};</span>
373 <span class="identifier">severity_level</span> <span class="identifier">level</span> <span class="special">=</span> <span class="identifier">manip</span><span class="special">.</span><span class="identifier">get</span><span class="special">();</span>
374 <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">level</span><span class="special">)</span> <span class="special"><</span> <span class="keyword">sizeof</span><span class="special">(</span><span class="identifier">strings</span><span class="special">)</span> <span class="special">/</span> <span class="keyword">sizeof</span><span class="special">(*</span><span class="identifier">strings</span><span class="special">))</span>
375 <span class="identifier">strm</span> <span class="special"><<</span> <span class="identifier">strings</span><span class="special">[</span><span class="identifier">level</span><span class="special">];</span>
376 <span class="keyword">else</span>
377 <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">level</span><span class="special">);</span>
379 <span class="keyword">return</span> <span class="identifier">strm</span><span class="special">;</span>
380 <span class="special">}</span>
382 <span class="keyword">void</span> <span class="identifier">init</span><span class="special">()</span>
383 <span class="special">{</span>
384 <span class="identifier">logging</span><span class="special">::</span><span class="identifier">add_console_log</span>
385 <span class="special">(</span>
386 <span class="identifier">std</span><span class="special">::</span><span class="identifier">clog</span><span class="special">,</span>
387 <span class="comment">// This makes the sink to write log records that look like this:</span>
388 <span class="comment">// 1: <NORM> A normal severity message</span>
389 <span class="comment">// 2: <ERRR> An error severity message</span>
390 <span class="identifier">keywords</span><span class="special">::</span><span class="identifier">format</span> <span class="special">=</span>
391 <span class="special">(</span>
392 <span class="identifier">expr</span><span class="special">::</span><span class="identifier">stream</span>
393 <span class="special"><<</span> <span class="identifier">line_id</span>
394 <span class="special"><<</span> <span class="string">": <"</span> <span class="special"><<</span> <span class="identifier">severity</span>
395 <span class="special"><<</span> <span class="string">"> "</span> <span class="special"><<</span> <span class="identifier">expr</span><span class="special">::</span><span class="identifier">smessage</span>
396 <span class="special">)</span>
397 <span class="special">);</span>
398 <span class="special">}</span>
403 Attribute keywords behave the same way as the <a class="link" href="expressions.html#log.detailed.expressions.attr" title="Generic attribute placeholder"><code class="computeroutput"><span class="identifier">attr</span></code></a> placeholders and can be used
404 both in filters and formatters. The <code class="computeroutput"><span class="identifier">or_throw</span></code>
405 and <code class="computeroutput"><span class="identifier">or_default</span></code> modifiers
409 Keywords can also be used in attribute value lookup expressions in log
410 records and attribute value sets:
414 <pre class="programlisting"><span class="keyword">void</span> <span class="identifier">print_severity</span><span class="special">(</span><span class="identifier">logging</span><span class="special">::</span><span class="identifier">record_view</span> <span class="keyword">const</span><span class="special">&</span> <span class="identifier">rec</span><span class="special">)</span>
415 <span class="special">{</span>
416 <span class="identifier">logging</span><span class="special">::</span><span class="identifier">value_ref</span><span class="special"><</span> <span class="identifier">severity_level</span><span class="special">,</span> <span class="identifier">tag</span><span class="special">::</span><span class="identifier">severity</span> <span class="special">></span> <span class="identifier">level</span> <span class="special">=</span> <span class="identifier">rec</span><span class="special">[</span><span class="identifier">severity</span><span class="special">];</span>
417 <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special"><<</span> <span class="identifier">level</span> <span class="special"><<</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>
418 <span class="special">}</span>
423 <div class="section">
424 <div class="titlepage"><div><div><h4 class="title">
425 <a name="log.detailed.expressions.record"></a><a class="link" href="expressions.html#log.detailed.expressions.record" title="Record placeholder">Record placeholder</a>
426 </h4></div></div></div>
427 <pre class="programlisting"><span class="preprocessor">#include</span> <span class="special"><</span><code class="computeroutput"><a class="link" href="../../expressions.html#header.boost.log.expressions.record_hpp" title="Header <boost/log/expressions/record.hpp>">boost/log/expressions/record.hpp</a></code><span class="special">></span>
430 The <code class="computeroutput"><span class="identifier">record</span></code> placeholder
431 can be used in <code class="computeroutput"><span class="identifier">bind</span></code> expressions
432 to pass the whole log <a class="link" href="../detailed.html#log.detailed.core.record" title="Logging records">record view</a>
433 to the bound function object.
435 <pre class="programlisting"><span class="keyword">void</span> <span class="identifier">my_formatter</span><span class="special">(</span><span class="identifier">logging</span><span class="special">::</span><span class="identifier">formatting_ostream</span><span class="special">&</span> <span class="identifier">strm</span><span class="special">,</span> <span class="identifier">logging</span><span class="special">::</span><span class="identifier">record_view</span> <span class="keyword">const</span><span class="special">&</span> <span class="identifier">rec</span><span class="special">)</span>
436 <span class="special">{</span>
437 <span class="comment">// ...</span>
438 <span class="special">}</span>
440 <span class="keyword">namespace</span> <span class="identifier">phoenix</span> <span class="special">=</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">phoenix</span><span class="special">;</span>
441 <span class="identifier">sink</span><span class="special">-></span><span class="identifier">set_formatter</span><span class="special">(</span><span class="identifier">phoenix</span><span class="special">::</span><span class="identifier">bind</span><span class="special">(&</span><span class="identifier">my_formatter</span><span class="special">,</span> <span class="identifier">expr</span><span class="special">::</span><span class="identifier">stream</span><span class="special">,</span> <span class="identifier">expr</span><span class="special">::</span><span class="identifier">record</span><span class="special">));</span>
443 <div class="note"><table border="0" summary="Note">
445 <td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../../../../doc/src/images/note.png"></td>
446 <th align="left">Note</th>
448 <tr><td align="left" valign="top"><p>
449 In case of filters, the placeholder will correspond to the <a class="link" href="attributes.html#log.detailed.attributes.related_components.attribute_value_set" title="Attribute value set">set
450 of attribute values</a> rather than the log record itself. This is
451 because the record is not constructed yet at the point of filtering,
452 and filters only operate on the set of attribute values.
456 <div class="section">
457 <div class="titlepage"><div><div><h4 class="title">
458 <a name="log.detailed.expressions.message"></a><a class="link" href="expressions.html#log.detailed.expressions.message" title="Message text placeholders">Message text placeholders</a>
459 </h4></div></div></div>
460 <pre class="programlisting"><span class="preprocessor">#include</span> <span class="special"><</span><code class="computeroutput"><a class="link" href="../../expressions.html#header.boost.log.expressions.message_hpp" title="Header <boost/log/expressions/message.hpp>">boost/log/expressions/message.hpp</a></code><span class="special">></span>
463 Log records typically contain a special attribute "Message" with
464 the value of one of the string types (more specifically, an <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">basic_string</span></code> specialization). This attribute
465 contains the text of the log message that is constructed at the point of
466 the record creation. This attribute is only constructed after filtering,
467 so filters cannot use it. There are several keywords to access this attribute
470 <div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
471 <li class="listitem">
472 <code class="computeroutput"><span class="identifier">smessage</span></code> - the attribute
473 value is expected to be an <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span></code>
475 <li class="listitem">
476 <code class="computeroutput"><span class="identifier">wmessage</span></code> - the attribute
477 value is expected to be an <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">wstring</span></code>
479 <li class="listitem">
480 <code class="computeroutput"><span class="identifier">message</span></code> - the attribute
481 value is expected to be an <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span></code>
482 or <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">wstring</span></code>
486 The <code class="computeroutput"><span class="identifier">message</span></code> keyword has
487 to dispatch between different string types, so it is slightly less efficient
488 than the other two keywords. If the application is able to guarantee the
489 fixed character type of log messages, it is advised to use the corresponding
490 keyword for better performance.
492 <pre class="programlisting"><span class="comment">// Sets up a formatter that will ignore all attributes and only print log record text</span>
493 <span class="identifier">sink</span><span class="special">-></span><span class="identifier">set_formatter</span><span class="special">(</span><span class="identifier">expr</span><span class="special">::</span><span class="identifier">stream</span> <span class="special"><<</span> <span class="identifier">expr</span><span class="special">::</span><span class="identifier">message</span><span class="special">);</span>
496 <div class="section">
497 <div class="titlepage"><div><div><h4 class="title">
498 <a name="log.detailed.expressions.predicates"></a><a class="link" href="expressions.html#log.detailed.expressions.predicates" title="Predicate expressions">Predicate expressions</a>
499 </h4></div></div></div>
500 <div class="toc"><dl class="toc">
501 <dt><span class="section"><a href="expressions.html#log.detailed.expressions.predicates.has_attr">Attribute
502 presence filter</a></span></dt>
503 <dt><span class="section"><a href="expressions.html#log.detailed.expressions.predicates.is_in_range">Range
504 checking filter</a></span></dt>
505 <dt><span class="section"><a href="expressions.html#log.detailed.expressions.predicates.simple_string_matching">Simple
506 string matching filters</a></span></dt>
507 <dt><span class="section"><a href="expressions.html#log.detailed.expressions.predicates.advanced_string_matching">Advanced
508 string matching filter</a></span></dt>
509 <dt><span class="section"><a href="expressions.html#log.detailed.expressions.predicates.channel_severity_filter">Severity
510 threshold per channel filter</a></span></dt>
511 <dt><span class="section"><a href="expressions.html#log.detailed.expressions.predicates.is_debugger_present">Debugger
512 presence filter</a></span></dt>
515 This section describes several expressions that can be used as predicates
516 in filtering expressions.
518 <div class="section">
519 <div class="titlepage"><div><div><h5 class="title">
520 <a name="log.detailed.expressions.predicates.has_attr"></a><a class="link" href="expressions.html#log.detailed.expressions.predicates.has_attr" title="Attribute presence filter">Attribute
522 </h5></div></div></div>
523 <pre class="programlisting"><span class="preprocessor">#include</span> <span class="special"><</span><code class="computeroutput"><a class="link" href="../../expressions.html#header.boost.log.expressions.predicates.has_attr_hpp" title="Header <boost/log/expressions/predicates/has_attr.hpp>">boost/log/expressions/predicates/has_attr.hpp</a></code><span class="special">></span>
526 The filter <code class="computeroutput"><a class="link" href="../../boost/log/expressions/has_attr_idm45711347208272.html" title="Function template has_attr">has_attr</a></code> checks if an
527 attribute value with the specified name and, optionally, type is attached
528 to a log record. If no type specified to the filter, the filter returns
529 <code class="computeroutput"><span class="keyword">true</span></code> if any value with the
530 specified name is found. If an MPL-compatible type sequence in specified
531 as a value type, the filter returns <code class="computeroutput"><span class="keyword">true</span></code>
532 if a value with the specified name and one of the specified types is
536 This filter is usually used in conjunction with <a class="link" href="expressions.html#log.detailed.expressions.formatters.conditional" title="Conditional formatters">conditional
537 formatters</a>, but it also can be used as a quick filter based on
538 the log record structure. For example, one can use this filter to extract
539 statistic records and route them to a specific sink.
543 <pre class="programlisting"><span class="comment">// Declare attribute keywords</span>
544 <span class="identifier">BOOST_LOG_ATTRIBUTE_KEYWORD</span><span class="special">(</span><span class="identifier">stat_stream</span><span class="special">,</span> <span class="string">"StatisticStream"</span><span class="special">,</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span><span class="special">)</span>
545 <span class="identifier">BOOST_LOG_ATTRIBUTE_KEYWORD</span><span class="special">(</span><span class="identifier">change</span><span class="special">,</span> <span class="string">"Change"</span><span class="special">,</span> <span class="keyword">int</span><span class="special">)</span>
547 <span class="comment">// A simple sink backend to accumulate statistic information</span>
548 <span class="keyword">class</span> <span class="identifier">my_stat_accumulator</span> <span class="special">:</span>
549 <span class="keyword">public</span> <span class="identifier">sinks</span><span class="special">::</span><span class="identifier">basic_sink_backend</span><span class="special"><</span> <span class="identifier">sinks</span><span class="special">::</span><span class="identifier">synchronized_feeding</span> <span class="special">></span>
550 <span class="special">{</span>
551 <span class="comment">// A map of accumulated statistic values,</span>
552 <span class="comment">// ordered by the statistic information stream name</span>
553 <span class="keyword">typedef</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">map</span><span class="special"><</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span><span class="special">,</span> <span class="keyword">int</span> <span class="special">></span> <span class="identifier">stat_info_map</span><span class="special">;</span>
554 <span class="identifier">stat_info_map</span> <span class="identifier">m_stat_info</span><span class="special">;</span>
556 <span class="keyword">public</span><span class="special">:</span>
557 <span class="comment">// Destructor</span>
558 <span class="special">~</span><span class="identifier">my_stat_accumulator</span><span class="special">()</span>
559 <span class="special">{</span>
560 <span class="comment">// Display the accumulated data</span>
561 <span class="identifier">stat_info_map</span><span class="special">::</span><span class="identifier">const_iterator</span> <span class="identifier">it</span> <span class="special">=</span> <span class="identifier">m_stat_info</span><span class="special">.</span><span class="identifier">begin</span><span class="special">(),</span> <span class="identifier">end</span> <span class="special">=</span> <span class="identifier">m_stat_info</span><span class="special">.</span><span class="identifier">end</span><span class="special">();</span>
562 <span class="keyword">for</span> <span class="special">(;</span> <span class="identifier">it</span> <span class="special">!=</span> <span class="identifier">end</span><span class="special">;</span> <span class="special">++</span><span class="identifier">it</span><span class="special">)</span>
563 <span class="special">{</span>
564 <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special"><<</span> <span class="string">"Statistic stream: "</span> <span class="special"><<</span> <span class="identifier">it</span><span class="special">-></span><span class="identifier">first</span>
565 <span class="special"><<</span> <span class="string">", accumulated value: "</span> <span class="special"><<</span> <span class="identifier">it</span><span class="special">-></span><span class="identifier">second</span> <span class="special"><<</span> <span class="string">"\n"</span><span class="special">;</span>
566 <span class="special">}</span>
567 <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span><span class="special">.</span><span class="identifier">flush</span><span class="special">();</span>
568 <span class="special">}</span>
570 <span class="comment">// The method is called for every log record being put into the sink backend</span>
571 <span class="keyword">void</span> <span class="identifier">consume</span><span class="special">(</span><span class="identifier">logging</span><span class="special">::</span><span class="identifier">record_view</span> <span class="keyword">const</span><span class="special">&</span> <span class="identifier">rec</span><span class="special">)</span>
572 <span class="special">{</span>
573 <span class="comment">// First, acquire statistic information stream name</span>
574 <span class="identifier">logging</span><span class="special">::</span><span class="identifier">value_ref</span><span class="special"><</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span><span class="special">,</span> <span class="identifier">tag</span><span class="special">::</span><span class="identifier">stat_stream</span> <span class="special">></span> <span class="identifier">name</span> <span class="special">=</span> <span class="identifier">rec</span><span class="special">[</span><span class="identifier">stat_stream</span><span class="special">];</span>
575 <span class="keyword">if</span> <span class="special">(</span><span class="identifier">name</span><span class="special">)</span>
576 <span class="special">{</span>
577 <span class="comment">// Next, get the statistic value change</span>
578 <span class="identifier">logging</span><span class="special">::</span><span class="identifier">value_ref</span><span class="special"><</span> <span class="keyword">int</span><span class="special">,</span> <span class="identifier">tag</span><span class="special">::</span><span class="identifier">change</span> <span class="special">></span> <span class="identifier">change_amount</span> <span class="special">=</span> <span class="identifier">rec</span><span class="special">[</span><span class="identifier">change</span><span class="special">];</span>
579 <span class="keyword">if</span> <span class="special">(</span><span class="identifier">change_amount</span><span class="special">)</span>
580 <span class="special">{</span>
581 <span class="comment">// Accumulate the statistic data</span>
582 <span class="identifier">m_stat_info</span><span class="special">[</span><span class="identifier">name</span><span class="special">.</span><span class="identifier">get</span><span class="special">()]</span> <span class="special">+=</span> <span class="identifier">change_amount</span><span class="special">.</span><span class="identifier">get</span><span class="special">();</span>
583 <span class="special">}</span>
584 <span class="special">}</span>
585 <span class="special">}</span>
586 <span class="special">};</span>
588 <span class="comment">// The function registers two sinks - one for statistic information,</span>
589 <span class="comment">// and another one for other records</span>
590 <span class="keyword">void</span> <span class="identifier">init</span><span class="special">()</span>
591 <span class="special">{</span>
592 <span class="identifier">boost</span><span class="special">::</span><span class="identifier">shared_ptr</span><span class="special"><</span> <span class="identifier">logging</span><span class="special">::</span><span class="identifier">core</span> <span class="special">></span> <span class="identifier">core</span> <span class="special">=</span> <span class="identifier">logging</span><span class="special">::</span><span class="identifier">core</span><span class="special">::</span><span class="identifier">get</span><span class="special">();</span>
594 <span class="comment">// Create a backend and attach a stream to it</span>
595 <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">text_ostream_backend</span> <span class="special">></span> <span class="identifier">backend</span> <span class="special">=</span>
596 <span class="identifier">boost</span><span class="special">::</span><span class="identifier">make_shared</span><span class="special"><</span> <span class="identifier">sinks</span><span class="special">::</span><span class="identifier">text_ostream_backend</span> <span class="special">>();</span>
597 <span class="identifier">backend</span><span class="special">-></span><span class="identifier">add_stream</span><span class="special">(</span>
598 <span class="identifier">boost</span><span class="special">::</span><span class="identifier">shared_ptr</span><span class="special"><</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">ostream</span> <span class="special">>(</span><span class="keyword">new</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">ofstream</span><span class="special">(</span><span class="string">"test.log"</span><span class="special">)));</span>
600 <span class="comment">// Create a frontend and setup filtering</span>
601 <span class="keyword">typedef</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_ostream_backend</span> <span class="special">></span> <span class="identifier">log_sink_type</span><span class="special">;</span>
602 <span class="identifier">boost</span><span class="special">::</span><span class="identifier">shared_ptr</span><span class="special"><</span> <span class="identifier">log_sink_type</span> <span class="special">></span> <span class="identifier">log_sink</span><span class="special">(</span><span class="keyword">new</span> <span class="identifier">log_sink_type</span><span class="special">(</span><span class="identifier">backend</span><span class="special">));</span>
603 <span class="comment">// All records that don't have a "StatisticStream" attribute attached</span>
604 <span class="comment">// will go to the "test.log" file</span>
605 <span class="identifier">log_sink</span><span class="special">-></span><span class="identifier">set_filter</span><span class="special">(!</span><span class="identifier">expr</span><span class="special">::</span><span class="identifier">has_attr</span><span class="special">(</span><span class="identifier">stat_stream</span><span class="special">));</span>
607 <span class="identifier">core</span><span class="special">-></span><span class="identifier">add_sink</span><span class="special">(</span><span class="identifier">log_sink</span><span class="special">);</span>
609 <span class="comment">// Create another sink that will receive all statistic data</span>
610 <span class="keyword">typedef</span> <span class="identifier">sinks</span><span class="special">::</span><span class="identifier">synchronous_sink</span><span class="special"><</span> <span class="identifier">my_stat_accumulator</span> <span class="special">></span> <span class="identifier">stat_sink_type</span><span class="special">;</span>
611 <span class="identifier">boost</span><span class="special">::</span><span class="identifier">shared_ptr</span><span class="special"><</span> <span class="identifier">stat_sink_type</span> <span class="special">></span> <span class="identifier">stat_sink</span><span class="special">(</span><span class="keyword">new</span> <span class="identifier">stat_sink_type</span><span class="special">());</span>
612 <span class="comment">// All records with a "StatisticStream" string attribute attached</span>
613 <span class="comment">// will go to the my_stat_accumulator sink</span>
614 <span class="identifier">stat_sink</span><span class="special">-></span><span class="identifier">set_filter</span><span class="special">(</span><span class="identifier">expr</span><span class="special">::</span><span class="identifier">has_attr</span><span class="special">(</span><span class="identifier">stat_stream</span><span class="special">));</span>
616 <span class="identifier">core</span><span class="special">-></span><span class="identifier">add_sink</span><span class="special">(</span><span class="identifier">stat_sink</span><span class="special">);</span>
617 <span class="special">}</span>
619 <span class="comment">// This simple macro will simplify putting statistic data into a logger</span>
620 <span class="preprocessor">#define</span> <span class="identifier">PUT_STAT</span><span class="special">(</span><span class="identifier">lg</span><span class="special">,</span> <span class="identifier">stat_stream_name</span><span class="special">,</span> <span class="identifier">change</span><span class="special">)\</span>
621 <span class="keyword">if</span> <span class="special">(</span><span class="keyword">true</span><span class="special">)</span> <span class="special">{\</span>
622 <span class="identifier">BOOST_LOG_SCOPED_LOGGER_TAG</span><span class="special">(</span><span class="identifier">lg</span><span class="special">,</span> <span class="string">"StatisticStream"</span><span class="special">,</span> <span class="identifier">stat_stream_name</span><span class="special">);\</span>
623 <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">logging</span><span class="special">::</span><span class="identifier">add_value</span><span class="special">(</span><span class="string">"Change"</span><span class="special">,</span> <span class="special">(</span><span class="keyword">int</span><span class="special">)(</span><span class="identifier">change</span><span class="special">));\</span>
624 <span class="special">}</span> <span class="keyword">else</span> <span class="special">((</span><span class="keyword">void</span><span class="special">)</span><span class="number">0</span><span class="special">)</span>
626 <span class="keyword">void</span> <span class="identifier">logging_function</span><span class="special">()</span>
627 <span class="special">{</span>
628 <span class="identifier">src</span><span class="special">::</span><span class="identifier">logger</span> <span class="identifier">lg</span><span class="special">;</span>
630 <span class="comment">// Put a regular log record, it will go to the "test.log" file</span>
631 <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">"A regular log record"</span><span class="special">;</span>
633 <span class="comment">// Put some statistic data</span>
634 <span class="identifier">PUT_STAT</span><span class="special">(</span><span class="identifier">lg</span><span class="special">,</span> <span class="string">"StreamOne"</span><span class="special">,</span> <span class="number">10</span><span class="special">);</span>
635 <span class="identifier">PUT_STAT</span><span class="special">(</span><span class="identifier">lg</span><span class="special">,</span> <span class="string">"StreamTwo"</span><span class="special">,</span> <span class="number">20</span><span class="special">);</span>
636 <span class="identifier">PUT_STAT</span><span class="special">(</span><span class="identifier">lg</span><span class="special">,</span> <span class="string">"StreamOne"</span><span class="special">,</span> <span class="special">-</span><span class="number">5</span><span class="special">);</span>
637 <span class="special">}</span>
642 <a href="../../../../../../libs/log/example/doc/expressions_has_attr_stat_accum.cpp" target="_top">See
643 the complete code</a>.
646 In this example, log records emitted with the <code class="computeroutput"><span class="identifier">PUT_STAT</span></code>
647 macro will be directed to the <code class="computeroutput"><span class="identifier">my_stat_accumulator</span></code>
648 sink backend, which will accumulate the changes passed in the "Change"
649 attribute values. All other records (even those made through the same
650 logger) will be passed to the filter sink. This is achieved with the
651 mutually exclusive filters set for the two sinks.
654 Please note that in the example above we extended the library in two
655 ways: we defined a new sink backend <code class="computeroutput"><span class="identifier">my_stat_accumulator</span></code>
656 and a new macro <code class="computeroutput"><span class="identifier">PUT_STAT</span></code>.
657 Also note that <code class="computeroutput"><span class="identifier">has_attr</span></code>
658 can accept attribute keywords to identify the attribute to check.
661 <div class="section">
662 <div class="titlepage"><div><div><h5 class="title">
663 <a name="log.detailed.expressions.predicates.is_in_range"></a><a class="link" href="expressions.html#log.detailed.expressions.predicates.is_in_range" title="Range checking filter">Range
665 </h5></div></div></div>
666 <pre class="programlisting"><span class="preprocessor">#include</span> <span class="special"><</span><code class="computeroutput"><a class="link" href="../../expressions.html#header.boost.log.expressions.predicates.is_in_range_hpp" title="Header <boost/log/expressions/predicates/is_in_range.hpp>">boost/log/expressions/predicates/is_in_range.hpp</a></code><span class="special">></span>
669 The <code class="computeroutput"><a class="link" href="../../boost/log/expressions/is_in_ra_idm45711347192160.html" title="Function template is_in_range">is_in_range</a></code> predicate
670 checks that the attribute value fits in the half-open range (i.e. it
671 returns <code class="computeroutput"><span class="keyword">true</span></code> if the attribute
672 value <code class="computeroutput"><span class="identifier">x</span></code> satisfies the
673 following condition: <code class="computeroutput"><span class="identifier">left</span> <span class="special"><=</span> <span class="identifier">x</span> <span class="special"><</span> <span class="identifier">right</span></code>).
676 <pre class="programlisting"><span class="identifier">sink</span><span class="special">-></span><span class="identifier">set_filter</span>
677 <span class="special">(</span>
678 <span class="comment">// drops all records that have level below 3 or greater than 4</span>
679 <span class="identifier">expr</span><span class="special">::</span><span class="identifier">is_in_range</span><span class="special">(</span><span class="identifier">expr</span><span class="special">::</span><span class="identifier">attr</span><span class="special"><</span> <span class="keyword">int</span> <span class="special">>(</span><span class="string">"Severity"</span><span class="special">),</span> <span class="number">3</span><span class="special">,</span> <span class="number">5</span><span class="special">)</span>
680 <span class="special">);</span>
683 The attribute can also be identified by an attribute keyword or name
686 <pre class="programlisting"><span class="identifier">sink</span><span class="special">-></span><span class="identifier">set_filter</span>
687 <span class="special">(</span>
688 <span class="identifier">expr</span><span class="special">::</span><span class="identifier">is_in_range</span><span class="special">(</span><span class="identifier">severity</span><span class="special">,</span> <span class="number">3</span><span class="special">,</span> <span class="number">5</span><span class="special">)</span>
689 <span class="special">);</span>
691 <span class="identifier">sink</span><span class="special">-></span><span class="identifier">set_filter</span>
692 <span class="special">(</span>
693 <span class="identifier">expr</span><span class="special">::</span><span class="identifier">is_in_range</span><span class="special"><</span> <span class="keyword">int</span> <span class="special">>(</span><span class="string">"Severity"</span><span class="special">,</span> <span class="number">3</span><span class="special">,</span> <span class="number">5</span><span class="special">)</span>
694 <span class="special">);</span>
697 <div class="section">
698 <div class="titlepage"><div><div><h5 class="title">
699 <a name="log.detailed.expressions.predicates.simple_string_matching"></a><a class="link" href="expressions.html#log.detailed.expressions.predicates.simple_string_matching" title="Simple string matching filters">Simple
700 string matching filters</a>
701 </h5></div></div></div>
702 <pre class="programlisting"><span class="preprocessor">#include</span> <span class="special"><</span><code class="computeroutput"><a class="link" href="../../expressions.html#header.boost.log.expressions.predicates.begins_with_hpp" title="Header <boost/log/expressions/predicates/begins_with.hpp>">boost/log/expressions/predicates/begins_with.hpp</a></code><span class="special">></span>
703 <span class="preprocessor">#include</span> <span class="special"><</span><code class="computeroutput"><a class="link" href="../../expressions.html#header.boost.log.expressions.predicates.ends_with_hpp" title="Header <boost/log/expressions/predicates/ends_with.hpp>">boost/log/expressions/predicates/ends_with.hpp</a></code><span class="special">></span>
704 <span class="preprocessor">#include</span> <span class="special"><</span><code class="computeroutput"><a class="link" href="../../expressions.html#header.boost.log.expressions.predicates.contains_hpp" title="Header <boost/log/expressions/predicates/contains.hpp>">boost/log/expressions/predicates/contains.hpp</a></code><span class="special">></span>
707 Predicates <code class="computeroutput"><a class="link" href="../../boost/log/expressions/begins_w_idm45711347518400.html" title="Function template begins_with">begins_with</a></code>, <code class="computeroutput"><a class="link" href="../../boost/log/expressions/ends_wit_idm45711347256848.html" title="Function template ends_with">ends_with</a></code>
708 and <code class="computeroutput"><a class="link" href="../../boost/log/expressions/contains_idm45711347279296.html" title="Function template contains">contains</a></code> provide an
709 easy way of matching string attribute values. As follows from their names,
710 the functions construct filters that return <code class="computeroutput"><span class="keyword">true</span></code>
711 if an attribute value begins with, ends with or contains the specified
712 substring, respectively. The string comparison is case sensitive.
714 <pre class="programlisting"><span class="identifier">sink</span><span class="special">-></span><span class="identifier">set_filter</span>
715 <span class="special">(</span>
716 <span class="comment">// selects only records that are related to Russian web domains</span>
717 <span class="identifier">expr</span><span class="special">::</span><span class="identifier">ends_with</span><span class="special">(</span><span class="identifier">expr</span><span class="special">::</span><span class="identifier">attr</span><span class="special"><</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="special">>(</span><span class="string">"Domain"</span><span class="special">),</span> <span class="string">".ru"</span><span class="special">)</span>
718 <span class="special">);</span>
721 The attribute can also be identified by an attribute keyword or name
725 <div class="section">
726 <div class="titlepage"><div><div><h5 class="title">
727 <a name="log.detailed.expressions.predicates.advanced_string_matching"></a><a class="link" href="expressions.html#log.detailed.expressions.predicates.advanced_string_matching" title="Advanced string matching filter">Advanced
728 string matching filter</a>
729 </h5></div></div></div>
730 <pre class="programlisting"><span class="preprocessor">#include</span> <span class="special"><</span><code class="computeroutput"><a class="link" href="../../expressions.html#header.boost.log.expressions.predicates.matches_hpp" title="Header <boost/log/expressions/predicates/matches.hpp>">boost/log/expressions/predicates/matches.hpp</a></code><span class="special">></span>
732 <span class="comment">// Supporting headers</span>
733 <span class="preprocessor">#include</span> <span class="special"><</span><code class="computeroutput"><a class="link" href="../../other_libraries_support_layer.html#header.boost.log.support.regex_hpp" title="Header <boost/log/support/regex.hpp>">boost/log/support/regex.hpp</a></code><span class="special">></span>
734 <span class="preprocessor">#include</span> <span class="special"><</span><code class="computeroutput"><a class="link" href="../../other_libraries_support_layer.html#header.boost.log.support.std_regex_hpp" title="Header <boost/log/support/std_regex.hpp>">boost/log/support/std_regex.hpp</a></code><span class="special">></span>
735 <span class="preprocessor">#include</span> <span class="special"><</span><code class="computeroutput"><a class="link" href="../../other_libraries_support_layer.html#header.boost.log.support.xpressive_hpp" title="Header <boost/log/support/xpressive.hpp>">boost/log/support/xpressive.hpp</a></code><span class="special">></span>
736 <span class="preprocessor">#include</span> <span class="special"><</span><code class="computeroutput"><a class="link" href="../../other_libraries_support_layer.html#header.boost.log.support.spirit_qi_hpp" title="Header <boost/log/support/spirit_qi.hpp>">boost/log/support/spirit_qi.hpp</a></code><span class="special">></span>
737 <span class="preprocessor">#include</span> <span class="special"><</span><code class="computeroutput"><a class="link" href="../../other_libraries_support_layer.html#header.boost.log.support.spirit_classic_hpp" title="Header <boost/log/support/spirit_classic.hpp>">boost/log/support/spirit_classic.hpp</a></code><span class="special">></span>
740 The <code class="computeroutput"><a class="link" href="../../boost/log/expressions/matches_idm45711347155120.html" title="Function template matches">matches</a></code> function creates
741 a filter that apples a regular expression or a parser to a string attribute
742 value. The regular expression can be provided by <a href="http://www.boost.org/doc/libs/release/libs/regex/index.html" target="_top">Boost.Regex</a>
743 or <a href="http://www.boost.org/doc/libs/release/doc/html/xpressive.html" target="_top">Boost.Xpressive</a>.
744 Parsers from <a href="http://www.boost.org/doc/libs/release/libs/spirit/classic/index.html" target="_top">Boost.Spirit</a>
745 and <a href="http://www.boost.org/doc/libs/release/libs/spirit/doc/html/index.html" target="_top">Boost.Spirit2</a>
746 are also supported. The filter returns <code class="computeroutput"><span class="keyword">true</span></code>
747 if the regular expression matches or the parser successfully parses the
750 <div class="note"><table border="0" summary="Note">
752 <td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../../../../doc/src/images/note.png"></td>
753 <th align="left">Note</th>
755 <tr><td align="left" valign="top"><p>
756 In order to use this predicate, a corresponding supporting header should
760 <pre class="programlisting"><span class="identifier">sink</span><span class="special">-></span><span class="identifier">set_filter</span>
761 <span class="special">(</span>
762 <span class="identifier">expr</span><span class="special">::</span><span class="identifier">matches</span><span class="special">(</span><span class="identifier">expr</span><span class="special">::</span><span class="identifier">attr</span><span class="special"><</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="special">>(</span><span class="string">"Domain"</span><span class="special">),</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">regex</span><span class="special">(</span><span class="string">"www\\..*\\.ru"</span><span class="special">))</span>
763 <span class="special">);</span>
766 The attribute can also be identified by an attribute keyword or name
770 <div class="section">
771 <div class="titlepage"><div><div><h5 class="title">
772 <a name="log.detailed.expressions.predicates.channel_severity_filter"></a><a class="link" href="expressions.html#log.detailed.expressions.predicates.channel_severity_filter" title="Severity threshold per channel filter">Severity
773 threshold per channel filter</a>
774 </h5></div></div></div>
775 <pre class="programlisting"><span class="preprocessor">#include</span> <span class="special"><</span><code class="computeroutput"><a class="link" href="../../expressions.html#header.boost.log.expressions.predicates.channel_severity_filter_hpp" title="Header <boost/log/expressions/predicates/channel_severity_filter.hpp>">boost/log/expressions/predicates/channel_severity_filter.hpp</a></code><span class="special">></span>
778 This filter is aimed for a specific but commonly encountered use case.
779 The <code class="computeroutput"><a class="link" href="../../boost/log/expressions/channel_severity_filter.html" title="Function channel_severity_filter">channel_severity_filter</a></code>
780 function creates a predicate that will check log record severity levels
781 against a threshold. The predicate allows setting different thresholds
782 for different channels. The mapping between channel names and severity
783 thresholds can be filled in <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">map</span></code>
784 style by using the subscript operator or by calling <code class="computeroutput"><span class="identifier">add</span></code>
785 method on the filter itself (the <code class="computeroutput"><a class="link" href="../../boost/log/expressions/channel__idm45711347497888.html" title="Class template channel_severity_filter_actor">channel_severity_filter_actor</a></code>
786 instance). Let's see an example:
790 <pre class="programlisting"><span class="comment">// We define our own severity levels</span>
791 <span class="keyword">enum</span> <span class="identifier">severity_level</span>
792 <span class="special">{</span>
793 <span class="identifier">normal</span><span class="special">,</span>
794 <span class="identifier">notification</span><span class="special">,</span>
795 <span class="identifier">warning</span><span class="special">,</span>
796 <span class="identifier">error</span><span class="special">,</span>
797 <span class="identifier">critical</span>
798 <span class="special">};</span>
800 <span class="comment">// Define the attribute keywords</span>
801 <span class="identifier">BOOST_LOG_ATTRIBUTE_KEYWORD</span><span class="special">(</span><span class="identifier">line_id</span><span class="special">,</span> <span class="string">"LineID"</span><span class="special">,</span> <span class="keyword">unsigned</span> <span class="keyword">int</span><span class="special">)</span>
802 <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>
803 <span class="identifier">BOOST_LOG_ATTRIBUTE_KEYWORD</span><span class="special">(</span><span class="identifier">channel</span><span class="special">,</span> <span class="string">"Channel"</span><span class="special">,</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span><span class="special">)</span>
806 <span class="keyword">void</span> <span class="identifier">init</span><span class="special">()</span>
807 <span class="special">{</span>
808 <span class="comment">// Create a minimal severity table filter</span>
809 <span class="keyword">typedef</span> <span class="identifier">expr</span><span class="special">::</span><span class="identifier">channel_severity_filter_actor</span><span class="special"><</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span><span class="special">,</span> <span class="identifier">severity_level</span> <span class="special">></span> <span class="identifier">min_severity_filter</span><span class="special">;</span>
810 <span class="identifier">min_severity_filter</span> <span class="identifier">min_severity</span> <span class="special">=</span> <span class="identifier">expr</span><span class="special">::</span><span class="identifier">channel_severity_filter</span><span class="special">(</span><span class="identifier">channel</span><span class="special">,</span> <span class="identifier">severity</span><span class="special">);</span>
812 <span class="comment">// Set up the minimum severity levels for different channels</span>
813 <span class="identifier">min_severity</span><span class="special">[</span><span class="string">"general"</span><span class="special">]</span> <span class="special">=</span> <span class="identifier">notification</span><span class="special">;</span>
814 <span class="identifier">min_severity</span><span class="special">[</span><span class="string">"network"</span><span class="special">]</span> <span class="special">=</span> <span class="identifier">warning</span><span class="special">;</span>
815 <span class="identifier">min_severity</span><span class="special">[</span><span class="string">"gui"</span><span class="special">]</span> <span class="special">=</span> <span class="identifier">error</span><span class="special">;</span>
817 <span class="identifier">logging</span><span class="special">::</span><span class="identifier">add_console_log</span>
818 <span class="special">(</span>
819 <span class="identifier">std</span><span class="special">::</span><span class="identifier">clog</span><span class="special">,</span>
820 <span class="identifier">keywords</span><span class="special">::</span><span class="identifier">filter</span> <span class="special">=</span> <span class="identifier">min_severity</span> <span class="special">||</span> <span class="identifier">severity</span> <span class="special">>=</span> <span class="identifier">critical</span><span class="special">,</span>
821 <span class="identifier">keywords</span><span class="special">::</span><span class="identifier">format</span> <span class="special">=</span>
822 <span class="special">(</span>
823 <span class="identifier">expr</span><span class="special">::</span><span class="identifier">stream</span>
824 <span class="special"><<</span> <span class="identifier">line_id</span>
825 <span class="special"><<</span> <span class="string">": <"</span> <span class="special"><<</span> <span class="identifier">severity</span>
826 <span class="special"><<</span> <span class="string">"> ["</span> <span class="special"><<</span> <span class="identifier">channel</span> <span class="special"><<</span> <span class="string">"] "</span>
827 <span class="special"><<</span> <span class="identifier">expr</span><span class="special">::</span><span class="identifier">smessage</span>
828 <span class="special">)</span>
829 <span class="special">);</span>
830 <span class="special">}</span>
832 <span class="comment">// Define our logger type</span>
833 <span class="keyword">typedef</span> <span class="identifier">src</span><span class="special">::</span><span class="identifier">severity_channel_logger</span><span class="special"><</span> <span class="identifier">severity_level</span><span class="special">,</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="special">></span> <span class="identifier">logger_type</span><span class="special">;</span>
835 <span class="keyword">void</span> <span class="identifier">test_logging</span><span class="special">(</span><span class="identifier">logger_type</span><span class="special">&</span> <span class="identifier">lg</span><span class="special">,</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="keyword">const</span><span class="special">&</span> <span class="identifier">channel_name</span><span class="special">)</span>
836 <span class="special">{</span>
837 <span class="identifier">BOOST_LOG_CHANNEL_SEV</span><span class="special">(</span><span class="identifier">lg</span><span class="special">,</span> <span class="identifier">channel_name</span><span class="special">,</span> <span class="identifier">normal</span><span class="special">)</span> <span class="special"><<</span> <span class="string">"A normal severity level message"</span><span class="special">;</span>
838 <span class="identifier">BOOST_LOG_CHANNEL_SEV</span><span class="special">(</span><span class="identifier">lg</span><span class="special">,</span> <span class="identifier">channel_name</span><span class="special">,</span> <span class="identifier">notification</span><span class="special">)</span> <span class="special"><<</span> <span class="string">"A notification severity level message"</span><span class="special">;</span>
839 <span class="identifier">BOOST_LOG_CHANNEL_SEV</span><span class="special">(</span><span class="identifier">lg</span><span class="special">,</span> <span class="identifier">channel_name</span><span class="special">,</span> <span class="identifier">warning</span><span class="special">)</span> <span class="special"><<</span> <span class="string">"A warning severity level message"</span><span class="special">;</span>
840 <span class="identifier">BOOST_LOG_CHANNEL_SEV</span><span class="special">(</span><span class="identifier">lg</span><span class="special">,</span> <span class="identifier">channel_name</span><span class="special">,</span> <span class="identifier">error</span><span class="special">)</span> <span class="special"><<</span> <span class="string">"An error severity level message"</span><span class="special">;</span>
841 <span class="identifier">BOOST_LOG_CHANNEL_SEV</span><span class="special">(</span><span class="identifier">lg</span><span class="special">,</span> <span class="identifier">channel_name</span><span class="special">,</span> <span class="identifier">critical</span><span class="special">)</span> <span class="special"><<</span> <span class="string">"A critical severity level message"</span><span class="special">;</span>
842 <span class="special">}</span>
847 <a href="../../../../../../libs/log/example/doc/expressions_channel_severity_filter.cpp" target="_top">See
848 the complete code</a>.
851 The filter for the console sink is composed from the <code class="computeroutput"><a class="link" href="../../boost/log/expressions/channel__idm45711347497888.html" title="Class template channel_severity_filter_actor">channel_severity_filter_actor</a></code>
852 filter and a general severity level check. This general check will be
853 used when log records do not have a channel attribute or the channel
854 name is not one of those specified in <code class="computeroutput"><a class="link" href="../../boost/log/expressions/channel__idm45711347497888.html" title="Class template channel_severity_filter_actor">channel_severity_filter_actor</a></code>
855 initialization. It should be noted that it is possible to set the default
856 result of the threshold filter that will be used in this case; the default
857 result can be set by the <code class="computeroutput"><span class="identifier">set_default</span></code>
858 method. The <code class="computeroutput"><a class="link" href="../../boost/log/expressions/channel__idm45711347497888.html" title="Class template channel_severity_filter_actor">channel_severity_filter_actor</a></code>
859 filter is set up to limit record severity levels for channels "general",
860 "network" and "gui" - all records in these channels
861 with levels below the specified thresholds will not pass the filter and
865 The threshold filter is implemented as an equivalent to <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">map</span></code> over the channels, which means
866 that the channel value type must support partial ordering. Obviously,
867 the severity level type must also support ordering to be able to be compared
868 against thresholds. By default the predicate will use <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">less</span></code>
869 equivalent for channel name ordering and <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">greater_equal</span></code>
870 equivalent to compare severity levels. It is possible to customize the
871 ordering predicates. Consult the reference of the <code class="computeroutput"><a class="link" href="../../boost/log/expressions/channel__idm45711347497888.html" title="Class template channel_severity_filter_actor">channel_severity_filter_actor</a></code>
872 class and <code class="computeroutput"><a class="link" href="../../boost/log/expressions/channel_severity_filter.html" title="Function channel_severity_filter">channel_severity_filter</a></code>
873 generator to see the relevant template parameters.
876 <div class="section">
877 <div class="titlepage"><div><div><h5 class="title">
878 <a name="log.detailed.expressions.predicates.is_debugger_present"></a><a class="link" href="expressions.html#log.detailed.expressions.predicates.is_debugger_present" title="Debugger presence filter">Debugger
880 </h5></div></div></div>
881 <pre class="programlisting"><span class="preprocessor">#include</span> <span class="special"><</span><code class="computeroutput"><a class="link" href="../../expressions.html#header.boost.log.expressions.predicates.is_debugger_present_hpp" title="Header <boost/log/expressions/predicates/is_debugger_present.hpp>">boost/log/expressions/predicates/is_debugger_present.hpp</a></code><span class="special">></span>
884 This filter is implemented for Windows only. The <code class="computeroutput"><span class="identifier">is_debugger_present</span></code>
885 filter returns <code class="computeroutput"><span class="keyword">true</span></code> if the
886 application is run under a debugger and <code class="computeroutput"><span class="keyword">false</span></code>
887 otherwise. It does not use any attribute values from the log record.
888 This predicate is typically used with the <a class="link" href="sink_backends.html#log.detailed.sink_backends.debugger" title="Windows debugger output backend">debugger
893 <pre class="programlisting"><span class="comment">// Complete sink type</span>
894 <span class="keyword">typedef</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">debug_output_backend</span> <span class="special">></span> <span class="identifier">sink_t</span><span class="special">;</span>
896 <span class="keyword">void</span> <span class="identifier">init_logging</span><span class="special">()</span>
897 <span class="special">{</span>
898 <span class="identifier">boost</span><span class="special">::</span><span class="identifier">shared_ptr</span><span class="special"><</span> <span class="identifier">logging</span><span class="special">::</span><span class="identifier">core</span> <span class="special">></span> <span class="identifier">core</span> <span class="special">=</span> <span class="identifier">logging</span><span class="special">::</span><span class="identifier">core</span><span class="special">::</span><span class="identifier">get</span><span class="special">();</span>
900 <span class="comment">// Create the sink. The backend requires synchronization in the frontend.</span>
901 <span class="identifier">boost</span><span class="special">::</span><span class="identifier">shared_ptr</span><span class="special"><</span> <span class="identifier">sink_t</span> <span class="special">></span> <span class="identifier">sink</span><span class="special">(</span><span class="keyword">new</span> <span class="identifier">sink_t</span><span class="special">());</span>
903 <span class="comment">// Set the special filter to the frontend</span>
904 <span class="comment">// in order to skip the sink when no debugger is available</span>
905 <span class="identifier">sink</span><span class="special">-></span><span class="identifier">set_filter</span><span class="special">(</span><span class="identifier">expr</span><span class="special">::</span><span class="identifier">is_debugger_present</span><span class="special">());</span>
907 <span class="identifier">core</span><span class="special">-></span><span class="identifier">add_sink</span><span class="special">(</span><span class="identifier">sink</span><span class="special">);</span>
908 <span class="special">}</span>
913 <a href="../../../../../../libs/log/example/doc/sinks_debugger.cpp" target="_top">See the complete
918 <div class="section">
919 <div class="titlepage"><div><div><h4 class="title">
920 <a name="log.detailed.expressions.formatters"></a><a class="link" href="expressions.html#log.detailed.expressions.formatters" title="Formatting expressions">Formatting expressions</a>
921 </h4></div></div></div>
922 <div class="toc"><dl class="toc">
923 <dt><span class="section"><a href="expressions.html#log.detailed.expressions.formatters.date_time">Date
924 and time formatter</a></span></dt>
925 <dt><span class="section"><a href="expressions.html#log.detailed.expressions.formatters.named_scope">Named
926 scope formatter</a></span></dt>
927 <dt><span class="section"><a href="expressions.html#log.detailed.expressions.formatters.conditional">Conditional
928 formatters</a></span></dt>
929 <dt><span class="section"><a href="expressions.html#log.detailed.expressions.formatters.auto_newline">Automatic
930 newline insertion</a></span></dt>
931 <dt><span class="section"><a href="expressions.html#log.detailed.expressions.formatters.decorators">Character
932 decorators</a></span></dt>
935 As was noted in the <a class="link" href="../tutorial/formatters.html" title="Log record formatting">tutorial</a>,
936 the library provides several ways of expressing formatters, most notable
937 being with a stream-style syntax and <a href="http://www.boost.org/doc/libs/release/libs/format/index.html" target="_top">Boost.Format</a>-style
938 expression. Which of the two formats is chosen is determined by the appropriate
939 anchor expression. To use stream-style syntax one should begin the formatter
940 definition with the <code class="computeroutput"><span class="identifier">stream</span></code>
943 <pre class="programlisting"><span class="preprocessor">#include</span> <span class="special"><</span><code class="computeroutput"><a class="link" href="../../expressions.html#header.boost.log.expressions.formatters.stream_hpp" title="Header <boost/log/expressions/formatters/stream.hpp>">boost/log/expressions/formatters/stream.hpp</a></code><span class="special">></span>
945 <span class="identifier">sink</span><span class="special">-></span><span class="identifier">set_formatter</span><span class="special">(</span><span class="identifier">expr</span><span class="special">::</span><span class="identifier">stream</span> <span class="special"><<</span> <span class="identifier">expr1</span> <span class="special"><<</span> <span class="identifier">expr2</span> <span class="special"><<</span> <span class="special">...</span> <span class="special"><<</span> <span class="identifier">exprN</span><span class="special">);</span>
948 Here expressions <code class="computeroutput"><span class="identifier">expr1</span></code>
949 through <code class="computeroutput"><span class="identifier">exprN</span></code> may be either
950 manipulators, described in this section, or other expressions resulting
951 in an object that supports putting into an STL-stream.
954 To use <a href="http://www.boost.org/doc/libs/release/libs/format/index.html" target="_top">Boost.Format</a>-style
955 syntax one should use <code class="computeroutput"><span class="identifier">format</span></code>
958 <pre class="programlisting"><span class="preprocessor">#include</span> <span class="special"><</span><code class="computeroutput"><a class="link" href="../../expressions.html#header.boost.log.expressions.formatters.format_hpp" title="Header <boost/log/expressions/formatters/format.hpp>">boost/log/expressions/formatters/format.hpp</a></code><span class="special">></span>
960 <span class="identifier">sink</span><span class="special">-></span><span class="identifier">set_formatter</span><span class="special">(</span><span class="identifier">expr</span><span class="special">::</span><span class="identifier">format</span><span class="special">(</span><span class="string">"format string"</span><span class="special">)</span> <span class="special">%</span> <span class="identifier">expr1</span> <span class="special">%</span> <span class="identifier">expr2</span> <span class="special">%</span> <span class="special">...</span> <span class="special">%</span> <span class="identifier">exprN</span><span class="special">);</span>
963 The format string passed to the <code class="computeroutput"><span class="identifier">format</span></code>
964 keyword should contain positional placeholders for the appropriate expressions.
965 In the case of wide-character logging the format string should be wide.
966 Expressions <code class="computeroutput"><span class="identifier">expr1</span></code> through
967 <code class="computeroutput"><span class="identifier">exprN</span></code> have the same meaning
968 as in stream-like variant. It should be noted though that using stream-like
969 syntax usually results in a faster formatter than the one constructed with
970 the <code class="computeroutput"><span class="identifier">format</span></code> keyword.
973 Another useful way of expressing formatters is by using string templates.
974 This part of the library is described in <a class="link" href="utilities.html#log.detailed.utilities.setup.filter_formatter" title="Filter and formatter parsers">this</a>
975 section and is mostly intended to support initialization from the application
978 <div class="section">
979 <div class="titlepage"><div><div><h5 class="title">
980 <a name="log.detailed.expressions.formatters.date_time"></a><a class="link" href="expressions.html#log.detailed.expressions.formatters.date_time" title="Date and time formatter">Date
981 and time formatter</a>
982 </h5></div></div></div>
983 <pre class="programlisting"><span class="preprocessor">#include</span> <span class="special"><</span><code class="computeroutput"><a class="link" href="../../expressions.html#header.boost.log.expressions.formatters.date_time_hpp" title="Header <boost/log/expressions/formatters/date_time.hpp>">boost/log/expressions/formatters/date_time.hpp</a></code><span class="special">></span>
985 <span class="comment">// Supporting headers</span>
986 <span class="preprocessor">#include</span> <span class="special"><</span><code class="computeroutput"><a class="link" href="../../other_libraries_support_layer.html#header.boost.log.support.date_time_hpp" title="Header <boost/log/support/date_time.hpp>">boost/log/support/date_time.hpp</a></code><span class="special">></span>
989 The library provides the <code class="computeroutput"><a class="link" href="../../boost/log/expressions/format_d_idm45711347922352.html" title="Function template format_date_time">format_date_time</a></code> formatter
990 dedicated to date and time-related attribute value types. The function
991 accepts the attribute value name and the format string compatible with
992 <a href="http://www.boost.org/doc/libs/release/doc/html/date_time.html" target="_top">Boost.DateTime</a>.
994 <pre class="programlisting"><span class="identifier">sink</span><span class="special">-></span><span class="identifier">set_formatter</span>
995 <span class="special">(</span>
996 <span class="identifier">expr</span><span class="special">::</span><span class="identifier">stream</span> <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">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><span class="string">"TimeStamp"</span><span class="special">,</span> <span class="string">"%Y-%m-%d %H:%M:%S"</span><span class="special">)</span>
997 <span class="special">);</span>
1000 The attribute value can alternatively be identified with the <a class="link" href="expressions.html#log.detailed.expressions.attr" title="Generic attribute placeholder"><code class="computeroutput"><span class="identifier">attr</span></code></a> placeholder or the <a class="link" href="expressions.html#log.detailed.expressions.attr_keywords" title="Defining attribute keywords">attribute keyword</a>.
1003 The following placeholders are supported in the format string:
1006 <a name="log.detailed.expressions.formatters.date_time.date_format_placeholders"></a><p class="title"><b>Table 1.2. Date format placeholders</b></p>
1007 <div class="table-contents"><table class="table" summary="Date format placeholders">
1039 Abbreviated weekday name
1073 Abbreviated month name
1078 "Feb" => February
1107 Numeric day of month with leading zero
1124 Numeric day of month with leading space
1141 Numeric month, 01-12
1158 Numeric day of week, 1-7
1204 <br class="table-break"><div class="table">
1205 <a name="log.detailed.expressions.formatters.date_time.time_format_placeholders"></a><p class="title"><b>Table 1.3. Time format placeholders</b></p>
1206 <div class="table-contents"><table class="table" summary="Time format placeholders">
1238 Fractional seconds with leading zeros
1255 Hours in 24 hour clock or hours in time duration types with
1256 leading zero if less than 10
1273 Hours in 12 hour clock with leading zero if less than 10
1290 Hours in 24 hour clock or hours in time duration types with
1291 leading space if less than 10
1308 Hours in 12 hour clock with leading space if less than 10
1342 AM/PM mark, uppercase
1359 AM/PM mark, lowercase
1381 "-0700" => Mountain Standard Time
1393 Extended ISO time zone
1398 "-05:00" => Eastern Standard Time
1422 <br class="table-break"><div class="table">
1423 <a name="log.detailed.expressions.formatters.date_time.miscellaneous_placeholders"></a><p class="title"><b>Table 1.4. Miscellaneous placeholders</b></p>
1424 <div class="table-contents"><table class="table" summary="Miscellaneous placeholders">
1456 Negative sign in case of time duration, if the duration is
1474 Sign of time duration, even if positive
1491 An escaped percent sign
1508 Extended ISO time, equivalent to "%H:%M:%S"
1520 <br class="table-break"><p>
1521 Note that in order to use this formatter you will also have to include
1522 a supporting header. When <code class="computeroutput"><a class="link" href="../../other_libraries_support_layer.html#header.boost.log.support.date_time_hpp" title="Header <boost/log/support/date_time.hpp>">boost/log/support/date_time.hpp</a></code>
1523 is included, the formatter supports the following types of <a href="http://www.boost.org/doc/libs/release/doc/html/date_time.html" target="_top">Boost.DateTime</a>:
1525 <div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
1526 <li class="listitem">
1527 Date and time types: <code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">posix_time</span><span class="special">::</span><span class="identifier">ptime</span></code>
1528 and <code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">local_time</span><span class="special">::</span><span class="identifier">local_date_time</span></code>.
1530 <li class="listitem">
1531 Gregorian date type: <code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">gregorian</span><span class="special">::</span><span class="identifier">date</span></code>.
1533 <li class="listitem">
1534 Time duration types: <code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">posix_time</span><span class="special">::</span><span class="identifier">time_duration</span></code>
1535 as well as all the specialized time units such as <code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">posix_time</span><span class="special">::</span><span class="identifier">seconds</span></code>,
1536 including subsecond units.
1538 <li class="listitem">
1539 Date duration types: <code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">gregorian</span><span class="special">::</span><span class="identifier">date_duration</span></code>.
1542 <div class="tip"><table border="0" summary="Tip">
1544 <td rowspan="2" align="center" valign="top" width="25"><img alt="[Tip]" src="../../../../../../doc/src/images/tip.png"></td>
1545 <th align="left">Tip</th>
1547 <tr><td align="left" valign="top"><p>
1548 <a href="http://www.boost.org/doc/libs/release/doc/html/date_time.html" target="_top">Boost.DateTime</a>
1549 already provides formatting functionality implemented as a number of
1550 locale facets. This functionality can be used instead of this formatter,
1551 although the formatter is expected to provide better performance.
1555 <div class="section">
1556 <div class="titlepage"><div><div><h5 class="title">
1557 <a name="log.detailed.expressions.formatters.named_scope"></a><a class="link" href="expressions.html#log.detailed.expressions.formatters.named_scope" title="Named scope formatter">Named
1559 </h5></div></div></div>
1560 <pre class="programlisting"><span class="preprocessor">#include</span> <span class="special"><</span><code class="computeroutput"><a class="link" href="../../expressions.html#header.boost.log.expressions.formatters.named_scope_hpp" title="Header <boost/log/expressions/formatters/named_scope.hpp>">boost/log/expressions/formatters/named_scope.hpp</a></code><span class="special">></span>
1563 The formatter <code class="computeroutput"><a class="link" href="../../boost/log/expressions/format_n_idm45711347725584.html" title="Function template format_named_scope">format_named_scope</a></code> is
1564 intended to add support for flexible formatting of the <a class="link" href="attributes.html#log.detailed.attributes.named_scope" title="Named scopes">named
1565 scope</a> attribute values. The basic usage is quite straightforward
1566 and its result is similar to what <a class="link" href="expressions.html#log.detailed.expressions.attr" title="Generic attribute placeholder"><code class="computeroutput"><span class="identifier">attr</span></code></a> provides:
1568 <pre class="programlisting"><span class="comment">// Puts the scope stack from outer ones towards inner ones: outer scope -> inner scope</span>
1569 <span class="identifier">sink</span><span class="special">-></span><span class="identifier">set_formatter</span><span class="special">(</span><span class="identifier">expr</span><span class="special">::</span><span class="identifier">stream</span> <span class="special"><<</span> <span class="identifier">expr</span><span class="special">::</span><span class="identifier">format_named_scope</span><span class="special">(</span><span class="string">"Scopes"</span><span class="special">,</span> <span class="string">"%n"</span><span class="special">));</span>
1572 The first argument names the attribute and the second is the format string.
1573 The string can contain the following placeholders:
1576 <a name="log.detailed.expressions.formatters.named_scope.named_scope_format_placeholders"></a><p class="title"><b>Table 1.5. Named scope format placeholders</b></p>
1577 <div class="table-contents"><table class="table" summary="Named scope format placeholders">
1626 Function name, if the scope is denoted with <code class="computeroutput"><span class="identifier">BOOST_LOG_FUNCTION</span></code>,
1627 otherwise the full scope name. See the note below.
1644 Function name, without the function scope, if the scope is
1645 denoted with <code class="computeroutput"><span class="identifier">BOOST_LOG_FUNCTION</span></code>,
1646 otherwise the full scope name. See the note below.
1663 Source file name of the scope
1668 "/home/user/project/foo.cpp"
1680 Source file name of the scope, without the path
1697 Line number in the source file
1709 <br class="table-break"><div class="note"><table border="0" summary="Note">
1711 <td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../../../../doc/src/images/note.png"></td>
1712 <th align="left">Note</th>
1714 <tr><td align="left" valign="top"><p>
1715 As described in the <a class="link" href="attributes.html#log.detailed.attributes.named_scope" title="Named scopes">named
1716 scope</a> attribute description, it is possible to use <code class="computeroutput"><span class="identifier">BOOST_LOG_FUNCTION</span></code> macro to automatically
1717 generate scope names from the enclosing function name. Unfortunately,
1718 the actual format of the generated strings is compiler-dependent and
1719 in many cases it includes the complete signature of the function. When
1720 "%c" or "%C" format flag is specified, the library
1721 attempts to parse the generated string to extract the function name.
1722 Since C++ syntax is very context dependent and complex, it is not possible
1723 to parse function signature correctly in all cases, so the library
1724 is basically guessing. Depending on the string format, this may fail
1725 or produce incorrect results. In particular, type conversion operators
1726 can pose problems for the parser. In case if the parser fails to recognize
1727 the function signature the library falls back to using the whole string
1728 (i.e. behave equivalent to the "%n" flag). To alleviate the
1729 problem the user can replace the problematic <code class="computeroutput"><span class="identifier">BOOST_LOG_FUNCTION</span></code>
1730 usage with the <code class="computeroutput"><span class="identifier">BOOST_LOG_NAMED_SCOPE</span></code>
1731 macro and explicitly write the desired scope name. Scope names denoted
1732 with <code class="computeroutput"><span class="identifier">BOOST_LOG_NAMED_SCOPE</span></code>
1733 will not be interpreted by the library and will be output as is. In
1734 general, for portability and runtime performance reasons it is preferable
1735 to always use <code class="computeroutput"><span class="identifier">BOOST_LOG_NAMED_SCOPE</span></code>
1736 and "%n" format flag.
1740 While the format string describes the presentation of each named scope
1741 in the list, the following named arguments allow to customize the list
1742 traversal and formatting:
1744 <div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
1745 <li class="listitem">
1746 <code class="computeroutput"><span class="identifier">format</span></code>. The named
1747 scope format string, as described above. This parameter is used to
1748 specify the format when other named parameters are used.
1750 <li class="listitem">
1751 <code class="computeroutput"><span class="identifier">iteration</span></code>. The argument
1752 describes the direction of iteration through scopes. Can have values
1753 <code class="computeroutput"><span class="identifier">forward</span></code> (default)
1754 or <code class="computeroutput"><span class="identifier">reverse</span></code>.
1756 <li class="listitem">
1757 <code class="computeroutput"><span class="identifier">delimiter</span></code>. The argument
1758 can be used to specify the delimiters between scopes. The default
1759 delimiter depends on the <code class="computeroutput"><span class="identifier">iteration</span></code>
1760 argument. If <code class="computeroutput"><span class="identifier">iteration</span>
1761 <span class="special">==</span> <span class="identifier">forward</span></code>
1762 the default <code class="computeroutput"><span class="identifier">delimiter</span></code>
1763 will be "->", otherwise it will be "<-".
1765 <li class="listitem">
1766 <code class="computeroutput"><span class="identifier">depth</span></code>. The argument
1767 can be used to limit the number of scopes to put to log. The formatter
1768 will print <code class="computeroutput"><span class="identifier">depth</span></code>
1769 innermost scopes and, if there are more scopes left, append an ellipsis
1770 to the written sequence. By default the formatter will write all
1773 <li class="listitem">
1774 <code class="computeroutput"><span class="identifier">incomplete_marker</span></code>.
1775 The argument can be used to specify the string that is used to indicate
1776 that the list has been limited by the <code class="computeroutput"><span class="identifier">depth</span></code>
1777 argument. By default the "..." string is used as the marker.
1779 <li class="listitem">
1780 <code class="computeroutput"><span class="identifier">empty_marker</span></code>. The
1781 argument can be used to specify the string to output in case if the
1782 scope list is empty. By default nothing is output in this case.
1786 Here are a few usage examples:
1788 <pre class="programlisting"><span class="comment">// Puts the scope stack in reverse order:</span>
1789 <span class="comment">// inner scope (file:line) <- outer scope (file:line)</span>
1790 <span class="identifier">sink</span><span class="special">-></span><span class="identifier">set_formatter</span>
1791 <span class="special">(</span>
1792 <span class="identifier">expr</span><span class="special">::</span><span class="identifier">stream</span>
1793 <span class="special"><<</span> <span class="identifier">expr</span><span class="special">::</span><span class="identifier">format_named_scope</span><span class="special">(</span>
1794 <span class="string">"Scopes"</span><span class="special">,</span>
1795 <span class="identifier">keywords</span><span class="special">::</span><span class="identifier">format</span> <span class="special">=</span> <span class="string">"%n (%f:%l)"</span><span class="special">,</span>
1796 <span class="identifier">keywords</span><span class="special">::</span><span class="identifier">iteration</span> <span class="special">=</span> <span class="identifier">expr</span><span class="special">::</span><span class="identifier">reverse</span><span class="special">)</span>
1797 <span class="special">);</span>
1799 <span class="comment">// Puts the scope stack in reverse order with a custom delimiter:</span>
1800 <span class="comment">// inner scope | outer scope</span>
1801 <span class="identifier">sink</span><span class="special">-></span><span class="identifier">set_formatter</span>
1802 <span class="special">(</span>
1803 <span class="identifier">expr</span><span class="special">::</span><span class="identifier">stream</span>
1804 <span class="special"><<</span> <span class="identifier">expr</span><span class="special">::</span><span class="identifier">format_named_scope</span><span class="special">(</span>
1805 <span class="string">"Scopes"</span><span class="special">,</span>
1806 <span class="identifier">keywords</span><span class="special">::</span><span class="identifier">format</span> <span class="special">=</span> <span class="string">"%n"</span><span class="special">,</span>
1807 <span class="identifier">keywords</span><span class="special">::</span><span class="identifier">iteration</span> <span class="special">=</span> <span class="identifier">expr</span><span class="special">::</span><span class="identifier">reverse</span><span class="special">,</span>
1808 <span class="identifier">keywords</span><span class="special">::</span><span class="identifier">delimiter</span> <span class="special">=</span> <span class="string">" | "</span><span class="special">)</span>
1809 <span class="special">);</span>
1811 <span class="comment">// Puts the scope stack in forward order, no more than 2 inner scopes:</span>
1812 <span class="comment">// ... outer scope -> inner scope</span>
1813 <span class="identifier">sink</span><span class="special">-></span><span class="identifier">set_formatter</span>
1814 <span class="special">(</span>
1815 <span class="identifier">expr</span><span class="special">::</span><span class="identifier">stream</span>
1816 <span class="special"><<</span> <span class="identifier">expr</span><span class="special">::</span><span class="identifier">format_named_scope</span><span class="special">(</span>
1817 <span class="string">"Scopes"</span><span class="special">,</span>
1818 <span class="identifier">keywords</span><span class="special">::</span><span class="identifier">format</span> <span class="special">=</span> <span class="string">"%n"</span><span class="special">,</span>
1819 <span class="identifier">keywords</span><span class="special">::</span><span class="identifier">iteration</span> <span class="special">=</span> <span class="identifier">expr</span><span class="special">::</span><span class="identifier">forward</span><span class="special">,</span>
1820 <span class="identifier">keywords</span><span class="special">::</span><span class="identifier">depth</span> <span class="special">=</span> <span class="number">2</span><span class="special">)</span>
1821 <span class="special">);</span>
1823 <span class="comment">// Puts the scope stack in reverse order, no more than 2 inner scopes:</span>
1824 <span class="comment">// inner scope <- outer scope <<and more>>...</span>
1825 <span class="identifier">sink</span><span class="special">-></span><span class="identifier">set_formatter</span>
1826 <span class="special">(</span>
1827 <span class="identifier">expr</span><span class="special">::</span><span class="identifier">stream</span>
1828 <span class="special"><<</span> <span class="identifier">expr</span><span class="special">::</span><span class="identifier">format_named_scope</span><span class="special">(</span>
1829 <span class="string">"Scopes"</span><span class="special">,</span>
1830 <span class="identifier">keywords</span><span class="special">::</span><span class="identifier">format</span> <span class="special">=</span> <span class="string">"%n"</span><span class="special">,</span>
1831 <span class="identifier">keywords</span><span class="special">::</span><span class="identifier">iteration</span> <span class="special">=</span> <span class="identifier">expr</span><span class="special">::</span><span class="identifier">reverse</span><span class="special">,</span>
1832 <span class="identifier">keywords</span><span class="special">::</span><span class="identifier">incomplete_marker</span> <span class="special">=</span> <span class="string">" <<and more>>..."</span>
1833 <span class="identifier">keywords</span><span class="special">::</span><span class="identifier">depth</span> <span class="special">=</span> <span class="number">2</span><span class="special">)</span>
1834 <span class="special">);</span>
1836 <div class="tip"><table border="0" summary="Tip">
1838 <td rowspan="2" align="center" valign="top" width="25"><img alt="[Tip]" src="../../../../../../doc/src/images/tip.png"></td>
1839 <th align="left">Tip</th>
1841 <tr><td align="left" valign="top"><p>
1842 An empty string can be specified as the <code class="computeroutput"><span class="identifier">incomplete_marker</span></code>
1843 parameter, in which case there will be no indication that the list
1848 <div class="section">
1849 <div class="titlepage"><div><div><h5 class="title">
1850 <a name="log.detailed.expressions.formatters.conditional"></a><a class="link" href="expressions.html#log.detailed.expressions.formatters.conditional" title="Conditional formatters">Conditional
1852 </h5></div></div></div>
1853 <pre class="programlisting"><span class="preprocessor">#include</span> <span class="special"><</span><code class="computeroutput"><a class="link" href="../../expressions.html#header.boost.log.expressions.formatters.if_hpp" title="Header <boost/log/expressions/formatters/if.hpp>">boost/log/expressions/formatters/if.hpp</a></code><span class="special">></span>
1856 There are cases when one would want to check some condition about the
1857 log record and format it depending on that condition. One example of
1858 such a need is formatting an attribute value depending on its runtime
1859 type. The general syntax of the conditional formatter is as follows:
1861 <pre class="programlisting"><span class="identifier">expr</span><span class="special">::</span><span class="identifier">if_</span> <span class="special">(</span><span class="identifier">filter</span><span class="special">)</span>
1862 <span class="special">[</span>
1863 <span class="identifier">true_formatter</span>
1864 <span class="special">]</span>
1865 <span class="special">.</span><span class="identifier">else_</span>
1866 <span class="special">[</span>
1867 <span class="identifier">false_formatter</span>
1868 <span class="special">]</span>
1871 Those familiar with <a href="http://www.boost.org/doc/libs/release/libs/phoenix/doc/html/index.html" target="_top">Boost.Phoenix</a>
1872 lambda expressions will find this syntax quite familiar. The <code class="computeroutput"><span class="identifier">filter</span></code> argument is a filter that is
1873 applied to the record being formatted. If it returns <code class="computeroutput"><span class="keyword">true</span></code>,
1874 the <code class="computeroutput"><span class="identifier">true_formatter</span></code> is
1875 executed, otherwise <code class="computeroutput"><span class="identifier">false_formatter</span></code>
1876 is executed. The <code class="computeroutput"><span class="identifier">else_</span></code>
1877 section with <code class="computeroutput"><span class="identifier">false_formatter</span></code>
1878 is optional. If it is omitted and <code class="computeroutput"><span class="identifier">filter</span></code>
1879 yields <code class="computeroutput"><span class="keyword">false</span></code>, no formatter
1880 is executed. Here is an example:
1882 <pre class="programlisting"><span class="identifier">sink</span><span class="special">-></span><span class="identifier">set_formatter</span>
1883 <span class="special">(</span>
1884 <span class="identifier">expr</span><span class="special">::</span><span class="identifier">stream</span>
1885 <span class="comment">// First, put the current time</span>
1886 <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="string">"TimeStamp"</span><span class="special">,</span> <span class="string">"%Y-%m-%d %H:%M:%S.%f"</span><span class="special">)</span> <span class="special"><<</span> <span class="string">" "</span>
1887 <span class="special"><<</span> <span class="identifier">expr</span><span class="special">::</span><span class="identifier">if_</span> <span class="special">(</span><span class="identifier">expr</span><span class="special">::</span><span class="identifier">has_attr</span><span class="special"><</span> <span class="keyword">int</span> <span class="special">>(</span><span class="string">"ID"</span><span class="special">))</span>
1888 <span class="special">[</span>
1889 <span class="comment">// if "ID" is present then put it to the record</span>
1890 <span class="identifier">expr</span><span class="special">::</span><span class="identifier">stream</span> <span class="special"><<</span> <span class="identifier">expr</span><span class="special">::</span><span class="identifier">attr</span><span class="special"><</span> <span class="keyword">int</span> <span class="special">>(</span><span class="string">"ID"</span><span class="special">)</span>
1891 <span class="special">]</span>
1892 <span class="special">.</span><span class="identifier">else_</span>
1893 <span class="special">[</span>
1894 <span class="comment">// otherwise put a missing marker</span>
1895 <span class="identifier">expr</span><span class="special">::</span><span class="identifier">stream</span> <span class="special"><<</span> <span class="string">"--"</span>
1896 <span class="special">]</span>
1897 <span class="comment">// and after that goes the log record text</span>
1898 <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>
1899 <span class="special">);</span>
1902 <div class="section">
1903 <div class="titlepage"><div><div><h5 class="title">
1904 <a name="log.detailed.expressions.formatters.auto_newline"></a><a class="link" href="expressions.html#log.detailed.expressions.formatters.auto_newline" title="Automatic newline insertion">Automatic
1905 newline insertion</a>
1906 </h5></div></div></div>
1907 <pre class="programlisting"><span class="preprocessor">#include</span> <span class="special"><</span><code class="computeroutput"><a class="link" href="../../expressions.html#header.boost.log.expressions.formatters.auto_newline_hpp" title="Header <boost/log/expressions/formatters/auto_newline.hpp>">boost/log/expressions/formatters/auto_newline.hpp</a></code><span class="special">></span>
1910 This is an adaptation of the <a class="link" href="utilities.html#log.detailed.utilities.manipulators.auto_newline" title="Automatic newline insertion"><code class="computeroutput"><span class="identifier">auto_newline</span></code> manipulator</a> for
1911 formatter expressions. The <code class="computeroutput"><span class="identifier">auto_newline</span></code>
1912 formatter can be useful, for example, if log messages generated by one
1913 source are terminated with a newline character (and that behavior cannot
1914 be changed easily), and other messages are not. The formatter will ensure
1915 that all messages are reliably terminated with a newline and there are
1916 no duplicate newline characters. Like the manipulator, it will insert
1917 a newline unless the last character inserted into the stream before it
1918 was a newline. For example:
1920 <pre class="programlisting"><span class="identifier">sink</span><span class="special">-></span><span class="identifier">set_formatter</span>
1921 <span class="special">(</span>
1922 <span class="identifier">expr</span><span class="special">::</span><span class="identifier">stream</span>
1923 <span class="comment">// Ensure that the sink outputs one message per line,</span>
1924 <span class="comment">// regardless whether the message itself ends with a newline or not</span>
1925 <span class="special"><<</span> <span class="identifier">expr</span><span class="special">::</span><span class="identifier">message</span> <span class="special"><<</span> <span class="identifier">expr</span><span class="special">::</span><span class="identifier">auto_newline</span>
1926 <span class="special">);</span>
1929 <div class="section">
1930 <div class="titlepage"><div><div><h5 class="title">
1931 <a name="log.detailed.expressions.formatters.decorators"></a><a class="link" href="expressions.html#log.detailed.expressions.formatters.decorators" title="Character decorators">Character
1933 </h5></div></div></div>
1935 There are times when one would like to additionally post-process the
1936 composed string before passing it to the sink backend. For example, in
1937 order to store log into an XML file the formatted log record should be
1938 checked for special characters that have a special meaning in XML documents.
1939 This is where decorators step in.
1941 <div class="note"><table border="0" summary="Note">
1943 <td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../../../../doc/src/images/note.png"></td>
1944 <th align="left">Note</th>
1946 <tr><td align="left" valign="top"><p>
1947 Unlike most other formatters, decorators are dependent on the character
1948 type of the formatted output and this type cannot be deduced from the
1949 decorated formatter. By default, the character type is assumed to be
1950 <code class="computeroutput"><span class="keyword">char</span></code>. If the formatter
1951 is used to compose a wide-character string, prepend the decorator name
1952 with the <code class="computeroutput"><span class="identifier">w</span></code> letter (e.g.
1953 use <code class="computeroutput"><span class="identifier">wxml_decor</span></code> instead
1954 of <code class="computeroutput"><span class="identifier">xml_decor</span></code>). Also,
1955 for each decorator there is a generator function that accepts the character
1956 type as a template parameter; the function is named similarly to the
1957 decorator prepended with the <code class="computeroutput"><span class="identifier">make_</span></code>
1958 prefix (e.g. <code class="computeroutput"><span class="identifier">make_xml_decor</span></code>).
1961 <div class="section">
1962 <div class="titlepage"><div><div><h6 class="title">
1963 <a name="log.detailed.expressions.formatters.decorators.xml"></a><a class="link" href="expressions.html#log.detailed.expressions.formatters.decorators.xml" title="XML character decorator">XML
1964 character decorator</a>
1965 </h6></div></div></div>
1966 <pre class="programlisting"><span class="preprocessor">#include</span> <span class="special"><</span><code class="computeroutput"><a class="link" href="../../expressions.html#header.boost.log.expressions.formatters.xml_decorator_hpp" title="Header <boost/log/expressions/formatters/xml_decorator.hpp>">boost/log/expressions/formatters/xml_decorator.hpp</a></code><span class="special">></span>
1969 This decorator replaces XML special characters (&, <, >,
1970 " and ') with the corresponding tokens (<code class="computeroutput"><span class="special">&</span><span class="identifier">amp</span><span class="special">;</span></code>,
1971 <code class="computeroutput"><span class="special">&</span><span class="identifier">lt</span><span class="special">;</span></code>, <code class="computeroutput"><span class="special">&</span><span class="identifier">gt</span><span class="special">;</span></code>,
1972 <code class="computeroutput"><span class="special">&</span><span class="identifier">quot</span><span class="special">;</span></code> and <code class="computeroutput"><span class="special">&</span><span class="identifier">apos</span><span class="special">;</span></code>,
1973 correspondingly). The usage is as follows:
1975 <pre class="programlisting"><span class="identifier">xml_sink</span><span class="special">-></span><span class="identifier">set_formatter</span>
1976 <span class="special">(</span>
1977 <span class="comment">// Apply the decoration to the whole formatted record</span>
1978 <span class="identifier">expr</span><span class="special">::</span><span class="identifier">stream</span> <span class="special"><<</span> <span class="identifier">expr</span><span class="special">::</span><span class="identifier">xml_decor</span>
1979 <span class="special">[</span>
1980 <span class="identifier">expr</span><span class="special">::</span><span class="identifier">stream</span> <span class="special"><<</span> <span class="identifier">expr</span><span class="special">::</span><span class="identifier">message</span>
1981 <span class="special">]</span>
1982 <span class="special">);</span>
1985 Since character decorators are yet another kind of formatters, it's
1986 fine to use them in other contexts where formatters are appropriate.
1987 For example, this is also a valid example:
1989 <pre class="programlisting"><span class="identifier">xml_sink</span><span class="special">-></span><span class="identifier">set_formatter</span>
1990 <span class="special">(</span>
1991 <span class="identifier">expr</span><span class="special">::</span><span class="identifier">format</span><span class="special">(</span><span class="string">"<message>%1%: %2%</message>"</span><span class="special">)</span>
1992 <span class="special">%</span> <span class="identifier">expr</span><span class="special">::</span><span class="identifier">attr</span><span class="special"><</span> <span class="keyword">unsigned</span> <span class="keyword">int</span> <span class="special">>(</span><span class="string">"LineID"</span><span class="special">)</span>
1993 <span class="special">%</span> <span class="identifier">expr</span><span class="special">::</span><span class="identifier">xml_decor</span><span class="special">[</span> <span class="identifier">expr</span><span class="special">::</span><span class="identifier">stream</span> <span class="special"><<</span> <span class="identifier">expr</span><span class="special">::</span><span class="identifier">message</span> <span class="special">];</span> <span class="comment">// Only decorate the message text</span>
1994 <span class="special">);</span>
1997 There is an example of the library set up for logging into an XML file,
1998 see <a href="../../../../../../libs/log/example/doc/sinks_xml_file.cpp" target="_top">here</a>.
2001 <div class="section">
2002 <div class="titlepage"><div><div><h6 class="title">
2003 <a name="log.detailed.expressions.formatters.decorators.csv"></a><a class="link" href="expressions.html#log.detailed.expressions.formatters.decorators.csv" title="CSV character decorator">CSV
2004 character decorator</a>
2005 </h6></div></div></div>
2006 <pre class="programlisting"><span class="preprocessor">#include</span> <span class="special"><</span><code class="computeroutput"><a class="link" href="../../expressions.html#header.boost.log.expressions.formatters.csv_decorator_hpp" title="Header <boost/log/expressions/formatters/csv_decorator.hpp>">boost/log/expressions/formatters/csv_decorator.hpp</a></code><span class="special">></span>
2009 This decorator allows to ensure that the resulting string conforms
2010 to the <a href="http://en.wikipedia.org/wiki/Comma-separated_values" target="_top">CSV</a>
2011 format requirements. In particular, it duplicates the quote characters
2012 in the formatted string.
2014 <pre class="programlisting"><span class="identifier">csv_sink</span><span class="special">-></span><span class="identifier">set_formatter</span>
2015 <span class="special">(</span>
2016 <span class="identifier">expr</span><span class="special">::</span><span class="identifier">stream</span>
2017 <span class="special"><<</span> <span class="identifier">expr</span><span class="special">::</span><span class="identifier">attr</span><span class="special"><</span> <span class="keyword">unsigned</span> <span class="keyword">int</span> <span class="special">>(</span><span class="string">"LineID"</span><span class="special">)</span> <span class="special"><<</span> <span class="string">","</span>
2018 <span class="special"><<</span> <span class="identifier">expr</span><span class="special">::</span><span class="identifier">csv_decor</span><span class="special">[</span> <span class="identifier">expr</span><span class="special">::</span><span class="identifier">stream</span> <span class="special"><<</span> <span class="identifier">expr</span><span class="special">::</span><span class="identifier">attr</span><span class="special"><</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="special">>(</span><span class="string">"Tag"</span><span class="special">)</span> <span class="special">]</span> <span class="special"><<</span> <span class="string">","</span>
2019 <span class="special"><<</span> <span class="identifier">expr</span><span class="special">::</span><span class="identifier">csv_decor</span><span class="special">[</span> <span class="identifier">expr</span><span class="special">::</span><span class="identifier">stream</span> <span class="special"><<</span> <span class="identifier">expr</span><span class="special">::</span><span class="identifier">message</span> <span class="special">]</span>
2020 <span class="special">);</span>
2023 <div class="section">
2024 <div class="titlepage"><div><div><h6 class="title">
2025 <a name="log.detailed.expressions.formatters.decorators.c"></a><a class="link" href="expressions.html#log.detailed.expressions.formatters.decorators.c" title="C-style character decorators">C-style
2026 character decorators</a>
2027 </h6></div></div></div>
2028 <pre class="programlisting"><span class="preprocessor">#include</span> <span class="special"><</span><code class="computeroutput"><a class="link" href="../../expressions.html#header.boost.log.expressions.formatters.c_decorator_hpp" title="Header <boost/log/expressions/formatters/c_decorator.hpp>">boost/log/expressions/formatters/c_decorator.hpp</a></code><span class="special">></span>
2031 The header defines two character decorators: <code class="computeroutput"><span class="identifier">c_decor</span></code>
2032 and <code class="computeroutput"><span class="identifier">c_ascii_decor</span></code>.
2033 The first one replaces the following characters with their escaped
2034 counterparts: \ (backslash, 0x5c), \a (bell character, 0x07), \b (backspace,
2035 0x08), \f (formfeed, 0x0c), \n (newline, 0x0a), \r (carriage return,
2036 0x0d), \t (horizontal tabulation, 0x09), \v (vertical tabulation, 0x0b),
2037 ' (apostroph, 0x27), " (quote, 0x22), ? (question mark, 0x3f).
2038 The <code class="computeroutput"><span class="identifier">c_ascii_decor</span></code> decorator
2039 does the same but also replaces all other non-printable and non-ASCII
2040 characters with escaped hexadecimal character codes in C notation (e.g.
2041 "\x8c"). The usage is similar to other character decorators:
2043 <pre class="programlisting"><span class="identifier">sink</span><span class="special">-></span><span class="identifier">set_formatter</span>
2044 <span class="special">(</span>
2045 <span class="identifier">expr</span><span class="special">::</span><span class="identifier">stream</span>
2046 <span class="special"><<</span> <span class="identifier">expr</span><span class="special">::</span><span class="identifier">attr</span><span class="special"><</span> <span class="keyword">unsigned</span> <span class="keyword">int</span> <span class="special">>(</span><span class="string">"LineID"</span><span class="special">)</span> <span class="special"><<</span> <span class="string">": ["</span>
2047 <span class="special"><<</span> <span class="identifier">expr</span><span class="special">::</span><span class="identifier">c_decor</span><span class="special">[</span> <span class="identifier">expr</span><span class="special">::</span><span class="identifier">stream</span> <span class="special"><<</span> <span class="identifier">expr</span><span class="special">::</span><span class="identifier">attr</span><span class="special"><</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="special">>(</span><span class="string">"Tag"</span><span class="special">)</span> <span class="special">]</span> <span class="special"><<</span> <span class="string">"] "</span>
2048 <span class="special"><<</span> <span class="identifier">expr</span><span class="special">::</span><span class="identifier">c_ascii_decor</span><span class="special">[</span> <span class="identifier">expr</span><span class="special">::</span><span class="identifier">stream</span> <span class="special"><<</span> <span class="identifier">expr</span><span class="special">::</span><span class="identifier">message</span> <span class="special">]</span>
2049 <span class="special">);</span>
2052 <div class="section">
2053 <div class="titlepage"><div><div><h6 class="title">
2054 <a name="log.detailed.expressions.formatters.decorators.char"></a><a class="link" href="expressions.html#log.detailed.expressions.formatters.decorators.char" title="General character decorator">General
2055 character decorator</a>
2056 </h6></div></div></div>
2057 <pre class="programlisting"><span class="preprocessor">#include</span> <span class="special"><</span><code class="computeroutput"><a class="link" href="../../expressions.html#header.boost.log.expressions.formatters.char_decorator_hpp" title="Header <boost/log/expressions/formatters/char_decorator.hpp>">boost/log/expressions/formatters/char_decorator.hpp</a></code><span class="special">></span>
2060 This decorator allows the user to define his own character replacement
2061 mapping in one of the two forms. The first form is a range of <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">pair</span></code>s of strings (which can be C-style
2062 strings or ranges of characters, including <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span></code>s).
2063 The strings in the <code class="computeroutput"><span class="identifier">first</span></code>
2064 elements of pairs will be replaced with the <code class="computeroutput"><span class="identifier">second</span></code>
2065 elements of the corresponding pair.
2067 <pre class="programlisting"><span class="identifier">std</span><span class="special">::</span><span class="identifier">array</span><span class="special"><</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">pair</span><span class="special"><</span> <span class="keyword">const</span> <span class="keyword">char</span><span class="special">*,</span> <span class="keyword">const</span> <span class="keyword">char</span><span class="special">*</span> <span class="special">>,</span> <span class="number">3</span> <span class="special">></span> <span class="identifier">shell_escapes</span> <span class="special">=</span>
2068 <span class="special">{</span>
2069 <span class="special">{</span> <span class="string">"\""</span><span class="special">,</span> <span class="string">"\\\""</span> <span class="special">},</span>
2070 <span class="special">{</span> <span class="string">"'"</span><span class="special">,</span> <span class="string">"\\'"</span> <span class="special">},</span>
2071 <span class="special">{</span> <span class="string">"$"</span><span class="special">,</span> <span class="string">"\\$"</span> <span class="special">}</span>
2072 <span class="special">};</span>
2074 <span class="identifier">sink</span><span class="special">-></span><span class="identifier">set_formatter</span>
2075 <span class="special">(</span>
2076 <span class="identifier">expr</span><span class="special">::</span><span class="identifier">stream</span> <span class="special"><<</span> <span class="identifier">expr</span><span class="special">::</span><span class="identifier">char_decor</span><span class="special">(</span><span class="identifier">shell_escapes</span><span class="special">)</span>
2077 <span class="special">[</span>
2078 <span class="identifier">expr</span><span class="special">::</span><span class="identifier">stream</span> <span class="special"><<</span> <span class="identifier">expr</span><span class="special">::</span><span class="identifier">message</span>
2079 <span class="special">]</span>
2080 <span class="special">);</span>
2083 The second form is two same-sized sequences of strings; the first containing
2084 the search patterns and the second - the corresponding replacements.
2086 <pre class="programlisting"><span class="identifier">std</span><span class="special">::</span><span class="identifier">array</span><span class="special"><</span> <span class="keyword">const</span> <span class="keyword">char</span><span class="special">*,</span> <span class="number">3</span> <span class="special">></span> <span class="identifier">shell_patterns</span> <span class="special">=</span>
2087 <span class="special">{</span>
2088 <span class="string">"\""</span><span class="special">,</span> <span class="string">"'"</span><span class="special">,</span> <span class="string">"$"</span>
2089 <span class="special">};</span>
2090 <span class="identifier">std</span><span class="special">::</span><span class="identifier">array</span><span class="special"><</span> <span class="keyword">const</span> <span class="keyword">char</span><span class="special">*,</span> <span class="number">3</span> <span class="special">></span> <span class="identifier">shell_replacements</span> <span class="special">=</span>
2091 <span class="special">{</span>
2092 <span class="string">"\\\""</span><span class="special">,</span> <span class="string">"\\'"</span><span class="special">,</span> <span class="string">"\\$"</span>
2093 <span class="special">};</span>
2095 <span class="identifier">sink</span><span class="special">-></span><span class="identifier">set_formatter</span>
2096 <span class="special">(</span>
2097 <span class="identifier">expr</span><span class="special">::</span><span class="identifier">stream</span> <span class="special"><<</span> <span class="identifier">expr</span><span class="special">::</span><span class="identifier">char_decor</span><span class="special">(</span><span class="identifier">shell_patterns</span><span class="special">,</span> <span class="identifier">shell_replacements</span><span class="special">)</span>
2098 <span class="special">[</span>
2099 <span class="identifier">expr</span><span class="special">::</span><span class="identifier">stream</span> <span class="special"><<</span> <span class="identifier">expr</span><span class="special">::</span><span class="identifier">message</span>
2100 <span class="special">]</span>
2101 <span class="special">);</span>
2104 In both cases the patterns are not interpreted and are sought in the
2105 formatted characters in the original form.
2108 <div class="section">
2109 <div class="titlepage"><div><div><h6 class="title">
2110 <a name="log.detailed.expressions.formatters.decorators.max_size"></a><a class="link" href="expressions.html#log.detailed.expressions.formatters.decorators.max_size" title="String length limiting decorator">String
2111 length limiting decorator</a>
2112 </h6></div></div></div>
2113 <pre class="programlisting"><span class="preprocessor">#include</span> <span class="special"><</span><code class="computeroutput"><a class="link" href="../../expressions.html#header.boost.log.expressions.formatters.max_size_decorator_hpp" title="Header <boost/log/expressions/formatters/max_size_decorator.hpp>">boost/log/expressions/formatters/max_size_decorator.hpp</a></code><span class="special">></span>
2116 Sometimes it can be useful to be able to limit the size of the output
2117 of a formatter or its part. For example, the limit might be imposed
2118 by the sink or the required output format. The <code class="computeroutput"><span class="identifier">max_size_decor</span></code>
2119 decorator allows to enforce such limit. Let's see a simple example:
2121 <pre class="programlisting"><span class="identifier">sink</span><span class="special">-></span><span class="identifier">set_formatter</span>
2122 <span class="special">(</span>
2123 <span class="identifier">expr</span><span class="special">::</span><span class="identifier">stream</span> <span class="special"><<</span> <span class="identifier">expr</span><span class="special">::</span><span class="identifier">max_size_decor</span><span class="special"><</span> <span class="keyword">char</span> <span class="special">>(</span><span class="number">20</span><span class="special">)</span>
2124 <span class="special">[</span>
2125 <span class="identifier">expr</span><span class="special">::</span><span class="identifier">stream</span> <span class="special"><<</span> <span class="identifier">expr</span><span class="special">::</span><span class="identifier">message</span>
2126 <span class="special">]</span>
2127 <span class="special">);</span>
2129 <div class="note"><table border="0" summary="Note">
2131 <td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../../../../doc/src/images/note.png"></td>
2132 <th align="left">Note</th>
2134 <tr><td align="left" valign="top"><p>
2135 The explicit template parameter for <code class="computeroutput"><span class="identifier">max_size_decor</span></code>
2136 specifies the character type that is used by formatter. In this example
2137 the string produced by the formatter contains characters of type
2138 <code class="computeroutput"><span class="keyword">char</span></code>, hence the template
2143 In this example the decorator limits the log message to no more than
2144 20 <a href="https://en.wikipedia.org/wiki/Character_encoding#Terminology" target="_top">code
2145 units</a> of type <code class="computeroutput"><span class="keyword">char</span></code>
2146 and removes the rest from the output. So if we had a log record like
2149 <pre class="programlisting"><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">"The quick brown fox jumps over the lazy dog"</span><span class="special">;</span>
2152 the resulting output would look like this:
2154 <pre class="programlisting">The quick brown fox
2157 However, looking at this output in a log file it is unclear whether
2158 the original output contained anything else. One might want to indicate
2159 the fact of message truncation, should one occur. For that purpose
2160 the decorator allows to specify an overflow marker that will be placed
2161 at the end of the truncated output, if the truncation took place. We
2162 can modify the above example like this:
2164 <pre class="programlisting"><span class="identifier">sink</span><span class="special">-></span><span class="identifier">set_formatter</span>
2165 <span class="special">(</span>
2166 <span class="identifier">expr</span><span class="special">::</span><span class="identifier">stream</span> <span class="special"><<</span> <span class="identifier">expr</span><span class="special">::</span><span class="identifier">max_size_decor</span><span class="special">(</span><span class="number">20</span><span class="special">,</span> <span class="string">">>>"</span><span class="special">)</span>
2167 <span class="special">[</span>
2168 <span class="identifier">expr</span><span class="special">::</span><span class="identifier">stream</span> <span class="special"><<</span> <span class="identifier">expr</span><span class="special">::</span><span class="identifier">message</span>
2169 <span class="special">]</span>
2170 <span class="special">);</span>
2172 <div class="tip"><table border="0" summary="Tip">
2174 <td rowspan="2" align="center" valign="top" width="25"><img alt="[Tip]" src="../../../../../../doc/src/images/tip.png"></td>
2175 <th align="left">Tip</th>
2177 <tr><td align="left" valign="top"><p>
2178 The formatter character type is deduced from the character type of
2179 the overflow marker, so it can be omitted.
2183 Now our log record will look like this in the output:
2185 <pre class="programlisting">The quick brown f>>>
2188 This output makes it more obvious that there was more to the original
2189 message. Note also that the length of the output is still 20 characters;
2190 the marker replaced the last characters of the truncated output.
2192 <div class="tip"><table border="0" summary="Tip">
2194 <td rowspan="2" align="center" valign="top" width="25"><img alt="[Tip]" src="../../../../../../doc/src/images/tip.png"></td>
2195 <th align="left">Tip</th>
2197 <tr><td align="left" valign="top"><p>
2198 For the character truncation and marker positioning to work correctly
2199 in multibyte encodings, it is important that the locale used by the
2200 formatter is set up properly. In particular, the <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">codecvt</span></code>
2201 facet in the locale must correctly recognize multibyte sequences
2202 corresponding to a single character in the output. One can use <a href="http://www.boost.org/doc/libs/release/libs/locale/doc/html/index.html" target="_top">Boost.Locale</a>
2203 to generate the locale and then install it in the sink frontend by
2204 calling <code class="computeroutput"><span class="identifier">imbue</span></code> (see
2205 <code class="computeroutput"><a class="link" href="../../boost/log/sinks/basic_fo_idm45711346293904.html" title="Class template basic_formatting_sink_frontend">basic_formatting_sink_frontend</a></code>
2206 for reference). If the output character type is <code class="computeroutput"><span class="keyword">wchar_t</span></code>,
2207 <code class="computeroutput"><span class="keyword">char16_t</span></code> or <code class="computeroutput"><span class="keyword">char32_t</span></code> the library assumes that
2208 the output is encoded in UTF-16 or UTF-32, depending on the size
2209 of the character type. Because the truncation might occur in the
2210 middle of a multi-unit character, truncated output produced by the
2211 decorator can be slightly shorter than the specified limit sometimes.
2215 As with any other formatter, <code class="computeroutput"><span class="identifier">max_size_decor</span></code>
2216 can participate in more complex formatting expressions and limit length
2217 of only part of the message.
2219 <pre class="programlisting"><span class="identifier">sink</span><span class="special">-></span><span class="identifier">set_formatter</span>
2220 <span class="special">(</span>
2221 <span class="identifier">expr</span><span class="special">::</span><span class="identifier">stream</span>
2222 <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="string">"TimeStamp"</span><span class="special">,</span> <span class="string">"%Y-%m-%d %H:%M:%S.%f"</span><span class="special">)</span> <span class="special"><<</span> <span class="string">" ["</span>
2223 <span class="special"><<</span> <span class="identifier">expr</span><span class="special">::</span><span class="identifier">max_size_decor</span><span class="special">(</span><span class="number">20</span><span class="special">,</span> <span class="string">">>>"</span><span class="special">)</span>
2224 <span class="special">[</span>
2225 <span class="identifier">expr</span><span class="special">::</span><span class="identifier">stream</span> <span class="special"><<</span> <span class="identifier">expr</span><span class="special">::</span><span class="identifier">message</span>
2226 <span class="special">]</span>
2227 <span class="special"><<</span> <span class="string">"]"</span>
2228 <span class="special">);</span>
2231 The above formatter can produce output like this:
2233 <pre class="programlisting">2016-08-10 00:36:44.028473 [The quick brown f>>>]
2239 <table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
2240 <td align="left"></td>
2241 <td align="right"><div class="copyright-footer">Copyright © 2007-2016 Andrey Semashev<p>
2242 Distributed under the Boost Software License, Version 1.0. (See accompanying
2243 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>).
2248 <div class="spirit-nav">
2249 <a accesskey="p" href="sink_backends.html"><img src="../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../detailed.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="attributes.html"><img src="../../../../../../doc/src/images/next.png" alt="Next"></a>